IMX6ULL嵌入式Linux驱动学习笔记(四)

本文介绍IMX6ULL嵌入式Linux平台上的字符设备驱动开发,包括新字符设备驱动原理、自动创建设备节点、文件私有数据的设置及错误处理等内容。

IMX6ULL-Linux开发学习
以下内容是我在学习正点原子IMX6ULL开发板alpha中记录的笔记,部分摘录自正点原子IMX6ULL开发手册

一、新字符设备驱动原理(相比于上一篇笔记)

  1. 以前的缺点:

    使用 register_chrdev 函数注册字符设备,会浪费很多次设备号,而且需要手动指定。

  2. 新的方法:

    使用 alloc_chrdev_region 函数申请设备号。原型如下:

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)

卸载驱动的时候,使用 unregister_chrdev_region 函数释放前面申请的设备号,原型如下:

void unregister_chrdev_region(dev_t from, unsigned count)
  1. 指定设备号

    如果指定主设备号,使用 register_chrdev_region 函数来注册,原型如下:

    int register_chrdev_region(dev_t from, unsigned count, const char *name)
    

    一般是给定主设备号,然后使用 MADEV 构建完整的 dev_t ,一般次设备号选择0

  2. 实际的驱动编写

    需要考虑实际情况,因为在实际开发中会有两种情况:给定设备号和没有给定设备号。

  3. 字符设备注册

    cdev 结构体表示字符设备,然后使用 cdev_init 函数来初始化 cdev ,原型

cdev_init(struct cdev *cdev, const struct file_operations *fops)

cdev_init 初始化完成 cdev 后,使用 cdev_add 添加到Linux内核,删除字符设备使用 cdev_del

二、自动创建设备节点

  1. linux内核在2.6版本中引入了 udev 机制,替换devfsudev 机制提供热插拔管理,可以在加载驱动的时候自动创建 /dev/xxx 设备文件。
  2. 在使用busybox构建根文件系统的时候,busybox会创建一个 udev 的简化版本 mdev ,所以在嵌入式linux中使用 mdev 来实现设备节点文件的自动创建和删除。linux系统中的热插拔事件也由 mdev 管理,在 /etc/init.d/rsS 文件中如下语句。
11 echo /sbin/mdev > /proc/sys/kernel/hotplug
12 mdev -s
  1. 创建设备节点

    3.1. 创建设备类

    创建设备节点需要先 使用class_create() 函数创建类。

    /* 创建设备类 */
    newChrLed.class = class_create(THIS_MODULE, LED_NAME);
    if (IS_ERR(newChrLed.class))
    {
         
         
        return PTR_ERR(newChrLed.class);
    }
    

    3.2. 创建设备节点

    使用 device_create() 函数来创建设备节点。

    /* 创建设备节点 */
    newChrLed.device = device_create(newChrLed.class, NULL, newChrLed.devid, NULL, LED_NAME);
    if (IS_ERR(newChrLed.device))
    {
         
         
        return PTR_ERR(newChrLed.device);
    }
    
  2. 销毁设备节点和类

    在驱动卸载的时候,需要对设备进行销毁。在驱动出口函数中使用如下代码进行销毁:

    /* 摧毁设备节点 */
    device_destroy(newChrLed.class, newChrLed.devid);
    
    /* 摧毁设备类 */
    class_destroy(newChrLed.class);
    

    因为创建设备节点是根据类来创建的,因此在销毁时,需要先销毁设备节点再销毁类。

三、文件私有数据

  1. open 函数里设置 filp->private_data 为设备变量。
/* 设置私有数据 */
filp->private_data= &newChrLed;
  1. 在其他的函数里,要访问设备的时候,直接读取私有数据
struct newChrLed_dev *dev = filp->private_data;

四、错误处理

​ 在 xxx_init 加载驱动出现错误的时候,可以使用 goto 语句,对错误进行处理。比如:

newChrLed.cdev.owner = THIS_MODULE;
ret = cdev_init(&newChrLed.cdev, &newChrLed_fops);
if (ret < 0)
{
   
   
    goto fail_cdev;
}

ret = cdev_add(&newChrLed.cdev, newChrLed.devid, 1);
if (ret < 0)
{
   
   
    goto fail_cdev;
}

fail_cdev:
	/* 删除字符设备 */
	cdev_del
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值