Chinaunix首页 | 论坛 | 博客
  • 博客访问: 207079
  • 博文数量: 91
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 15
  • 用 户 组: 普通用户
  • 注册时间: 2015-12-09 10:37
文章分类
文章存档

2016年(87)

2015年(4)

我的朋友

分类: LINUX

2016-02-26 09:29:51

每次测试自己写的驱动模块都要自己mknod设备文件,总觉得是一种不好的行为
而且要自己指定主设备号和次设备号,就是没有书上说sysfsudev什么程序员不需关心设备号之类的优点了

内核TMD经常变,一个2.6.25上还好好的驱动,跑到2.6.29上就不能编译通过了,妈的,
可以理解为什么Linux驱动工程师会高薪了,好,我忍了


这里的方法只能保证倒2.6.31,再往后就未知了,所以死读书是不行的
要融会贯通,深入理解,有问题直接到内核代码里找答案

2.6.17以前,在/dev目录下生成设备文件很容易,
devfs_mk_bdev
devfs_mk_cdev
devfs_mk_symlink
devfs_mk_dir
edvfs_remove
这几个是纯devfsapi2.6.17以前可用,但是后来devfs被抛弃,采用sysfs+udev的形式

同时期sysfs文件系统可以用的api
class_device_create_file
2.6.26以后也不行了

现在,好使的是device_create ,从2.6.18开始可用
/**
* device_create - creates a device and registers it with sysfs
* @class: pointer to the struct class that this device should be registered to
* @parent: pointer to the parent struct device of this new device, if any
* @devt: the dev_t for the char device to be added
* @fmt: string for the device's name
*
* This function can be used by char device classes.  A struct device
* will be created in sysfs, registered to the specified class.
*
* A "dev" file will be created, showing the dev_t for the device, if
* the dev_t is not 0,0.
* If a pointer to a parent struct device is passed in, the newly created
* struct device will be a child of that device in sysfs.
* The pointer to the struct device will be returned from the call.
* Any further sysfs files that might be required can be created using this
* pointer.
*
* Note: the struct class passed to this function must have previously
* been created with a call to class_create().
*/
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, const char *fmt, ...)

2.6.26起又多了一个参数drvdata the data to be added to the device for callbacks
不会用就给个NULL
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)




试例程序
会在/dev/下生成test_usb 设备文件,并且在/sys也有相应文件
#include
#include
#include
#include
#include
#include
#include

MODULE_DESCRIPTION("My kernel module");
MODULE_AUTHOR("deep_pro");
MODULE_LICENSE("GPL");

static struct class *usb_class;
static struct device *dev;
static const char shortname [] = "test_usb";
static dev_t test_usb_devno;


static int test_sysfs_init_module(void)
{
int    ret;
printk( KERN_DEBUG "Module test_sysfs init\n" );
usb_class = class_create(THIS_MODULE, shortname);
if (IS_ERR(usb_class))
{
printk( KERN_DEBUG "class_create error\n" );
return -1;
}

ret=alloc_chrdev_region(&test_usb_devno, 0, 1, shortname);
if (ret)
{
printk( KERN_DEBUG "alloc_chrdev_region error\n" );
class_destroy(usb_class);
return ret;
}

dev=device_create(usb_class, NULL, test_usb_devno, shortname);
//2.6.26
以上
// dev=device_create(usb_class, NULL, test_usb_devno, NULL,shortname);
return 0;
}

static void test_sysfs_exit_module(void)
{
/* Remove sysfs files */
device_destroy(usb_class, test_usb_devno);
unregister_chrdev_region(test_usb_devno, 1);
class_destroy(usb_class);
printk( KERN_DEBUG "Module test_sysfs exit\n" );
}

module_init(test_sysfs_init_module);
module_exit(test_sysfs_exit_module);

阅读(1098) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~