作者:武汉华嵌嵌入式培训 长沙中心 讲师: 周龙
Step 1: 申请设备号(主要是申请主设备号)
有两种方式:
⑴静态申请
通过下面这个函数实现:
int register_chrdev_region(dev_t from, unsigned count, const char *name);
/* register_chrdev_region() - register a range of device numbers
* @from:the first in the desired range of device numbers; must include
* the major number.
* @count: the number of consecutive device numbers required
* @name: the name of the device or driver.
*
* Return value is zero on success, a negative error code on failure.*/
这种方式主要用于,驱动开发者事先知道该驱动主设备号的情况。
⑵动态申请
通过下面这个函数实现:
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
/* alloc_chrdev_region() - register a range of char device numbers
* @dev: output parameter for first assigned number
* @baseminor: first of the requested range of minor numbers
* @count: the number of minor numbers required
* @name: the name of the associated device or driver
*
* Allocates a range of char device numbers. The major number will be
* chosen dynamically, and returned (along with the first minor number)
* in @dev. Returns zero or a negative error code.*/
这种方式由系统动态分配一个设备号,返回的设备号保存在参数dev中。
Step 2 :注册字符设备
在linux 内核中用struct cdev表示一个字符设备。
字符设备的注册与注销分别通过下面的两个函数来实现:
int cdev_add(struct cdev *p, dev_t dev, unsigned count);
/**
* cdev_add() - add a char device to the system
* @p: the cdev structure for the device
* @dev: the first device number for which this device is responsible
* @count: the number of consecutive minor numbers corresponding to this
* device
*
* cdev_add() adds the device represented by @p to the system, making it
* live immediately. A negative error code is returned on failure.
*/
void cdev_del(struct cdev *p);
不过,在注册一个字符设备之前,要调用下面这个函数来初始化struct cdev结构体:
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
/**
* cdev_init() - initialize a cdev structure
* @cdev: the structure to initialize
* @fops: the file_operations for this device
*
* Initializes @cdev, remembering @fops, making it ready to add to the
* system with cdev_add().
*/
另外,struct cdev结构体变量可以声明为一个指针,内核提供了一个函数来申请:
struct cdev *cdev_alloc(void);
step 3:创建设备节点
有两种方法:
一是通过mknod命令来创建。如:
mknod /dev/yourname c major minor
其中“yourname”可以是任意符合unix下路径名的名字,不一定要是你代码里定义的驱动或设备的名字;c 表示创建字符设备节点,major是你成功申请的主设备号,minor是次设备号,这个可以是任意的(在次设备号范围内)
另外一种方法是通过udev自动生成。这种方法需要在你的代码里创建一个设备类,然后在这个设备类的基础上,创建一个设备;另外应用程序需要跑一个udevd的后台程序。
struct class* class_create(owner, name);
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)