Lover雪儿
想念时,就看看天空,无论距离有多远,我们总在同一片天空下!

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\n");
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\n",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! \n");
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 !\n");
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\n", "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

 

posted on 2015-02-26 13:02  Lover雪儿  阅读(403)  评论(0编辑  收藏  举报