【原创】嵌入式字符设备驱动概述
0赞成都六月天,阴沉沉的,最近在做驱动,今天给大家写一下相关的内容。
声明头文件:linux/cdev.h |
struct cdev { ... struct module *owner; //一般是THIS_MODULE const struct file_operations *ops;//指向操作方法集,用于登记初始化、注销、控制等操作设备函数 dev_t dev; //设备号,用于查找设备 unsigned int count; //设备数量,一般是1. }; |
4.2、主要的字符设备对象内核函数
/* *功能:分配字符设备对象 *参数: * void *返回值: * 成功:指向字符设备对象的首地址指针;失败:NULL */ struct cdev *cdev_alloc(void); |
/* *功能:初始化字符设备对象 *参数: * struct cdev * 指向被初始化的字符设备对象 * const struct file_operations *指向操作方法集 *返回值: * void */ void cdev_init(struct cdev *, const struct file_operations *); |
/* *功能:注册字符设备对象 *参数: * struct cdev *指向被注册的字符设备对象 * dev_t 设备号 * unsigned 设备数量 *返回值: * 成功:0;失败:错误码 */ int cdev_add(struct cdev *, dev_t, unsigned); |
/* *功能:注销字符设备对象 *参数: * struct cdev *指向被注销的字符设备对象 *返回值: * void */ void cdev_del(struct cdev *); |
4.3、字符设备操作函数集
struct file_operations主要用来登记控制设备的接口,驱动设计者编写好控制设备的函数,登记在这个结构体里面,封装进cdev对象里,注册给用户层来用调用。
声明头文件:linux/fs.h |
struct file_operations { //模块所有者,一般是THIS_MODULE struct module *owner;
//定位设备读写接口 loff_t (*llseek) (struct file *, loff_t, int);
//同步读接口 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); //同步写接口 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); //异步读接口 ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); //异步写接口 ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
//轮询接口 unsigned int (*poll) (struct file *, struct poll_table_struct *);
//设备参数读写、状态读及控制接口 int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);//加内核锁接口 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);//未加内核锁接口 long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
//把内核空间映射给用户层的接口 int (*mmap) (struct file *, struct vm_area_struct *);
//打开设备接口 int (*open) (struct inode *, struct file *); //刷新设备数据接口 int (*flush) (struct file *, fl_owner_t id); //关闭设备接口 int (*release) (struct inode *, struct file *);
//异步通知接口 int (*fasync) (int, struct file *, int);
... }; |
下面就讲设备号的用处了!