标签:全局变量   派生   检测   函数   modules   tracking   register   resources   需求   
本文转载自:http://blog.csdn.net/coding__madman/article/details/51428400
总线驱动设备模型:
1. 总线设备驱动模型概述
        随着技术的不断进步,系统的拓扑结构也越来越复杂,对热插拔,跨平台移植性的要求也越来越高,2.4内核已经难以满足这些需求,为适应这宗形势的需求,从linux2.6内核开始提供了全新的设备模型
2. 总线
    2.1 描述结构


    2.2 注册

    2.3 注销
void  bus_unregister(struct  bus_type *bus)
代码例程:
bus.c
 
- #include<linux/module.h>  
 
- #include<linux/init.h>  
 
- #include<linux/kernel.h>  
 
- #include<linux/device.h>  
 
-   
 
- MODULE_LICENSE("GPL");  
 
-   
 
- int my_match(struct device *dev, struct device_driver *drv)  
 
- {  
 
-       
 
-     return 0;  
 
- }  
 
-   
 
- struct bus_type my_bus_type =   
 
- {  
 
-     .name = "my_bus",  
 
-     .match = my_match,  
 
- };  
 
-   
 
- int my_bus_init(void)  
 
- {  
 
-     int ret;  
 
-       
 
-     ret = bus_register(&my_bus_type);  
 
-       
 
-     return ret;  
 
- }  
 
-   
 
- void my_bus_exit(void)  
 
- {  
 
-     bus_unregister(&my_bus_type);  
 
- }  
 
-   
 
-   
 
- module_init(my_bus_init);  
 
- module_exit(my_bus_exit);  
 
 

这是上面的总线驱动模块编译运行的效果图!
 
 
下面向上面的my_bus总线上挂载一个驱动!
 
3. 驱动
    3.1 描述结构

    3.2 注册
      int  drvier_register(struct  device  *dev)
    3.3 注销
      void drever_unregister(struct  device_driver  *drv)
4. 设备
    4.1 设备的描述

    4.2 设备的注册
       int device_register(struct device *dev)
    4.3 设备的注销
       void device_unregister(struct device *dev)
driver.c
 
- #include<linux/module.h>  
 
- #include<linux/init.h>  
 
- #include<linux/device.h>  
 
- #include<linux/kernel.h>  
 
-   
 
- MODULE_LICENSE("GPL");  
 
-   
 
- extern struct bus_type my_bus_type;  
 
-   
 
- int my_probe(struct device *dev)  
 
- {  
 
-     printk(KERN_WARNING"driver found the device!!!\n");  
 
-       
 
-     return 0;  
 
- }  
 
-   
 
- struct device_driver my_driver =   
 
- {  
 
-     .name = "my_dev",  
 
-     .bus = &my_bus_type,  
 
-     .probe = my_probe, 
 
- };  
 
-   
 
- int my_device_init(void)  
 
- {  
 
-     int ret;   
 
-       
 
-     ret = driver_register(&my_driver);
 
-       
 
-     return 0;  
 
- }  
 
-   
 
- void my_device_exit(void)  
 
- {  
 
-     driver_unregister(&my_driver);  
 
- }  
 
-   
 
- module_init(my_device_init);  
 
- module_exit(my_device_exit);  
 
 
Makefile
 
 
- obj-m := bus.o device.o  
 
- KDIR := /home/kernel/linux-ok6410  
 
- all:  
 
-     make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm  
 
- clean:  
 
-     rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order  
 
 

 
下面再在总线上挂载一个设备!
device.c
 
- #include <linux/device.h>  
 
- #include <linux/module.h>  
 
- #include <linux/kernel.h>  
 
- #include <linux/init.h>  
 
-   
 
- MODULE_LICENSE("GPL");  
 
-   
 
- extern struct bus_type my_bus_type;  
 
-   
 
- struct device my_dev =   
 
- {  
 
-      .init_name = "my_dev",
 
-      .bus = &my_bus_type,     
 
- };  
 
-   
 
- int my_device_init(void)  
 
- {  
 
-     int ret;  
 
-      ret = device_register(&my_dev);  
 
-      return ret;  
 
-        
 
- }  
 
-   
 
-   
 
- void my_device_exit(void)  
 
- {  
 
-     device_unregister(&my_dev);  
 
- }  
 
-   
 
- module_init(my_device_init);  
 
- module_exit(my_device_exit);  
 
 
driver.c
 
 
- #include<linux/module.h>  
 
- #include<linux/init.h>  
 
- #include<linux/device.h>  
 
- #include<linux/kernel.h>  
 
-   
 
- MODULE_LICENSE("GPL");  
 
-   
 
- extern struct bus_type my_bus_type;  
 
-   
 
- int my_probe(struct device *dev)  
 
- {  
 
-     printk(KERN_WARNING"driver found the device!!!\n");  
 
-       
 
-     return 0;  
 
- }  
 
-   
 
- struct device_driver my_driver =   
 
- {  
 
-     .name = "my_dev",  
 
-     .bus = &my_bus_type,  
 
-     .probe = my_probe, 
 
- };  
 
