【LV14 day4 字符设备驱动基础框架】

一、字符设备驱动框架解析

设备的操作函数如果比喻是桩的话(性质类似于设备操作函数的函数,在一些场合被称为桩函数),则:

驱动实现设备操作函数 ----------- 做桩

insmod调用的init函数主要作用 --------- 钉桩

rmmod调用的exitt函数主要作用 --------- 拔桩

应用层通过系统调用函数间接调用这些设备操作函数 ------- 用桩
1.1 两个操作函数中常用的结构体说明

内核中记录文件元信息的结构体
struct inode
{
//…
dev_t i_rdev;//设备号
struct cdev i_cdev;//如果是字符设备才有此成员,指向对应设备驱动程序中的加入系统的struct cdev对象
//…
}
/

1. 内核中每个该结构体对象对应着一个实际文件,一对一
2. open一个文件时如果内核中该文件对应的inode对象已存在则不再创建,不存在才创建
3. 内核中用此类型对象关联到对此文件的操作函数集(对设备而言就是关联到具体驱动代码)
*/

读写文件内容过程中用到的一些控制性数据组合而成的对象------文件操作引擎(文件操控器)
struct file
{
//…
mode_t f_mode;//不同用户的操作权限,驱动一般不用
loff_t f_pos;//position 数据位置指示器,需要控制数据开始读写位置的设备有用
unsigned int f_flags;//open时的第二个参数flags存放在此,驱动中常用
struct file_operations *f_op;//open时从struct inode中i_cdev的对应成员获得地址,驱动开发中用来协助理解工作原理,内核中使用
void *private_data;//本次打开文件的私有数据,驱动中常来在几个操作函数间传递共用数据
struct dentry f_dentry;//驱动中一般不用,除非需要访问对应文件的inode,用法flip->f_dentry->d_inode
int refcnt;//引用计数,保存着该对象地址的位置个数,close时发现refcnt为0才会销毁该struct file对象
//…
};
/

1. open函数被调用成功一次,则创建一个该对象,因此可以认为一个该类型的对象对应一次指定文件的操作
2. open同一个文件多次,每次open都会创建一个该类型的对象
3. 文件描述符数组中存放的地址指向该类型的对象
4. 每个文件描述符都对应一个struct file对象的地址
*/

1.2 字符设备驱动程序框架分析

驱动实现端:
在这里插入图片描述

驱动使用端:
在这里插入图片描述整体流程以open函数为例
应用层app系统调用open函数使用文件名,struct inode查询是否有该文件名的对象,若没有则创建,有则查询该设备的设备好devno对应的cdev对象,再通过cdev对象得到操作函数集fops,然后open函数创建struct file对象将操作函数集设置到该对象下面的成员f_ops里面,再把struc file对象填到描述符数组里面,得到文件描述符,同时调用驱动程序的drive_open函数,再通过system_open函数返回文件描述符给到应用层的open函数。

若要调用read函数则根据文件描述符找到对应的struct file 对象然后通过里面的f_ops操作函数集调用驱动程序对应的read函数。

syscall_open函数实现的伪代码:

int syscall_open(const char *filename,int flag)
{
dev_t devno;
struct inode *pnode = NULL;
struct cdev *pcdev = NULL;
struct file *pfile = NULL;
int fd = -1;

/*根据filename在内核中查找该文件对应的struct inode对象地址找到则pnode指向该对象未找到则创建新的struct inode对象,pnode指向该对象,并从文件系统中读取文件的元信息到该对象*/
if(/*未找到对应的struct inode对象*/)
{/*根据文件种类决定如何进行下面的操作,如果是字符设备则执行如下操作*//*从pnode指向对象中得到设备号*/devno = pnode->i_rdev;/*用devno在字符设备链表查找对应节点,并将该节点的地址赋值给pcdev*//*pcdev赋值给pnode的i_cdev成员*/pnode->i_cdev = pcdev;
}/*创建struct file对象,并将该对象的地址赋值给pfile*/pfile->f_op = pnode->i_cdev->ops;
pfile->f_flags = flag;/*调用驱动程序的open函数*/
pfile->f_op->open(pnode,pfile,flag);/*将struct file对象地址填入进程的描述符数组,得到对应位置的下标赋值给fd*/return fd;

}

syscall_read函数实现的伪代码

int syscall_read(int fd,void *pbuf,int size)
{
struct file *pfile = NULL;
struct file_operations *fops = NULL;
int cnt;

/*将fd作为下标,在进程的描述符数组中获得struct file对象的地址赋值给pfile*//*从struct file对象的f_op成员中得到操作函数集对象地址赋值给fops*//*从操作函数集对象的read成员得到该设备对应的驱动程序中read函数,并调用之*/
cnt = fops->read(pfile,pbuf,size,&pfile->f_pos);。。。。
return cnt;

}

