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");
附上 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");
附上 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
* 博客园: http://www.cnblogs.com/lihaiyan/
* 邮箱:1063385677@qq.com
* QQ: 1063385677
* Copyright ©2014 Lover雪儿
********************************************
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。