创建字符设备
~/study/linuxlerning/linux-4.9.37/driver_test
Linux字符设备是一种按字节来访问的设备,字符驱动则负责驱动字符设备,这样的驱动通常实现open、close、read和write系统调用。例如:串口、Led、按键等。
创建字符设备文件的方法
1、使用命令 mknod /dev/文件名 c 主设备号 此设备号(查看主设备号:cat /proc/devices)
文件系统与字符设备驱动程序之间的关系
1、在Linux系统中,每一个打开的文件,在内核中都会关联一个struct file结构,它是由内核在打开文件时创建,在文件关闭后释放
struct file结构中的重要成员
struct file_operations* f_op; //文件操作函数集
loff_t f_pos; //文件读写指针
2、每一个存在于文件系统中的文件都会关联一个inode结构,该结构主要用来记录文件物理上的信息。因此,它和代表打开文件的file结构是不同的,一个文件没有被打开时不会关联file结构,但是会关联一个inode结构(存于磁盘,操作文件是在内存中建立相应的映射结构)
3、系统实质上是把字符设备的注册表看成了文件。其中chrdevs[]在内核的定义如下
static struct char_device_struct {
struct char_device_struct *next;
unsigned int major;
unsigned int baseminor;
int minorct;
char name[64];
struct cdev *cdev; /* will die */
} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
4、 字符设备在内核中使用struct cdev来描述
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops; //设备操作函数集
struct list_head list;
dev_t dev; //设备号
unsigned int count; //设备数
};
5、Linux内核中使用dev_t类型来定义设备号,dev_t其实质为32位unsigned int类型,其中高12位为主设备号,低20位为次设备号。
(1)MKDEV(主设备号,次设备号)
(2)MAJOR(dev_t dev)
(3)MINOR(dev_t dev)
注:字符设备文件与字符设备驱动是通过主设备号建立对应关系;驱动程序用次设备号来区分同类型的设备
设备号的申请与注销
(1)静态申请:开发者自己选择一个数字作为主设备号,通过函数 register_chardev_region 向内核申请
(2)动态分配:使用 alloc_chrdev_region 由内核分配一个可用的主设备号(推荐使用)
(3)不论使用何种方法分配设备号,都应该在驱动退出时,使用 unregister_chrdev_region 函数释放这些设备
字符设备描述结构的分配、注册与注销
- 字符设备描述结构的分配、注册与注销
(1)cdev变量的定义可以采用静态和动态两种方法
* 静态分配:struct cdev mdev;
* 动态分配:struct cdev* pdev = cdev_alloc();(可以通过命令:cat /proc/devices查看主设备号)
(2)cdev变量的初始化使用cdev_init()函数来完成
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
cdev: 待初始化的cdev结构
fops: 设备对应的操作函数集
(3)字符设备的注册使用cdev_add()函数来完成
(4)字符设备的注销使用cdev_del()函数来完成
设计Linux字符设备驱动程序的主要工作:
(1)根据外部设备的特点,实现file_operations结构所需要的函数
(2)调用函数cdev_alloc()函数向系统动态申请一个cdev结构实例
(3)调用函数cdev_init()初始化cdev实例,并建立cdev实例与file_operations实例之间的连接
(4)调用函数alloc_chrdev_region()向系统申请一个设备号
(5)调用函数cdev_add()向系统添加一个设备
(6)调用函数cdev_del()从系统删除一个cdev结构实例
注:如果把驱动程序制作成一个内核模块,上述的第(2)、(3)、(4)、(5)步应在模块的初始化函数中实现,而第(6)步应在模块的卸载函数中实现
一键创建
register_chrdev(major,fops)) 创建
1、第一个参数静态申请设备号,如果是0,则系统随机分配
2、fops
__unregister_chrdev() 注销
网友评论