字符设备驱动(API)自动创建字符设备文件节点
字符设备驱动(新API函数)
前言
之前的字符设备,采用register_chrdev与unregister_chedev完成驱动的注册与卸载,而且还需要手动创建设备节点,比较不方便。
目前可采用新的注册与卸载函数,完成驱动的注册与卸载。实现在驱动模块的加载过程中,完成自动创建设备节点。
设备号的申请与释放
字符设备号申请
旧的驱动注册函数register_chrdev,需要我们提供一个主设备号。该方式有两个问题:需要事先确认哪些主设备号没有使用。次设备号都被使用掉,而不管实际设备有多少个,造成浪费。最好的情况:一个具体的设备:一个主设备号,一个次设备号。
这对上述缺点,最好向内核申请设备号。采用的API接口。
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
*dev:保存设备号。
baseminor:次设备号初始号。
count:申请设备的数量。
name:设备名称。
确定主设备号与次设备号之后,采用如下接口来注册设备号:
int register_chrdev_region(dev_t from, unsigned count, const char *name)
from:申请的起始设备号。
count:申请的数量。
name:设备名字。
字符设备号释放
注册设备号之后,使用完成后。需要释放掉设备号:
void unregister_chrdev_region(dev_t from, unsigned count)
通过以上接口,将设备号释放。
字符设备驱动
在linux中,有一个有关设备的结构体:cdev:
图 1 Linux中的cdev结构
在cdev的重要成员变量:ops和dev。Ops是函数操作集合。dev是设备号变量。编写设备驱动需要定义一个cdev结构体变量,这个变量表示一个字符设备。
对于一个设备,定义一个变量:struct cdev my_cdev
首先需要完成对cdev的初始化
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
向Linux OS 系统添加字符设备:
int cdev_add(struct cdev *p_cdev, dev_t dev, unsigned count)
参数p_cdev表示需要添加的字符设备(cdev的结构体变量)。dev是申请的设备号。count是添加设备的数量。
卸载的过程,需要卸载设备
void cdev_del(struct cdev *p_cdev)
p_cdev就是需要删除的字符设备。
设备节点文件创建
自动创建设备节点文件,不需要手动操作,方便快捷。
创建和删除类
自动创建设备节点是在驱动程序的入口函数完成。自动创建需要创建类,具体接口如下:
struct class *class_create (struct module *owner, const char *name)
参数一共两个:owner 表示是属于这个模块。Name表示class的名字。
卸载驱动程序,需要删除掉类,类删除函数class_destroy,接口函数如下所示:
void class_destroy(struct class *cls);
创建设备
创建好类以后需要创建一个设备,才可以创建设备节点。Device_create是在类下创建设备,device_create函数原型如下:
struct device *device_create(struct class *class,struct device *parent,dev_t devt,void *drvdata,const char *fmt, ...)
class表示在那个类下创建设备,参数parent是父设备,可以设置NULL。
Devt是设备号。Drvdata是设备是可能会使用一些数据。
Fmt是设备名字,如果设置fmt=xxx,就会生成/dev/xxx的设备文件。
删除创建的设备,使用如下接口:
void device_destroy(struct class *class, dev_t devt)
class是删除的设备所处的类,devt是设备号。