博航智能圈

标题: 动态申请设备号 和 自动创建设备节点 [打印本页]

作者: 博航技术    时间: 2015-1-29 19:40:09     标题: 动态申请设备号 和 自动创建设备节点

编译完  hello 模块之后开始学习 字符型设备的驱动开发,
今天从LED 的驱动函数开始。在linux-3.0.8/driver/char目录下有一个mini210_leds.c文件,在在此基础上修改得到我的MYLED.c

本想加载动态加载进内核测试,但是出现错我   提示
cannot insert '*.ko': Device or resource busy错误。

查了一下发现是设备号被占用了,因为系统中已经有了led 驱动,就是inux-3.0.8/driver/char目录下mini210_leds.c文件生成的,所以在此加载是,不改变注册方式,肯定是加载不进来的,所以想办法把自己的驱动加载进内核。
参考:http://www.linuxidc.com/Linux/2014-03/97438.htm
用动态申请设备号和动态创建设备节点的方式实现:
添加头文件
//下面这三个头文件是由于动态创建需要加的
#include <asm/device.h>
#include <linux/device.h>
#include <linux/cdev.h>

程序中添加
dev_t dev = 0;   //这里是动态分配设备号和动态创建设备结点需要用到的                     added *
struct cdev dev_c;                                                                                                   // added

把原有的设备模块初始化函数改为:
static int __init smdkv210_led_dev_init(void) {
int ret,err;
ret = alloc_chrdev_region(&dev, 0, 1,DEVICE_NAME); //动态分配设备号
if (ret)
{
printk("globalvar register failure\n");
    unregister_chrdev_region(dev,1);
    return ret;
}
else
{
printk("globalvar register success\n");
}

cdev_init(&dev_c, &smdkv210_led_dev_fops);

err = cdev_add(&dev_c, dev, 1);

if(err)
{
    printk(KERN_NOTICE "error %d adding FC_dev\n",err);
    unregister_chrdev_region(dev, 1);
    return err;
}

cdev_class = class_create(THIS_MODULE, DEVICE_NAME);//动态创建设备结点
if(IS_ERR(cdev_class))
{
printk("ERR:cannot create a cdev_class\n");
    unregister_chrdev_region(dev, 1);
    return -1;
}

device_create(cdev_class,NULL, dev, 0, DEVICE_NAME);

return ret;
}
把原有的卸载函数改为
static void __exit smdkv210_led_dev_exit(void)
{
device_destroy(cdev_class, dev);
class_destroy(cdev_class);
unregister_chrdev_region(dev,1);
printk("globalvar_exit \n");
}

之后
按照模块加载的方式 生成 .ko文件  ,下载到开发板之后 insmod
就会加载成功,并在/dev下创建了设备节点。






欢迎光临 博航智能圈 (http://club.broadon.net/club/) Powered by Discuz! X2