看LDD3,针对字符设备驱动的一些简单的笔记。
建立一个字符设备,首先要做的是获取设备编号。包括主设备号和次设备号。
一般,主设备号标识驱动程序,此设备号用于确定设备。
在内核中,dev_t类型(
获取dev_t的主设备号或次设备号,使用下面的宏:
#include
MAJOR(dev_t dev);
MINOR(dev_t dev);
将主次设备号转换成dev_t类型,使用:
MKDEV(int major, int minor);
通过下面这个函数获取设备号:
#include
int register_chrdev_region(dev_t first, unsigned int count, char *name);
参数说明:
first:是要分配的设备编号范围的起始值;
count:是所请求的连续设备编号的个数;
name:是和该编号范围关联的设备名称;
返回值:
正常操作返回0,错误情况下返回一个负数。
使用下面这个函数获取设备号:
#include
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
参数说明:
dev:用于输出的参数,用于函数执行成功后保存已分配范围的第一个编号;
firstminor:要使用的被请求的第一个次设备号,通常为0;
count:是所请求的连续设备编号的个数;
name:是和该编号范围关联的设备名称;
不使用时要释放这些设备编号,使用下面这个函数:
void unregister_chrdev_region(dev_t first, unsigned int count);
该结构体建立驱动程序操作到设备编号的连接。
针对设备实现open、read、write、ioctl等系统调用所对应的函数都在这个结构体中定义,类似于这是一个文件操作的类,驱动程序中实现了它的一些方法。
例如:
struct file_operations f_fops = {
.owner = THIS_MODULE,
.open = f_open,
.read = f_read,
.write = f_write,
...
};
file结构体代表一个内核打开的文件,系统中每个打开的文件在内核空间都有一个对应的file结构,它由内核在open操作时创建。
在内核中表示文件,该结构在内核中唯一定位到一个文件。是由内核构建的。
内核用struct cdev结构体表示字符设备,在内核调用设备操作之前,必须分配注册上述结构,需要包含头文件
#include
初始化cdev结构
void cdev_init(struct cdev *cdev, struct file_operations *fops);
通知内核cdev结构信息
int cdev_add(struct cdev *dev, dev_t num, unsigned int count);
参数说明:
dev:cdev结构;
num:是该设备对应的第一个设备编号;
count:是应该和该设备关联的设备编号的数量;
移除
要从系统中移除一个字符设备,使用下面的函数
void cdev_del(struct cdev *dev);