`

《linux设备驱动详解》学习笔记(二)---字符设备驱动程序

 
阅读更多

一、程序的基本构架如下:

1、头文件包含、宏定义

2、设备结构体(一般都包括cdev结构体与设备的其他参数)

3、用户接口定义(打开文件关闭文件写文件读文件定位文件等等

4、用户接口结构体(struct file_operations)

5、加载模块

(1)申请结构体的内存

(2)初始化cdev以及设备的其他参数(cdev_init( ),register_chrdev_region( )静态申请设备号,alloc_chrdev_region( )动态申请设备号)

(3)向内核添加cdev(cdev_add( ))

6、卸载模块

(1)注销cdev(cdev_del( ))

(2)释放设备结构体的内存

(3)释放设备号(unregister_chrdev_region( ))

7、其他声明(MODULE_AUTHOR( )声明作者、MODULE_LICENSE( )声明证书等等)

二、以下就解释一下主要的几部分

1、设备结构体

一般设备结构体都会包含(1)cdev结构体,这是内核结构体,包含了设备号、文件操作结构体、所属模块等数据项(2)操控设备过程中要用到的一些变量或存储空间,比如并发控制需要用到的信号量或自旋锁、支持阻塞操作需要用到的阻塞等待队列头等等


2、用户接口结构体


用户程序主要是为用户服务,而驱动程序主要是为用户程序服务。因为用户程序是通过系统调用来实现某项功能,而驱动程序正是为用户程序提供这些系统调用。用户程序对一个设备的操作一般都不止一个,比如说用户程序对字符设备的操作有打开、定位、读、写、关闭等,而这么多的操作,它们对应的程序到底在哪里呢?所以需要一个(struct file_operations)用户接口结构体来管理着,这个结构体的每一项都是一个函数指针,都指向一个操作函数程序,用户如果需要对该设备进行什么操作,只要通过该结构体就可以找到该操作对应的程序在哪里。


3、加载模块


一般加载模块的主要工作有二:

(1)初始化设备结构体,即初始化cdev结构体和操控设备过程中要用到的一些变量或存储空间,不过在初始化cdev结构体之前,你需要通过静态或动态的方式申请号主设备号;

(2)向系统添加该设备,系统会对cdev和设备号有个登记的,这样用户程序才能通过系统来使用该设备。


4、卸载模块


卸载模块主要是对设备结构做善后处理,释放设备结构体的内存,不过释放前要先注销cdev,释放后要释放设备号,因为这两者在你加载进去的时候,系统都有记录的。比如小车开进某个小区时,需要要登记你的车牌号表示你进入该小区,离开时你需要让门卫将你的车牌号从登记表上划掉,表示你离开了该小区。


5、出入口


用户程序都会使用main函数来告知系统该程序应该从哪里执行,驱动程序同样也有,它是通过module_init和module_exit来告知系统应该从哪里进入,从哪里出来。

三、完整代码会在《并发控制》那一篇blog贴出

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics