自动创建设备节点 device_create
来源:互联网 发布:mac刷新页面的快捷键 编辑:程序博客网 时间:2024/05/02 04:24
这个代码在Kernel 2.6.18下面编译的时候没有任何问题。为什么在2.6.34下面会出现这个错误呢?难道class_device_create这个kernel API已经从新版kernel里面移除了?
google了一下,发现确实是已经被移除了,在新版的kernel里面,可以使用device_create来代替,参数完全一致。
在LXR(http://lxr.linux.no)网站上面查找了一番,发现class_device_create在2.6.25里面还有,从2.6.26起就被移除了。
Linux Kernel的Kernel API是经常会变化的。这给需要支持多个版本的Driver带来了不小的麻烦。有没有什么地方可以很方便的知道 Linux Kernel各个版本之间Kernel API的变化?暂时没有找到。一个可行的方法是,遇到问题之后,到LXR里面如搜索一下,LXR可以搜索特定的kernel版本。
之前写的字符类设备驱动,没有自动创建设备节点,因为只使用了register_chrdev()函数,只是注册了这个设备。然后在系统启动后,就要自己创建设备节点mknod,这样虽然是可行的,但是比较麻烦。于是想在__init函数里面,自动创建设备节点。
经过查阅资料,发现创建设备节点使用了两个函数 class_create()和class_device_create(),当然在__exit()函数里,要使用class_destory()和class_device_desotry()注销创建的设备节点!
问题来了,编译了之后,发现报错error: implicit declaration of 'class_device_create'等几个错误。经过分析,应该是Linux内核版本不同的原因!早期的版本,使用的是上面说的两个函数,但是在2.6.29以后(我用的是2.6.32的),使用的函数则变成了 class_create()和device_create(),并且要在声明中加入#i nclude <linux/device.h> ,因为定义这些函数是在Linux2.6.32/include/linux/device.h里面!
经过这些修改后,驱动编译成功,就能够自动创建设备节点了!
class_device_create(myclass, NULL, MKDEV(major_num, 0), NULL, “char_dev”);
当然,在exit函数中要把创建的class移除:
class_destory(&xxx_dev->cdev);
class_device_desotry(my_class,MKDEV(major_num,0));
下面以一个简单字符设备驱动来展示如何使用这几个函数
#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/device.h>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 (); /* create your own class under /sysfs */ my_class = class_create(THIS_MODULE, "my_class"); if(IS_ERR(my_class)) { printk("Err: failed in creating class./n"); return -1; } /* register your own device in sysfs, and this will cause udev to create corresponding device node */ 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这个设备节点了。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
<span style="color:#ff0000;">#include <linux/kernel.h>#include <linux/module.h>#include <linux/platform_device.h>#include <linux/i2c.h>#include <linux/err.h>#include <linux/regmap.h>#include <linux/slab.h>#include <linux/fs.h>#include <asm/uaccess.h></span>
<span style="color:#ff0000;"></span>
<span style="color:#ff0000;">static struct class *class;</span>
static int __devinit at24cxx_probe(struct i2c_client *client, const struct i2c_device_id *id){at24cxx_client = client;//printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);major = register_chrdev(0, "at24cxx", &at24cxx_fops);<span style="color:#ff0000;">class = class_create(THIS_MODULE, "at24cxx");device_create(class, NULL, MKDEV(major, 0), NULL, "at24cxx"); /* /dev/at24cxx */</span>return 0;}static int __devexit at24cxx_remove(struct i2c_client *client){//printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);<span style="color:#ff0000;">device_destroy(class, MKDEV(major, 0));class_destroy(class);</span>unregister_chrdev(major, "at24cxx");return 0;}
- 自动创建设备节点 device_create
- 自动创建设备节点 device_create
- class_create(),class_device_create()或device_create()自动创建设备节点
- device_create创建设备节点分析
- device_create device_destroy 使用==mknod及通过class_create自动创建设备节点
- device_create device_destroy 使用==mknod及通过class_create自动创建设备节点
- device_create device_destroy 使用==mknod及通过class_create自动创建设备节点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点 .
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- 解决ADT插件不兼容问题
- 字符串面试题—字符串逆序
- Isnull() CAST()函数
- 基数排序
- 某游戏攻城师的2014年年度总结
- 自动创建设备节点 device_create
- 开启博客模式
- 设置HtmlUnitDriver代理及处理用户验证问题
- mac 终端 常用命令
- Caffe + Ubuntu 14.04 64bit + CUDA 6.5 配置说明
- if exists (select *from sysobjects where name='shangpininsert ')
- OpenGL常识汇总
- 生活中需要注意的细节
- Eclipse将引用了第三方jar包的Java项目打包成jar文件的两种方法