1.3 参考原理图

字符设备驱动框架

Linux字符设备驱动工作原理图
1.4 常用操作函数说明

int (*open) (struct inode *, struct file ); //打开设备
/

指向函数一般用来对设备进行硬件上的初始化,对于一些简单的设备该函数只需要return 0,对应open系统调用,是open系统调用函数实现过程中调用的函数,
*/

int (*release) (struct inode *, struct file ); //关闭设备
/

,指向函数一般用来对设备进行硬件上的关闭操作,对于一些简单的设备该函数只需要return 0,对应close系统调用,是close系统调用函数实现过程中调用的函数
*/

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系统调用函数实现过程中调用的函数
*/

loff_t (*llseek) (struct file , loff_t, int); //数据操作位置的定位
/

指向函数用来获取或设置设备数据的开始操作位置(位置指示器),对应lseek系统调用,是lseek系统调用函数实现过程中调用的函数
*/

long (*unlocked_ioctl) (struct file , unsigned int, unsigned long);//读写设备参数,读设备状态、控制设备
/

指向函数用来获取、设置设备一些属性或设备的工作方式等非数据读写操作,对应ioctl系统调用,是ioctl系统调用函数实现过程中调用的函数
*/

unsigned int (*poll) (struct file *, struct poll_table_struct );//POLL机制,实现对设备的多路复用方式的访问
/

指向函数用来协助多路复用机制完成对本设备可读、可写数据的监控,对应select、poll、epoll_wait系统调用,是select、poll、epoll_wait系统调用函数实现过程中调用的函数
*/

int (*fasync) (int, struct file , int); //信号驱动
/

指向函数用来创建信号驱动机制的引擎,对应fcntl系统调用的FASYNC标记设置,是fcntl系统调用函数FASYNC标记设置过程中调用的函数
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/712847.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

都说了能不动就别动,非要去调整,出生产事故了吧

MyBatis 替换成 MyBatis-Plus 背景介绍 一个老项目,数据库用的是 MySQL 5.7.36 , ORM 框架用的 MyBatis 3.5.0 , mysql-connector-java 版本是 5.1.26 新来了一个干练的小伙,精力充沛,看着就是一个喜欢折腾的主 他…

leetcode 3.1

leetcode hot 100 双指针1.三数之和2.接雨水 多维动态规划1.最长公共子序列 双指针 1.三数之和 三数之和 排序 双指针的方法&#xff0c;固定一个数nums[i], 用两数和找target - nums[i] 的数需要注意两点: 1.需要去掉重复数字 while (l < r && nums[l] nums[…

社交APP开发能给用户带来什么

现在的社交软件也非常的多&#xff0c;每款社交软件都有自己的特色&#xff0c;社交软件是日常中必备的软件&#xff0c;不管是生活交流还是感情工作交流都是比较方便的&#xff0c;因为社交软件满足了日常的远程交流问题&#xff0c;所以开发社交软件也会逐渐的流行起来的。 …

【Qt学习】QLCDNumber的介绍与实例使用(倒计时功能)

文章目录 1. 介绍2. 实例 - QLCDNumber倒计时3. 资源文件 1. 介绍 QLCDNumber是Qt框架中用于显示数字的控件&#xff0c;它模拟了一个液晶数字显示屏。 在Designer界面中显示如下&#xff1a; 有以下 常用属性&#xff1a; 属性描述intValue获取或设置QLCDNumber显示的整数…

js截取图片地址后面的参数和在路径中截取文件名或后缀名

文章目录 前言截取地址 &#xff1f;后面的参数在路径中截取文件名或后缀名总结 前言 在处理网页上的图片资源或者其他类型的文件资源时&#xff0c;你可能会遇到需要使用这些技巧的情况。以下是一些具体的使用场景&#xff1a; 动态修改图片参数&#xff1a;如果你有一个图片U…

【BBuf的CUDA笔记】十四,OpenAI Triton入门笔记三 FusedAttention

0x0. 前言 继续Triton的学习&#xff0c;这次来到 https://triton-lang.org/main/getting-started/tutorials/06-fused-attention.html 教程。也就是如何使用Triton来实现FlashAttention V2。对于FlashAttention和FlashAttention V2网上已经有非常多的介绍了&#xff0c;大家如…

Win11系统安装安卓子系统教程

随着Win11系统的不断普及&#xff0c;以及硬件设备的更新换代&#xff0c;我相信很多同学都已经更新并使用到了最新的Win11系统。那么&#xff0c;Win11系统最受期待的功能“Windows Subsystem for Android”&#xff08;简称WSA&#xff09;&#xff0c;即《安卓子系统》。他可…

spring.factories的常用配置项

