这个代码在Kernel
google了一下,发现确实是已经被移除了,在新版的kernel里面,可以使用device_create来代替,参数完全一致。
在LXR(http://lxr.linux.no)网站上面查找了一番,发现class_device_create在2.6.25里面还有,从2.6.26起就被移除了。
Linux
之前写的字符类设备驱动,没有自动创建设备节点,因为只使用了register_chrdev()函数,只是注册了这个设备。然后在系统启动后,就要自己创建设备节点mknod,这样虽然是可行的,但是比较麻烦。于是想在__init函数里面,自动创建设备节点。
class_device_create(myclass,
当然,在exit函数中要把创建的class移除:
class_destory(&xxx_dev->cdev);
class_device_desotry(my_class,MKDEV(major_num,0));
下面以一个简单字符设备驱动来展示如何使用这几个函数
- #include
- #include
- #include
- #include
- #include
- #include
-
- MODULE_LICENSE
("GPL"); -
- int
hello_major = 555; - int
hello_minor = 0; - int
number_of_devices = 1; -
- struct
cdev cdev; -
dev_t dev = 0; -
- struct
file_operations hello_fops = { -
.owner = THIS_MODULE -
}; -
- static
void char_reg_setup_cdev (void) -
{ -
int error, devno = MKDEV (hello_major, hello_minor); -
cdev_init (&cdev, &hello_fops); -
cdev.owner = THIS_MODULE; -
cdev.ops = &hello_fops; -
error = cdev_add (&cdev, devno , 1); -
if (error) -
printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev", error); -
- }
-
- struct
class *my_class; -
- static
int __init hello_2_init (void) -
{ -
int result; -
dev = MKDEV (hello_major, hello_minor); -
result = register_chrdev_region (dev, number_of_devices, "hello"); -
if (result<0) { -
printk (KERN_WARNING "hello: can't get major number %d/n", hello_major); -
return result; -
} -
-
char_reg_setup_cdev (); -
-
-
my_class = class_create(THIS_MODULE, "my_class"); -
if(IS_ERR(my_class)) -
{ -
printk("Err: failed in creating class./n"); -
return -1; -
} -
-
-
device_create( my_class, NULL, MKDEV(hello_major, 0), "hello" "%d", 0 ); -
-
printk (KERN_INFO "Registered character driver/n"); -
return 0; -
} -
- static
void __exit hello_2_exit (void) -
{ -
dev_t devno = MKDEV (hello_major, hello_minor); -
-
cdev_del (&cdev); -
-
device_destroy(my_class, MKDEV(adc_major, 0)); //delete device node under /dev -
class_destroy(my_class); //delete class created by us -
-
unregister_chrdev_region (devno, number_of_devices); -
-
printk (KERN_INFO "char driver cleaned up/n"); -
} -
- module_init
(hello_2_init); - module_exit
(hello_2_exit);
这样,模块加载后,就能在/dev目录下找到hello0这个设备节点了。
mdev是busybox自带的一个简化版的udev,适合于嵌入式的应用埸合。其具有使用简单的特点。它的作用,就是在系统启动和热插拔 或动态加载驱动程序时,自动产生驱动程序所需的节点文件。在以busybox为基础构建嵌入式linux的根文件系统时,使用它是最优
的选择。
mdev使用
mdev的使用在busybox中的mdev.txt文档已经将得很详细了。但作为例子,我简单讲讲我的使用过程:
(1)在编译时加上对mdev的支持(我是使用的是busybox1.10.1):
Linux System Utilities --->
mdev
Support /etc/mdev.conf
Support command execution at device addition/removal
(2)在启动时加上使用mdev的命令:
我在自己创建的根文件系统(nfs)中的/linuxrc文件中添加了如下指令:
#挂载/sys为sysfs文件系统
echo "----------mount /sys as sysfs"
/bin/mount -t tmpfs mdev /dev
/bin/mount -t sysfs sysfs /sys
echo "----------Starting mdev......"
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
注意:是/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug,并非/bin/echo /bin/mdev > /proc/sys/kernel/hotplug。
busybox的文档有错!!
(3)在你的驱动中加上对类设备接口的支持。
在驱动程序的初始化函数中,使用下述的类似语句,就能在类设备目录下添加包含设备号的名为“dev”的属性文件。并通过mdev
在/dev目录下产生gpio_dev0的设备节点文件。
my_class = class_create(THIS_MODULE, "gpio_class");
if(IS_ERR(my_class)) {
printk("Err: failed in creating class.\n");
return -1;
}
class_device_create(my_class, NULL, MKDEV(gpio_major_number, 0), NULL, "gpio_dev%d" ,0);
在驱动程序的清除程序段,加入以下语句,以完成清除工作。
class_device_destroy(my_class, MKDEV(gpio_major_number, 0));
class_destroy(my_class);
需要的头文件是linux/device.h,因此程序的开始应加入下句
#include
另外,my_class是class类型的结构体指针,要在程序开始时声明成全局变量。
struct class *my_class;
上述程序中的gpio_major_number是设备的主节点号。可以换成需要的节点号。gpio_dev是最终生成的设备节点文件的名子。%d是
用于以相同设备自动编号的。gpio_class是建立的class的名称,当驱动程序加载后,可以在/sys/class的目录下看到它。
上述语句也不一定要在初始化和清除阶段使用,可以根据需要在其它地方使用。
(4)至于/etc/mdev.conf文件,可有可无,不影响使用,只是添加了些功能。
关于mdev的使用方法,我在网上找到一篇中文版的。大家可以到我上传的资源中下载。
要想真正用好mdev,适当知道一下原理是必不可少的。现在简单介绍一下mdev的原理:
执行mdev -s
:以‘-s’为参数调用位于
/sbin目录写的mdev(其实是个链接,作用是传递参数给/bin目录下的busybox程序并调用它),mdev扫描 /sys/class 和
/sys/block
中所有的类设备目录,如果在目录中含有名为“dev”的文件,且文件中包含的是设备号,则mdev就利用这些信息为这个设备在/dev
下创建设备节点文件。一般只在启动时才执行一次 “mdev -s”。
热插拔事件:由于启动时运行了命
令:echo /sbin/mdev > /proc/sys/kernel/hotplug ,那么当有热插拔事件产生时,内核就会调用位于
/sbin目录的mdev。这时mdev通过环境变量中的 ACTION 和
DEVPATH,(这两个变量是系统自带的)来确定此次热插拔事件的动作以及影响了/sys中的那个目录。接着会看看这个目录中是否有
“dev”的属性文件,如果有就利用这些信息为
这个设备在/dev 下创建设备节点文件。
最后,附上我在工作中编写的一段简单的gpio控制驱动程序。此程序没有什么功能,主要是做一些测试用的。有兴趣的朋友可以用
它测试一下上述的mdev的使用方法。我用的是友善公司的mini2440开发板。
补充:1
[b]为mdev的运行准备环境
mdev需要改写/dev和/sys两个目录。所以必须保证这两个目录是可写的(一般会用到sysfs,tmpfs。所以要重新编译内核)。
然后在你的启动脚本文件中加入
/bin/mdev -s[/b]
[b]补充2:[/b]
[b] ·/etc/fstab[/b]
[b]这是mount -a要读取的文本。根据需要编写。[/b]