瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。
第12章 字符设备驱动框架实验
下面对前面三个章节进行总结,首先驱动向Linux内核进行设备号申请,之后的字符设备注册时,会对申请的设备号进行使用。而Linux 内核会将字符设备抽象成一个具体的struct cdev结构体,该结构体记录了字符设备的字符设备号、内核对象等信息,cdev_init(…)函数对结构体进行初始化之后,cdev_add(…)函数将设备号和cdev结构体进行链接,这时设备号才真正指向了内核中注册的设备。设备注册成功之后,此时还不能对字符设备进行文件操作,所以需要设备节节点来充当内核和用户层通信的桥梁,至此,前面三个章节就总结完成了,以上步骤并没有涉及到操作设备文件,本章节将对字符设备框架进行最终的完善。
12.1 文件操作集简介
在进行注册字符设备实验章节中,使用cdev_init(…)函数对struct cdev结构体类型变量和struct file_operations结构体类型变量相链接,struct file_operations结构体就是把系统调用和驱动程序关联起来的关键数据结构。该结构体的每一个成员都对应着一个系统调用,读取file_operation中相应的函数指针,接着把控制权转交给函数,从而完成了Linux设备驱动程序的工作。
file_operations结构体定义在“内核源码/include/linux/fs.h”文件中,下面对部分常用函数进行说明:
struct module *owner;
owner是第一个 file_operations 成员,它并不是一个操作, 而一个指向拥有该结构的模块的指针,避免正在操作时被卸载,一般为初始化为THIS_MODULES (在 <linux/module.h> 中定义的宏)
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
read函数指针用来从设备中同步读取数据,读取成功返回读取的字节数。与应用程序中的 read函数对应。
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
write函数指针用来发送数据给设备. 写入成功返回写入的字节数。与应用程序中的write函数对应。
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
unlocked_ioctl函数指针提供对于设备的控制功能,与应用程序中的ioctl函数对应。
int (*open) (struct inode *, struct file *);
open函数指针用于打开设备,与应用程序中的open函数对应。
int (*release) (struct inode *, struct file *);
release函数指针在file结构体释放时被调用
至此对于file_operations文件操作集的部分常用函数就介绍完了,填充了部分常用函数的 file_operations结构体如下(图12-1)所示:
static struct file_operations cdev_fops_test = {
.owner = THIS_MODULE,//将owner字段指向本模块,可以避免在模块的操作正在被使用时卸载该模块
.open = chrdev_open,//将open字段指向chrdev_open(...)函数
.read = chrdev_read,//将open字段指向chrdev_read(...)函数
.write = chrdev_write,//将open字段指向chrdev_write(...)函数
.release = chrdev_release,//将open字段指向chrdev_release(...)函数
};//定义file_operations结构体类型的变量cdev_test_ops
会在下个小节进行字符设备驱动框架实验代码的编写,在上一章节实验的基础上加入file_operations结构体,并通过应用程序对字符设备驱动进行文件操作测试。
更多内容可以B站搜索:迅为RK3568,关注公众号:迅为电子
|