-   
 
- int my_device_init(void)  
 
- {  
 
-     int ret;   
 
-       
 
-     ret = driver_register(&my_driver);
 
-       
 
-     return 0;  
 
- }  
 
-   
 
- void my_device_exit(void)  
 
- {  
 
-     driver_unregister(&my_driver);  
 
- }  
 
-   
 
- module_init(my_device_init);  
 
- module_exit(my_device_exit);  
 
 
bus.c
 
 
- #include<linux/module.h>  
 
- #include<linux/init.h>  
 
- #include<linux/kernel.h>  
 
- #include<linux/device.h>  
 
-   
 
- MODULE_LICENSE("GPL");  
 
-   
 
- int my_match(struct device *dev, struct device_driver *drv)  
 
- {  
 
-     return !strncmp(dev->kobj.name,drv->name,strlen(drv->name));  
 
- }  
 
-   
 
- struct bus_type my_bus_type =   
 
- {  
 
-     .name = "my_bus",  
 
-     .match = my_match,  
 
- };  
 
-   
 
- EXPORT_SYMBOL(my_bus_type);
 
-   
 
- int my_bus_init(void)  
 
- {  
 
-     int ret;  
 
-       
 
-     ret = bus_register(&my_bus_type);  
 
-       
 
-     return ret;  
 
- }  
 
-   
 
- void my_bus_exit(void)  
 
- {  
 
-     bus_unregister(&my_bus_type);  
 
- }  
 
-   
 
-   
 
- module_init(my_bus_init);  
 
- module_exit(my_bus_exit);  
 
 
Makefile
 
 
- obj-m := bus.o driver.o device.o  
 
- KDIR := /home/kernel/linux-ok6410  
 
- all:  
 
-     make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm  
 
- clean:  
 
-     rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order  
 
 

运行效果图:
 

平台总线驱动设计:
1. 平台总线概述
    平台总线(Platform bus)是linux2.6内核加入的一种虚拟总线,其优势在于采用了总线的模型对设备与驱动进行了管理,这样提高了程序的可移植性。

2. 平台设备


注册平台设备,使用函数:
    int platform_device_register(struct platform_device *pdev)

3. 平台驱动

平台驱动注册使用函数:
int platform_driver_register(struct platform_driver *)
 
结合上面的基础知识,将案件驱动修改为平台驱动模式!
1. 平台设备注册
2. 平台按键驱动设计
key_dev.c
 
- #include<linux/init.h>  
 
- #include<linux/module.h>  
 
- #include<linux/platform_device.h>  
 
- #include<linux/interrupt.h>  
 
-   
 
- MODULE_LICENSE("GPL");  
 
-   
 
- #define GPNCON 0x7F008830  
 
-   
 
- static struct resource key_resource[] = { 
 
-     [0] = {  
 
-               .start = GPNCON,  
 
-               .end = GPNCON + 8,  
 
-               .flags = IORESOURCE_MEM,
 
-           },  
 
-     [1] = {  
 
-               .start = S3C_EINT(0),
 
-               .end = S3C_EINT(5),  
 
-               .flags = IORESOURCE_IRQ,
 
-           },  
 
- };  
 
-   
 
- struct platform_device key_device =   
 
- {  
 
-     .name = "my_key",  
 
-     .id = 0,  
 
-     .num_resources = ARRAY_SIZE(key_resource),  
 
-     .resource = key_resource,  
 
- };  
 
-   
 
- int keydri_init(void)  
 
- {  
 
-     platform_device_register(&key_device);  
 
-     return 0;  
 
- }  
 
-   
 
- void keydri_exit(void)  
 
- {  
 
-     platform_device_unregister(&key_device);  
 
- }  
 
-   
 
- module_init(keydri_init);  
 
- module_exit(keydri_exit);  
 
 
编译运行截图:
 

key_dri.c
 
- #include <linux/module.h>  
 
- #include <linux/init.h>  
 
- #include <linux/miscdevice.h> /* for struct miscdevice*/  
 
- #include <linux/interrupt.h>  
 
- #include <linux/fs.h> /* for iormap */  
 
- #include <linux/io.h>  
 
- #include <linux/slab.h> /* for kmalloc */  
 
- #include<linux/uaccess.h> /* for copy_to_usr */  
 
- #include <linux/platform_device.h>  
 
-   
 
- MODULE_LICENSE("GPL");  
 
-   
 
- unsigned int *key_base;  
 
-   
 
- struct work_struct *work1;
 
-   
 
- struct timer_list key_timer; 
 
-   
 
- unsigned int key_num;  
 
-   
 
- struct resource *res_mem;  
 
- struct resource *res_irq;  
 
- int size;  
 
-   
 
- void work1_func(struct work_struct *work)  
 
- {  
 
-     
 
-     mod_timer(&key_timer,jiffies + HZ/10); 
 
- }  
 
-   
 
- void key_timer_func(unsigned long data)  
 
