首页 > 其他分享 >字符设备驱动编写流程

字符设备驱动编写流程

时间:2023-02-18 10:57:15浏览次数:56  
标签:字符 struct int 流程 dev cdev 编写 设备

1 什么是字符设备?

  1. 字符(char)设备是能够像字节流(类似文件)一样被访问的设备,由字符设备驱动来实现这种特性。
  2. 字符设备驱动程序通常至少要实现open、close、read和write系统调用。
  3. 字符设备可以通过文件系统节点来访问。比如/dev/tty1和/dev/pl0等。
  4. 设备文件和普通文件之间的唯一差别在于对普通文件的访问可以前后移动访问位置,而大多数字符设备是一个只能顺序访问的数据通道。然后具有数据区特性的字符设备在访问时也可以前后移动访问位置。例如,帧抓取器可以由应用程序调用mmap或lsesk访问抓取的图像。

2 字符设备的本质

字符设备文件有两个要素:设备号、file_operations。其中,设备号是字符设备文件在系统中的唯一标识,file_operations 对应设备文件各种操作方法。
表示字符设备的数据结构 struct cdev 就是上述两个要素的超集:

struct cdev {
	...
	const struct file_operations *ops;  //file_operations
	dev_t dev;             //字符设备的起始设备号
	unsigned int count;    //子设备号个数
} __randomize_layout;

注意:struct cdev 与设备号的关系是一对多,cdev.dev 表示字符设备启动设备号,cdev.count 表示子设备号的个数。而 struct device 与设备号的关系是一对一。
比如,当系统插入多个键盘时,他们的底层操作方法相同,没必要创建多个 struct cdev,但是他们确实存在多个实例。所以,需要创建多个 struct device。这种场景可以把 struct cdev 看成 struct device 实例的代理。

3 设备号(Device numbers)

对字符设备的访问是通过文件系统内的设备名称进行的,那些名称被称为特殊文件,设备文件,或文件系统树的节点(special files or device files or simply nodes of the filesystem tree),它们通常位于/dev目录下。

主设备号标识设备对应的驱动程序。

允许多个驱动程序共享主设备号。

次设备号标识驱动程序所实现的设备。

可以通过次设备号获得一个指向内核设备的直接指针,也可以将次设备号当作设备本地数组的索引。

4 建立一个字符设备

第一步:获得一个或多个设备号

//静态请求设备号
int register_chrdev_region(dev_t first, unsigned int count, char *name);

//动态请求设备号
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);

//释放设备号
void unregister_chrdev_region(dev_t first, unsigned int count);

第二步:分配并注册struct cdev

内核内部使用struct cdev结构来表示字符设备。在内核调用设备的操作之前,必须分配并注册一个或者多个上述结构。

  1. 初始化cdev
void cdev_init(struct cdev *cdev, struct file_operations *fops);
  1. 初始化ops成员
struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &my_fops;
  1. 初始化owner成员
my_cdev->owner = THIS_MODULE;
  1. 告诉内核该结构的消息
int cdev_add(struct cdev *dev, dev_t num, unsigned int count);

引用:

https://tinylab.org/linux-device-model/ 自上而下分析 Linux 设备模型 by法海

标签:字符,struct,int,流程,dev,cdev,编写,设备
From: https://www.cnblogs.com/ixbwer/p/17132112.html

相关文章