分类: LINUX
2012-08-24 10:07:43
在linux内核中广泛采用分层分离的思想,将一个驱动人为的拆分为几部分,将与硬件相关的代码放在设备代码中,将软件的代码放在驱动的代码中。在向系统注册设备的时候,将设备放入dev链表中,然后遍历drv链表,并取出每一个drv,调用bus的match函数,通过名字判断该drv是否与注册dev匹配;在向系统注册驱动时,将驱动放入drv链表中,然后遍历dev链表,并取出每一个dev,调用bus的match函数,通过名字判断该drv是否与注册dev匹配。当调用的match函数发现他们两者是匹配的,然后就调用struct platform_driver的probe函数,当设备和驱动中的一个卸载时就调用struct platform_driver的remove函数。
实现设备程序的步骤:
1.分配和设置struct platform_device结构
2.使用platform_device_register函数向内核注册一个平台设备
3.设置硬件相关的属性文件,即设置struct resource结构
设备程序程序代码:
定义一个struct platform_device结构
static struct platform_device led_dev = {
.name = "myled", // 名字
.num_resources = ARRAY_SIZE(led), // 设备属性的个数
.resource = led, // 指向设置属性的指针
.dev = {
.release = led_release, // release必须写出,不写在卸载驱动的时候会 // 出现问题,本程序中release函数是一个空函数
},
};
设置设备的属性:
static struct resource led[] = {
[0] = {
.start = 0x56000010, // 即为DPIO的控制寄存器和数据寄存器
.end = 0x56000010 + 8 -1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 7, // 设置要控制那个lcd
.end = 7,
.flags = IORESOURCE_IO,
}
};
实现驱动程序的步骤:
1.分配和设置struct platform_driver结构
2.使用platform_driver_register函数向内核注册一个注册驱动
3.当发现有同名的设备时就调用struct platform_driver的probe函数,即完成prob函数,在这个函数中可以注册字符设备等相关操作。
在该驱动部分的代码中:
/*
*函数中pdev参数来源于prob函数的参数,作用是获取在设备程序中设置的设备属性
*的结构体数组中,flags为IORESOURCE_MEM项的结构体指针。
*/
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
通过这种方式就将一个驱动拆分为两部分,对于驱动的那一块一直不变,对于操作不同的硬件设备比如要操作不同的led灯,我们只需更改设备相关代码中定义设备属性的结构体数组即可。
以上内容全是本人凭个人理解写出的:如有错误请多包涵,若能指出,本人将万分感激。