首页 > 代码库 > linux总线设备驱动模型

linux总线设备驱动模型

本篇文章通过平台总线设备模型为例,讲解总线设备驱动模型:

platform_device_register的作用:
1.把device放入bus的device链表
2.从bus的driver链表中取出每一个driver,用bus的match函数判断driver能否支持这个device
3.若可以支持,调用driver的probe函数
platform_driver_register的作用:
1.将driver放入bus的driver链表
2.从bus的device链表中取出每一个device,用bus的match函数判断这个driver能否支持这个device
3.若可以支持,调用driver的probe函数
 
一、device驱动程序
1.构造并初始化平台设备资源结构体resource
struct resource led_resource[] = {     [0] = {          .start = 0x56000000,          .end = 0x56000000 + 8 - 1,          .flags = IORESOURCE_MEM,     },     [1] = {          .start = 5,          .end = 5,          .flags = IORESOUCE_IRQ,     },};
2.构造并初始化平台设备结构体platform_device
struct platform_device led_dev = {     .name = "myled";     .id      = -1;     .num_resource = ARRAY_SIZE(led_resource);     .resource = led_resource,     .dev = {          .release = led_release,     },};/* release函数可以什么都不做,但是不能为空 */static void led_release(struct device * dev){}
3.注册平台device
platform_device_register(&led_dev);
二、driver驱动程序
1.构造并初始化平台驱动结构体platform_driver
struct platform_driver led_drv = {     .probe = led_probe,     .remove = led_remove,     .driver = {          .name = "myled",     },};
2.构造并初始化file_operations结构体
static struct file_operations led_fops = {     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */     .open   =   led_open,     .write    =   led_write,};static int led_open(struct inode *inode, struct file *file){     //printk("first_drv_open\n");     /* 配置为输出 */     *gpio_con &= ~(0x3<<(pin*2));     *gpio_con |= (0x1<<(pin*2));     return 0;    }static ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos){     int val;     //printk("first_drv_write\n");     copy_from_user(&val, buf, count); //     copy_to_user();     if (val == 1)     {          // 点灯          *gpio_dat &= ~(1<<pin);     }     else     {          // 灭灯          *gpio_dat |= (1<<pin);     }         return 0;}
3.实现platform_driver结构的probe函数
static int led_probe(struct platform_device *pdev){     struct resource *res;      *platform_get_resource     *@dev:platformdevice     *@type:resourcetype     *@num:resourceindex     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);     gpio_con = ioremap(res->start,res->end-res->start+1);     gpio_dat = gpio_con + 1;     res = platform_get_resource(pdev, IORESOURCE_IRQ, 0)     pin = res->start;     major = register_chrdev(0, "myled", &led_fops);     cls = class_create(THIS_MODULE, "myled");     device_create(cls, NULL, MKDEV(major,0), NULL, "led");}
4.注册平台driver驱动程序
platform_driver_register(&led_drv);