概述 spring.factories 实现是依赖 spring-core 包里的 SpringFactoriesLoader 类&#xff0c;这个类实现了检索 META-INF/spring.factories 文件&#xff0c;并获取指定接口的配置的功能。 Spring Factories机制提供了一种解耦容器注入的方式&#xff0c;帮助外部包&am…

掘根宝典之C语言字符串输入函数(gets(),fgets(),get_s())

字符串输入前的注意事项 如果想把一个字符串读入程序&#xff0c;首先必须预留该字符串的空间&#xff0c;然后用输入函数获取该字符串 这意味着必须要为字符串分配足够的空间。 不要指望计算机在读取字符串时顺便计算它的长度&#xff0c;然后再分配空间(计算机不会这样做&a…

ai图生文的软件!分享4个受欢迎的!

在数字化时代&#xff0c;随着人工智能技术的飞速发展&#xff0c;AI图生文软件已经成为自媒体人、创作者和广告从业者手中的得力助手。这些软件能够将静态的图片转化为生动的文字&#xff0c;为图片注入灵魂&#xff0c;让观者仿佛置身于画面之中。今天&#xff0c;就让我们一…

LabVIEW和Python开发微细车削控制系统

LabVIEW和Python开发微细车削控制系统 为满足现代精密加工的需求&#xff0c;开发了一套基于LabVIEW和Python的微细车削控制系统。该系统通过模块化设计&#xff0c;实现了高精度的加工控制和G代码的自动生成&#xff0c;有效提高了微细车削加工的自动化水平和编程效率。 项目…

1950-2022年各省逐年平均降水量数据

1950-2022年各省逐年平均降水量数据 1、时间&#xff1a;1950-2022年 2、指标&#xff1a;省逐年平均降水量 3、范围&#xff1a;33省&#xff08;不含澳门&#xff09; 4、指标解释&#xff1a;逐年平均降水数据是指当年的日降水量的年平均值&#xff0c;不是累计值&#…

ONLYOFFICE 桌面编辑器 v8.0 更新内容详细攻略

文章目录 引言PDF 表单RTL 支持电子表格中的新增功能Moodle 集成用密码保护 PDF 文件从“开始”菜单快速创建文档本地界面主题下载安装桌面编辑工具总结 引言 官网链接&#xff1a; ONLYOFFICE 官方网址 ONLYOFFICE 桌面编辑器是一款免费的文档处理软件&#xff0c;适用于 Li…

uniapp实现-审批流程效果

一、实现思路 需要要定义一个变量, 记录当前激活的步骤。通过数组的长度来循环数据&#xff0c;如果有就采用3元一次进行选择。 把循环里面的变量【name、status、time】, 全部替换为取出的那一项的值。然后继续下一次循环。 虚拟的数据都是请求来的, 组装为好渲染的格式。 二…

【打工日常】使用docker部署在线PDF工具

一、Stirling-PDF介绍 Stirling-PDF是一款功能强大的本地托管的基于 Web 的 PDF 操作工具&#xff0c;使用 docker部署。该自托管 Web 应用程序最初是由ChatGPT全权制作的&#xff0c;现已发展到包含广泛的功能来处理您的所有 PDF 需求。允许对 PDF 文件执行各种操作&#xff0…

基于session注册JAva篇springboot

springboot3全家桶&#xff0c;数据库 &#xff1a;redis&#xff0c;mysql 背景环境&#xff1a;邮箱验证码&#xff0c;验证注册 流程&#xff1a;先通过邮箱验证&#xff0c;发送验证码&#xff0c;将获取到的session和验证码&#xff0c;存入redis里&#xff08;发送邮箱…

【leetcode】链表的回文结构

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家刷题&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 点击查看题目 思路: 1.找中间节点 找中间节点的方法在下面这个博文中详细提过 【点击进入&#xff1a;【l…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:布局约束)

通过组件的宽高比和显示优先级约束组件显示效果。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 aspectRatio aspectRatio(value: number) 指定当前组件的宽高比。 卡片能力&#xff1a; 从API vers…

浅谈 Linux 孤儿进程和僵尸进程

文章目录 前言孤儿进程僵尸进程 前言 本文介绍 Linux 中的 孤儿进程 和 僵尸进程。 孤儿进程 在 Linux 中&#xff0c;就是父进程已经结束了&#xff0c;但是子进程还在运行&#xff0c;这个子进程就被称作 孤儿进程。 需要注意两点&#xff1a; 孤儿进程最终会进入孤儿院…

软考-计算题

1.二维矩阵转换成一维矩阵 2.算术表达式&#xff1a; 3.计算完成项目的最少时间&#xff1a;之前和的max&#xff08;必须之前的所有环节都完成&#xff09; 松弛时间&#xff1a;最晚开始时间-最早开始时间 最早&#xff1a;之前环节都完成的和的max 最晚&#xff1a;总时间…