zoukankan      html  css  js  c++  java
  • 20150226 IMX257 总线设备驱动模型编程之设备篇

    20150226 IMX257 总线设备驱动模型编程之设备篇

    2015-02-26 李海沿

    前面我们呢实现了总线-设备-驱动模型中的总线,自然,我们的目标就是在我们建立的总线下面创建一个设备。

     http://www.cnblogs.com/lihaiyan/p/4301072.html 

    一、程序分析

    1. 包含总线

    既然我们的设备在总线上,自然我们既要包含总线了

    如图所示,使用外部声明将我们的总线的结构体包含进来

    2. 定义设备结构体

    父目录为 my_bus

    3. 定义属性文件结构体

    属性文件结构体可以有一下得到:

    //产生后面的 bus_attr_version 结构体

    static DEVICE_ATTR(dev,S_IRUGO,mydev_show,NULL);

    如图所示:

    4. 在初始化函数中

    如图所示:

    在初始化函数中,

    先初始化设备的名字,这个名字用于于驱动名字进行匹配

    然后注册设备,让系统认识这个设备,在/sys/device/my_bus0 下面就会有my_dev这个设备

    最后创建属性文件,这个就是在my_dev下面的 dev文件,可以使用cat dev 进行读取,用于传递字符串。

    5. 在exit函数中

    如图所示就是 移除属性文件,注销设备

    二、编译测试

    可以发现,在我们的/sys/bus/目录下生成了 my_bus 目录

    然后,在 my_bus/devices/ 目录下又生成了 my_dev 目录

    查看my_dev的属性文件 cat dev

    我们使用cat drivers_autoprobe 命令,为1,意思就是我们驱动会自动探测设备

    移除驱动时最好注意顺序

    至此,总线-设备-驱动 模型中,我们已经完成其二了,最后的一个驱动篇,加油!

    我们的目标是在总线中加入驱动程序,并且驱动程序和设备程序会自动互相探测寻找,然后在match中检测关联。

    附上 mybus .c 总线驱动程序

     1 #include <linux/device.h>
     2 #include <linux/module.h>
     3 #include <linux/kernel.h>
     4 #include <linux/init.h>
     5 #include <linux/string.h>
     6 
     7 
     8 static char *Version = "$LoverXueEr : 1.0 $";
     9 
    10 //检测驱动是否匹配设备,dev->bus_id 和 driver->name相等的
    11 static int my_match(struct device *dev ,struct device_driver *driver){
    12     return !strncmp(dev_name(dev),driver->name,strlen(driver->name));
    13 }
    14 
    15 static void my_bus_release(struct device *dev){
    16     printk("<0>my bus release
    ");
    17 }
    18   
    19 //设置设备的名字  dev_set_name(&dev,"name");
    20 struct device my_bus = {
    21     .init_name = "my_bus0",
    22     .release = my_bus_release,
    23 };
    24 
    25 struct bus_type my_bus_type = {
    26     .name = "my_bus",
    27     .match = my_match,
    28 };
    29 EXPORT_SYMBOL(my_bus);  //导出符号
    30 EXPORT_SYMBOL(my_bus_type);
    31 
    32 //显示总线版本号
    33 static ssize_t show_bus_version(struct bus_type *bus,char *buf){
    34     return snprintf(buf,PAGE_SIZE,"%s
    ",Version);
    35 }
    36 
    37 //产生后面的 bus_attr_version 结构体
    38 static BUS_ATTR(version,S_IRUGO, show_bus_version, NULL);
    39 
    40 static int __init my_bus_init(void){
    41     int ret;
    42     /* 注册总线 */
    43     ret = bus_register(&my_bus_type);
    44     if(ret)
    45         return ret;
    46     /*  创建属性文件 */
    47     if(bus_create_file(&my_bus_type, &bus_attr_version))
    48         printk("<0>Fail to create version attribute! 
    ");
    49 
    50     /* 注册总线设备 */
    51     ret = device_register(&my_bus);
    52     if(ret)
    53         printk("<0>Fail to register device: my_bus");
    54     return ret;
    55 }
    56 
    57 static void my_bus_exit(void){
    58     bus_unregister(&my_bus_type);
    59     device_unregister(&my_bus);
    60 }
    61 
    62 module_init(my_bus_init);
    63 module_exit(my_bus_exit);
    64 
    65 
    66 MODULE_AUTHOR("Lover雪儿");
    67 MODULE_LICENSE("GPL");
    View Code

    附上 mydev .c 设备驱动程序

     1 #include <linux/device.h>
     2 #include <linux/module.h>
     3 #include <linux/kernel.h>
     4 #include <linux/init.h>
     5 #include <linux/string.h>
     6 
     7 //包含总线
     8 extern struct device my_bus;
     9 extern struct bus_type my_bus_type;
    10 
    11 static void my_dev_release(struct device *dev){
    12     printk("<0>my_dev release !
    ");
    13 }
    14   
    15 //设置设备的名字  dev_set_name(&dev,"name");
    16 struct device my_dev = {
    17     .bus = &my_bus_type,
    18     .parent = &my_bus,        //父目录为my_bus
    19     .release = my_dev_release,
    20 };
    21 
    22 ssize_t mydev_show(struct device *dev,struct device_attribute *attr,char *buf){
    23     return sprintf(buf, "%s
    ", "This is my device");
    24 }
    25 
    26 //产生后面的 dev_attr_dev 结构体
    27 static DEVICE_ATTR(dev,S_IRUGO,mydev_show,NULL);
    28 
    29 static int __init my_dev_init(void){
    30     int ret = 0;
    31 
    32     /* 初始化设备 以后看驱动与设备是否匹配就看这个名字 */
    33       dev_set_name(&my_dev,"my_dev");
    34 
    35     /* 注册设备 */
    36     ret = device_register(&my_dev);
    37     if(ret)
    38         printk("<0>Fail to register device: my_dev");
    39     /* 创建属性文件 */
    40     if(device_create_file(&my_dev, &dev_attr_dev))
    41         printk("<0>Fail to create device file: my_dev");
    42 
    43     return ret;
    44 }
    45 
    46 static void my_dev_exit(void){
    47     device_remove_file(&my_dev, &dev_attr_dev);
    48     device_unregister(&my_dev);
    49 }
    50 
    51 module_init(my_dev_init);
    52 module_exit(my_dev_exit);
    53 
    54 
    55 MODULE_AUTHOR("Lover雪儿");
    56 MODULE_LICENSE("GPL");
    View Code

    附上 MAKEFILE程序

     1 ifeq ($(KERNELRELEASE),)
     2     KERNELDIR ?= /home/study/system/linux-2.6.31
     3     PWD := $(shell pwd)
     4 modules:
     5     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
     6 modules_install:
     7     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
     8 clean:
     9     rm -rf *.o *~ core .depend  *.cmd *.ko *.mod.c .tmp_versions *.markers *.order *.symvers
    10 
    11 else
    12     obj-m := mybus.o mydev.o
    13 endif
    View Code
  • 相关阅读:
    面向服务的体系架构 SOA(三) --- Zookeeper API、zkClient API的使用
    面向服务的体系架构 SOA(二) --- 服务的路由和负载均衡
    面向服务的体系架构 SOA(一) --- 基于TCP、HTTP协议的RPC
    eclipse集成dorado5插件
    java微信公众号开发token验证失败的问题及解决办法
    oracle使用中的一些问题
    JAVA设计模式之装饰者模式
    JAVA设计模式之观察者模式
    JDBC三层架构
    如何使用JDBC实现数据访问对象层(DAO)
  • 原文地址:https://www.cnblogs.com/lihaiyan/p/4301079.html
Copyright © 2011-2022 走看看