思科认证考试CCIE网工企业基础设施EI路由交换理论lab在线培训
0 人在学
课课家将在这里,以字符设备举例,为大家分析其驱动程序的框架:
一、编写驱动程序的初始化函数。驱动程序的初始化在函数XXX_init()中完成,包括对硬件初始化、中断函数、向内核注册等。
a) 首先要理解硬件结构,搞清楚其功能、接口寄存器以及CPU怎么访问控制这些寄存器等。
b) 其次要明白如何把该设备驱动注册到内核中。设备驱动程序可以直接编进内核(在移植内核时,就将该驱动程序编译进内核),在系统启动的时候初始化,也可以在需要的时候以模块的方式动态到内核中去(使用insmod加载模块到内核中,而移除模块使用rmmod卸载模块)。每个字符设备或是块设备都是通过register_chrdev()函数注册,调用该函数后就可以向系统申请主设备号,操作成功后,该设备名就会出现在/proc/devices里。
此外,在关闭设备时,需要先解除原先设备的注册,而解除注册功能在XXXX_exit()中通过unregister_chrdev()函数实现,之后设备就会从/proc/devices里消失。
二、构造file_perations结构中要用到各个成员函数
Linux操作系统将所有的设备都要看成文件,并以操作文件的方式访问设备。应用程序不能直接操作硬件,而是使用统一的接口调用硬件驱动程序,这组接口被看成系统调用。每个系统调用中都有一个与之对应的函数(open、release、read、write、ioctl等),在字符驱动程序中,这些函数集合在一个file_openrations类型的数据结构中。以一个键盘驱动程序为例:
Struct file_operations Key7279_foPS =
{
.open = Key7279_open,
.ioctl =Key7279_ioctl,
.release=Key7279_close,
.read=Key7279_read,
};
1、设备的打开与释放
打开设备是由open()函数来完成,在open()函数中主要使用硬件的寄存器接口,对硬件进行初始化的设置工作。
而释放设备由release()函数完成。在release()函数中主要使用硬件的寄存器接口,对硬件进行关闭操作。
2、设备的读写操作
读写设备的主要任务就是把内核空间的数据复制到用户空间,或者是从用户空间复制到内核空间,也就是将内核空间缓冲区里的数据复制到用户空间的缓冲区中或者相反。字符设备使用各自的read()函数和write()函数来进行数据读写。
3、设备的控制操作
大部分设备除了读写能力,还可经行超出简单的数据传输之外的操作,所以设备驱动也必须具备进行各种硬件控制操作的能力,这些操作常常通过ioctl方法来支持。与读写操作不同,ioctl()的用法与具体设备密切相关。
三、设备的中断和轮询处理
对于不支持中断的设备,读写时需要轮询设备状态,以及是否需要继续进行数据传输。例如,打印机。如果设备支持中断,则可按照中断方式进行。
模块在使用中断前要先请求一个中断通道(或者 IRQ中断请求),并在使用后释放它。通过request_irq()函数来注册中断,free_irq()函数来释放。
四、驱动程序的测试
对驱动程序的调试可以通过打印的方式来进行,就是通过在驱动程序中添加printk()打印函数,来跟踪驱动程序的执行过程,以此来判断问题。
基于操作系统的驱动就是在无操作系统下的硬件接口函数加上操作系统外套
实现一个嵌入式Linux设备驱动程序的大致流程如下:
(l)查看原理图,理解设备的工作原理。
(2)定义主设备号。设备由一个主设备号和一个次设备号来标识。主设备号唯一标识了设
备类型,即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。次设备号仅
由设备驱动程序解释,区分被一个设备驱动控制下的某个独立的设备。
(3)实现初始化函数。在驱动程序中实现驱动的注册和卸载。
(4)设计所要实现的文件操作,定义file--operations结构。
(5)实现所需的文件操作调用,如read,write等。
(6)实现中断服务,并用request--irq向内核注册,中断并不是每个设备驱动所必需的。
(7)编译该驱动程序到内核中,或者用insmod命令加载模块。
(8)测试该设备,编写应用程序,对驱动程序进行测试。
典型字符设备驱动编写框架:
1 编写硬件接口函数
2 建立文件系统与设备驱动程序间的接口,如:struct file_operations结构体
3 注册设备到chrdevfs全局数组中,注册或注销设备可以在任何时候,但一般在模块加载时注册设备,在模块退出时注销设备。(module_init();module_exit();)
4 以模块方式编译驱动源码,并将其加载到内核中
5 创建设备节点,mknode
6 编写应用程序访问底层设备