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);
posted @ 2014-06-27 01:17  zpehome  阅读(321)  评论(0编辑  收藏  举报