【Linux开发】linux设备驱动归纳总结(十):1.udev&misc
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
不知不觉我的总结已经写得七七八八了,这一章节只是补充一下两个知识点:动态创建设备节点和杂设备类的注册。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
一、动态创建设备节点——udev
之前加载字符型设备后是通过命令mknod来创建设备节点的。在2.6内核中,有一个名叫udev的后台程序,它通过读取/sys/class的信息,一旦添加的新的设备,该后台程序就会自动创建设备节点。
一、要使用动态创建设备节点,首先要运行udev后台程序。
在嵌入式下有两种方法:
1、移植udev到嵌入式系统中。
2、在编译busybox时加入mdev。
mdev可以理解是udev的精简版,在这里我就不介绍如何加入mdev,仅仅介绍udev的移植。
首先:进入到udev的目录,我在附件中提供了udev的源文件:
root@xiaobai-laptop:/nfsroot/review_driver/10th_udev_misc/udev/tools/udev-096# pwd
/nfsroot/review_driver/10th_udev_misc/udev/tools/udev-096
接着修改Makefile的两处:
line 96 prefix = /nfsroot //指定udev安装路径,安装到我们的跟文件系统中
linr 114 CROSS_COMPILE = arm-linux- //指定编译工具
然后编译并安装:
make
make install
最后在跟文件系统的/nfsroot/etc/init.d/rcS加上三句话,让系统启动后运行udev后台程序:
mount -t tmpfs tmpfs /dev
/sbin/udevd -d
/sbin/udevstart
移植udev后,系统启动是就会自己启动udev程序。
二、接着就是在代码中使用动态创建函数了。
udev的动态创建是通过读取/sys/class的信息来实现的。所以,首先是要创建一个类:
struct class *class_create(struct module *owner, const char *name)
owner用于指定该类的所属,一般填写THIS_MODULE。
name是指定该类该/sys/class/目录下的目录名字。
同样的,该操作有可能出错,需要检验返回值。
类创建成功后会在/sys/class创建一个以name命名的目录。
类的注销使用以下函数:
void class_destroy(struct class *cls)
创建类后,就可以调用以下函数注册类设备,将设备加入到指定的类中,这样udev就可以才class目录下读取信息后动态创建设备节点了:
/*drivers/base/core.c*/
1386 struct device *device_create(struct class *class, struct device *parent,
1387 dev_t devt, void *drvdata, const char *fmt, ...)
class是用于指定所属的class。
parent用于指定设备的父设备,一般填NULL就可以了。
Devt用于指定该设备的设备号。
drvdata用于指定class下的数据,一般也不用传。
fmt就是动态创建的设备文件的名字,一般格式:"%s", "test_led"。
设个函数成功调用会在/sys/devices/virtual的对应总线下创建一个test_led的目录,并且软连接到/sys/class对应的总线目录下。
使用以下函数注销类设备:
void device_destroy(struct class *class, dev_t devt)
注意:上面的两步并没有真正创建设备文件,只有在udev读取/sys/class信息后发现tesl_led,才会真正创建设备文件。
先来来个代码,这是我之前写的简洁版led驱动,添加了动态创建设备文件功能:
/*10th_udev_misc/udev/1st_udev/test.c*/
7 #include //需要包含该头文件
10 struct class *my_class;
。。。。。
62 int test_init(void)
63 {
64 //devmodel class create
65 my_class
= class_create(THIS_MODULE, "test_class"); //创建class
66 if(IS_ERR(my_class)){
67 printk("create
cleaa wrong!\n");
68 return
-1;
69 }
70 device_create(my_class,
NULL, MKDEV(253, 0), NULL, "%s", "test_led"); //根据class和设备号创建设备
71
72 register_chrdev(253, "udev led", &led_fops);
73 led_init(); //ioremap的地址映射
74 led_config(); //gpio_led的配置
75
76 return 0;
77 }
78 void test_exit(void)
79 {
80 iounmap((void *)virt); //注销虚拟地址的映射
81 unregister_chrdev(253, "udev led");
//注销设备节点
82 device_destroy(my_class,
MKDEV(253, 0)); //注销类设备
83 class_destroy(my_class);
//注销类
84 printk("bye\n");
85 }
接下来验证一下:
[root: 1st_udev]# insmod test.ko //加载驱动
[root: 1st_udev]# ./app on //灯亮
[root: 1st_udev]# ./app off //灯灭
[root: 1st_udev]# cat /proc/devices //查看一下
Character devices:
1 mem
。。。。。
136 pts
204 s3c2410_serial
253 udev led //设备被注册了
254 rtc
[root: 1st_udev]# cd /
[root: /]# find -name "*test_led*" //查找test_led相关文件
./sys/devices/virtual/test class/test_led ///device/virtule目录下有test_led目录
./sys/class/test class/test_led //并且有类test_class
./dev/test_led //动态创建了test_led设备文件
[root: 1st_udev]# ls -l /sys/class/test\ class/test_led
lrwxrwxrwx 1 root root 0 Jan 1 08:29 /sys/class/test class/test_led -> ../../devices/virtual/test class/test_led
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
二、杂设备——misc
简单的说,杂设备就是内核自动帮你分配设备号并且自动创建设备文件。
1、自动分配设备号,是指所有注册为杂设备的设备的主设备号为10,而次设备号内核自动分配。
2、自动创建设备文件是指,内核会使用udev(前提是你已经移植udev),动态创建设备节点。
方法很简单:需要包含头文件:linux/miscdevice.h
1、定义杂设备结构体:
36 struct miscdevice {
37 int minor;
38 const
char *name; //设备文件的名字
39 const
struct file_operations *fops; //指定该设备的fops结构体
40 struct list_head list;
41 struct device *parent;
42 struct device *this_device;
43 };
红色标记的内容是我们必须要自己填写的,其他部分可以由内核自己分配。
2、定义结构体后使用使用一下函数注册和注销:
int misc_register(struct miscdevice * misc); //注册
int misc_deregister(struct miscdevice *misc); //注销
注册操作会失败,建议检查返回值。
看代码:
/*10th_udev_misc/misc/1st_misc/test.c*/
58 static struct file_operations led_fops = {
59 .ioctl
= led_ioctl,
60 };
61
62 static struct miscdevice misc_led = { //杂设备
63 .name
= "test_led",
64 .fops
= &led_fops,
65 };
66
67 int test_init(void)
68 {
69 misc_register(&misc_led);
//注册杂设备
70
71 led_init(); //ioremap的地址映射
72 led_config(); //gpio_led的配置
73
74 return 0;
75 }
76 void test_exit(void)
77 {
78 misc_deregister(&misc_led);
//注销杂设备
79 iounmap((void *)virt); //注销虚拟地址的映射
80 printk("bye\n");
81 }
再看效果
[root: 1st_misc]# insmod test.ko
[root: 1st_misc]# cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc //创建的设备在misc中
[root: 1st_misc]# lsmod
test 2212 0 - Live 0xbf000000
[root: 1st_misc]# ls -l /dev/test_led
[root: 1st_misc]# ./app on //亮灯
[root: 1st_misc]# ./app off //灭灯
[root: 1st_misc]# cd / //查看test_led相关文件
[root: /]# find -name "*test_led*"
./sys/devices/virtual/misc/test_led
./sys/class/misc/test_led //发现注册到misc类中
./dev/test_led
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
三、总结
这节介绍了如何动态创建设备文件和如果创建杂设备类驱动。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
源代码: 10th_udev_misc.rar
【Linux开发】linux设备驱动归纳总结(十):1.udev&misc的更多相关文章
- 【Linux开发】linux设备驱动归纳总结(十二):简单的数码相框
linux设备驱动归纳总结(十二):简单的数码相框 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- linux设备驱动归纳总结(十二):简单的数码相框【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-116926.html linux设备驱动归纳总结(十二):简单的数码相框 xxxxxxxxxxxxxx ...
- linux设备驱动归纳总结(十):1.udev&misc【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-111839.html linux设备驱动归纳总结(十):1.udev&misc xxxxxxx ...
- 【Linux开发】linux设备驱动归纳总结(十一):写个简单的看门狗驱动
linux设备驱动归纳总结(十一):写个简单的看门狗驱动 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- 【Linux开发】linux设备驱动归纳总结(八):3.设备管理的分层与面向对象思想
linux设备驱动归纳总结(八):3.设备管理的分层与面向对象思想 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- 【Linux开发】linux设备驱动归纳总结(六):1.中断的实现
linux设备驱动归纳总结(六):1.中断的实现 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- 【Linux开发】linux设备驱动归纳总结(六):2.分享中断号
linux设备驱动归纳总结(六):2.分享中断号 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- 【Linux开发】linux设备驱动归纳总结(五):1.在内核空间分配内存
linux设备驱动归纳总结(五):1.在内核空间分配内存 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- 【Linux开发】linux设备驱动归纳总结(五):2.操作硬件——IO内存
linux设备驱动归纳总结(五):2.操作硬件--IO内存 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
随机推荐
- mysql索引分类及实现原理
索引分类:主键索引.唯一索引.普通索引.全文索引.组合索引 1.主键索引:即主索引,根据主键pk_clolum(length)建立索引,不允许重复,不允许空值 ALTER TABLE 'table_n ...
- BZOJ1968: [Ahoi2005]COMMON 约数研究 线性筛
按照积性函数的定义筛一下这个积性函数即可. #include <cstdio> #include <algorithm> #define N 1000004 #define s ...
- 【转】vue 手动挂载$mount() 获取 $el
原文:https://www.cnblogs.com/CyLee/p/8425183.html 手动挂载$mount() 如果没有挂载的话,没有关联的 DOM 元素.是获取不到$el的. https: ...
- TensorFlow使用记录 (十四): Multi-task to MNIST + Fashion MNIST
前言 后面工作中有个较重要的 task 是将 YOLOV3 目标检测和 LanNet 车道线检测和到一个网络中训练,特别的是,这两部分数据来自于不同的数据源.这和我之前在 caffe 环境下训练检测整 ...
- ansible模块文件操作
Ansible常用模块文件操作 [root@tiandong etc]# ansible-doc -l 列出ansible所支持的模块 [root@tiandong ~]# ansible-doc ...
- Android学习_广播接收器
一.广播 1. 标准广播和有序广播 标准广播:异步,发出消息,所有接收器同时接收.但无法被截断 有序广播:同步,同一时刻只有一个广播接收器接收.可截断消息. 2. 广播注册 代码中注册(动态注册).A ...
- LeetCode 48. 旋转图像(Rotate Image)
题目描述 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转图像. 示例 1: ...
- Nginx作为静态资源web服务
一.CDN 1.定义: 内容分发的逻辑网络. 2.作用: CDN能做到传输延时的最小化. CDN请求示意图如下: 二.静态资源需要配置的一些语法模块. 1.配置语法 - 文件读取 Syntax : s ...
- 装机、做系统必备:秒懂MBR和GPT分区表____转载网络
装机.做系统必备:秒懂MBR和GPT分区表 科技美学 2016-10-17 16:36:23 阅读(3835) 评论(4) 很多网友询问MBR和GPT的问题,涉及到硬盘操作系统的安装,其实除了MBR和 ...
- android dialog使用自定义布局 设置窗体大小位置
AlertDialog.Builder builder = new Builder(mContext); builder.setTitle("更新进度"); final Layou ...