驱动开发中常用的函数:
module_param(name, type, perm)
功能:接收命令行传的参数
参数:
@name:变量名
@type: 变量的类型
@perm: 权限 0664 0775
例:char a;
module_param(a, byte, 0664)
MODULE_PARM_DESC(_parm, desc)
功能:对命令行传递的参数进行描述
参数:
@_parm:变量
@desc:描述的字符串
例:
a.安装驱动的时候传参:
sudo insmod demo.ko light=80
b.在运行的使用传参
/sys/module/驱动命名的目录/parameters/
以变量命名的文件
su root
echo 70 > light
3
module_param_array(name, type, nump, perm)
功能:接收整型的数组
参数:
@name :数组名
@type :数组的类型
@nump :命令行传递的参数的个数
@perm :权限
例:sudo insmod demo.ko light=50 tt=65
p="www.hqyj.com" ww=11,22,33
4
EXPORT_SYMBOL_GPL(sym)
功能:将函数或者变量的符号表导出
参数:
@sym:函数名或者变量名
(导出符号表可以让一个内核模块,调用另外一个
内核模块中的函数,它可以让linux更简约,防止
代码冗余的现象。还可以让驱动工程师写否写复杂
驱动的时候更简答。)
编译:
1.先编译提供者模块,编译完之后会产生一个
Module.symvers,这个文件中记录的就是函
数的名字及地址
2.在编译调用者前需要将Module.symvers拷贝到
调用者目录下,然后执行make,如果不拷贝会提示
add undefined
安装:
先安装提供者,在安装调用者
卸载:
先卸载调用者,在卸载提供者
5
int register_chrdev(unsigned int major, const char *name,
const struct file_operations *fops)
功能:注册一个字符设备驱动
参数:
@major :主设备号
major>0 系统认为这个major就是主设备号
major=0 系统自动分配一个主设备号
设备号(32位)=主设备号(高12)+次设备号(低20)
主设备号:它是哪一类设备 LED UART BEEP WDT
次设备号:同类中的第几个设备
@name :给你的字符设备驱动起的名字
通过命令 cat /proc/devices 可以查看
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
@fops:操作方法结构体
可以通过在内核中(kernel)中使用 vi -t file_operations命令查看函数
struct file_operations {
ssize_t (*read) (struct file *,
char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *,
const char __user *, size_t, loff_t *);
int (*open) (struct inode *, struct file *);
int (*release) (struct inode *, struct file *);
} 结构体中成员有很多,以上是列举几种比较常用的。
返回值:
major>0 成功返回0,失败返回错误码(负数)
major=0 成功返回主设备号,失败返回错误码
6
void unregister_chrdev(unsigned int major, const char *name)
功能:注销一个字符设备驱动
参数:
@major:主设备号
@name : 名字
返回值:无
指定驱动文件的tags就是内核顶层的tags
:set tags=/home/linux/kernel/kernel-3.4.39/tags
7
unsigned long copy_from_user(void *to,
const void __user *from, unsigned long n)
功能:将数据从用户空间拷贝到内核空间
参数:
@to :内核空间的首地址
@from:用户空间的首地址
@n :拷贝的字节的个数
返回值:
成功返回0,失败返回未拷贝的字节的个数
8
unsigned long copy_to_user(void __user *to,
const void *from, unsigned long n)
功能:将数据从内核空间拷贝到用户空间
参数:
@to :用户空间的首地址
@from:内核空间的首地址
@n :拷贝的字节的个数
返回值:
成功返回0,失败返回未拷贝的字节的个数
9
void *ioremap(phys_addr_t offset, unsigned long size)
功能:将物理地址映射成虚拟地址
参数:
@offset:物理地址
@size :映射的长度(字节)
返回值:成功返回虚拟地址,失败返回NULL
10
void iounmap(void *addr)
功能:取消映射
参数:
@addr:虚拟地址
返回值:无
11
int ioctl(int fd, int request, ...);
功能:input /output 控制设备
参数:
@fd :打开设备得到的文件描述符
@request:通过同宏_IO _IOR _IOW _IOWR封装的请求码
@... :可变参数
12
class_create(owner, name)
功能:提交目录
参数:
@owner :THIS_MODULE
(所有的驱动遇到owner就写THIS_MODULE,
编译驱动之后会生成一个文件,这个文件通过this_module
记录程序的入口和出口)
@name :目录名
返回值:成功返回struct class *的结构体指针,
失败返回错误码指针(void *)-5;
13
void class_destroy(struct class *cls)
功能:注销class
14
struct device *device_create(struct class *class,
struct device *parent,dev_t devt, void *drvdata,
const char *fmt, ...)
功能:提交设备节点名
参数:
@class :cls的结构体指针
@parent:NULL
@devt : 设备号
@drvdata:NULL
@fmt :设备节点的名字
返回值:成功返回struct device *的结构体指针,
失败返回错误码指针
15
void device_destroy(struct class *class, dev_t devt)
功能:注销device
16
struct cdev *cdev_alloc(void)
分配cdev的对象
void cdev_init(struct cdev *cdev,
const struct file_operations *fops)
功能:初始化cdev的结构体,没有初始化设备号和设备的个数
参数:
@cdev:刚才分配好的结构体指针
@fops:操作方法结构体
17
int register_chrdev_region(dev_t from,
unsigned count, const char *name)
功能:静态申请(直接指定)设备号
参数:
@from :设备号的起始值
@count:设备的个数
@name :名字cat /proc/devices
返回值:成功返回0 ,失败返回错误码
18
int alloc_chrdev_region(dev_t *dev,
unsigned baseminor, unsigned count,
const char *name)
功能:.动态申请(操作系统分配)设备号
参数:
@dev:返回申请到的第一个设备号
@baseminor:次设备号的起始值 3
@count:设备的个数
@name :名字cat /proc/devices
返回值:成功返回0 ,失败返回错误码
19
int cdev_add(struct cdev *p, dev_t dev,
unsigned count)
功能:注册字符设备驱动
参数:
@p:cdev结构体指针
@dev:设备号
@count:设备的个数
返回值:成功返回0 ,失败返回错误码
20
void cdev_del(struct cdev *p)
功能:注销字符设备驱动
参数:
@p:cdev的结构体指针
21
void unregister_chrdev_region(dev_t from, unsigned count)
功能:释放设备号
参数:
@from:设备号的起始的值
@count:设备的个数
22
void kfree(void *p)
功能:释放cdev_alloc分配的内存
参数:
@p:申请的内存的首地址
未完待续…