- {  
 
-     unsigned int key_val;  
 
-       
 
-     key_val = readw(key_base + 1)&0x01; 
 
-     if(key_val == 0)  
 
-     {  
 
-         printk(KERN_WARNING"OK6410 key1 down!\n");  
 
-         key_num = 0;  
 
-     }  
 
-       
 
-     key_val = readw(key_base + 1)&0x20; 
 
-     if(key_val == 0)  
 
-     {  
 
-         printk(KERN_WARNING"OK6410 key6 down!\n");  
 
-         key_num = 6;  
 
-     }  
 
-   
 
- }  
 
-   
 
- irqreturn_t key_int(int irq, void *dev_id)  
 
- {  
 
-     
 
-       
 
-     
 
-            
 
-     
 
-     schedule_work(work1);  
 
-       
 
-     
 
-     return IRQ_HANDLED;  
 
- }  
 
-   
 
- void key_hw_init(void) 
 
- {  
 
-     
 
-     unsigned short data;  
 
-       
 
-     
 
-     data = readw(key_base);  
 
-     data &= ~0b110000000011; 
 
-     data |= 0b100000000010;  
 
-     writew(data, key_base);  
 
-       
 
-     
 
-       
 
-     printk(KERN_WARNING"init ...!\n");  
 
- }  
 
-   
 
- int key_open(struct inode *node, struct file *filp)  
 
- {  
 
-     printk(KERN_WARNING"open ...!\n");  
 
-       
 
-     return 0;  
 
- }  
 
-   
 
- ssize_t key_read(struct file *filp, char __user *buf, size_t size, loff_t *pos)  
 
- {  
 
-     
 
-     printk(KERN_WARNING"in kernel :key num is %d\n",key_num);  
 
-     copy_to_user(buf, &key_num, 4); 
 
-       
 
-     return 4;  
 
- }  
 
-   
 
- struct file_operations key_fops =   
 
- {  
 
-     .open = key_open,  
 
-     .read = key_read,  
 
- };  
 
-   
 
- struct miscdevice key_miscdev = 
 
- {  
 
-     .minor = 200,  
 
-     .name = "6410key",  
 
-     .fops = &key_fops,
 
- };  
 
-   
 
- static int __devinit key_probe(struct platform_device *pdev)  
 
- {  
 
-   
 
-     misc_register(&key_miscdev);
 
-       
 
-     res_irq =  platform_get_resource(pdev, IORESOURCE_IRQ, 0); 
 
-     request_irq(res_irq->start,key_int,IRQF_TRIGGER_FALLING,"my_key",(void *)1);  
 
-     request_irq(res_irq->end,key_int,IRQF_TRIGGER_FALLING,"my_key",(void *)6);  
 
-       
 
-     res_mem =  platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-       
 
-     size = res_mem->end - res_mem->start + 1;  
 
-     key_base = ioremap(res_mem->start,size);  
 
-       
 
-     key_hw_init();  
 
-       
 
-     work1 = kmalloc(sizeof(struct work_struct),GFP_KERNEL);  
 
-     INIT_WORK(work1 , work1_func );  
 
-       
 
-     
 
-     init_timer(&key_timer);  
 
-     key_timer.function = key_timer_func; 
 
-       
 
-     
 
-     add_timer(&key_timer);  
 
-       
 
-           
 
-     return 0;  
 
-       
 
- }  
 
-   
 
- static int key_remove(struct platform_device *device)  
 
- {  
 
-     free_irq(S3C_EINT(0), 0);
 
-     free_irq(S3C_EINT(5), 0);
 
-       
 
-     misc_deregister(&key_miscdev);
 
-       
 
-     return 0;  
 
- }  
 
-   
 
- struct platform_driver key_driver =   
 
- {  
 
-     .driver     = {  
 
-         .name   = "my_key",  
 
-         .owner  = THIS_MODULE,  
 
-     },  
 
-     .probe      = key_probe,  
 
-     .remove     = key_remove,  
 
- };  
 
-   
 
- static int key_init(void)  
 
- {  
 
-       
 
-     return platform_driver_register(&key_driver);  
 
-       
 
- }  
 
-   
 
- static void key_exit(void)  
 
- {  
 
-   
 
-     platform_driver_register(&key_driver);
 
-       
 
-     printk(KERN_WARNING"key up!");  
 
- }  
 
-   
 
- module_init(key_init);  
 
- module_exit(key_exit);  
 
- MODULE_LICENSE("GPL");  
 
- MODULE_DESCRIPTION("key driver");  
 
 
Makefile
 
 
- obj-m := key_dev.o key_dri.o  
 
- KDIR := /home/kernel/linux-ok6410  
 
- all:  
 
-     make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm  
 
- clean:  
 
-     rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order  
 
 
编译运行效果截图:
 

按下按键1或者按下按键6 可以看到驱动程序打印出如下信息! 这里或者创建设备文件,然后用前面博客里面的应用程序来测试也是一样的!
总线设备驱动模型【转】
标签:全局变量   派生   检测   函数   modules   tracking   register   resources   需求   
原文地址:http://www.cnblogs.com/zzb-Dream-90Time/p/6255231.html