字符设备实现内部驱动原理及分步注册流程

news/2024/11/28 18:49:06/

 字符设备实现内部驱动原理:

 应用层:open函数回调到驱动中open操作方法的路线:

open()--->sys_open()--->struct inode结构体--->struct cdev结构体--->struct file_operations结构体--->mycdev_open()

字符设备驱动编写流程:

1、分配对象空间

2、对象空间的初始化

3、对象的注册

4、对象的注销

流程模板(非详细)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>//定义cdev的结构体指针变量
struct cdev *cdev;
static int __init mycdev_init(void)
{//1.分配对象cdev = cdev_alloc();//2.对象的初始化cdev_init(cdev,&fops);//3.申请设备号,动态申请ret = alloc_chrdev_region(&devno,minor,count,CNAME);//4.字符设备驱动的注册
ret = cdev_add(cdev,MKDEV(major,minor),count);//5.自动创建设备节点cls = class_create(THIS_MODULE,CNAME);dev = device_create(cls,NULL,MKDEV(major,i),NULL,"mycdev%d",i);return 0;
}
static void __exit mycdev_exit(void)
{//1.销毁设备节点device_destroy(cls,MKDEV(major,i));class_destroy(cls);//2.销毁字符设备驱动cdev_del(cdev);//3.销毁设备号
unregister_chrdev_region(MKDEV(major,minor),count);//4.释放动态申请的cdev内存
kfree(cdev);}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

 inode结构体作用:

只要文件存在文件系统中,在内核中就会有一个struct inode类型的空间,用于保存该文件的信息

struct file结构体作用:

open函数参数是路径下的文件名字,根据文件名找到inode号,然后根据inode结构体,回调对应的操作方法

通过文件描述符回调对应操作方法的路径:

fd--->fd_array[fd]--->struct file--->f_op--->操作方法

linux内核中的并发和竟态解决方法:

当多个应用程序访问同一个驱动的临界资源的时候,竞态就会产生。

根本原因:

1.对于单核处理器,如果内核支持抢占就会产生竞态

2.多核处理器,核心与核心之间本身就会产生竞态。

3.中断和进程间也会产生竞态

解决方法:

1、中断屏蔽:

local_irq_disable();  //屏蔽中断
//临界资源
local_irq_enable();   //开启中断

2、自旋锁:

自旋锁:针对多核设计的,当一个进程获取到自旋锁之后,另外一个进程也想获取这把锁,此时后一个进程处于自旋状态(原地打转)(自旋锁又叫盲等锁);

特点:

1.自旋状态是需要消耗cpu资源的

2.自旋锁适合用在临界区比较小地方,临界区不能有延时,耗时,甚至休眠的操作,

临界区也不能够有copy_to_user/copy_from_user的函数。

3.自旋锁会导致死锁(在同一个进程中多次获取同一把未解锁的锁)

4.自旋锁可以在进程上下文中使用,也可以在中断上下文中使用

5.自旋锁在上锁前会关闭抢占

spinlock_t lock;        //定义自旋锁
spin_lock_init(&lock); //初始化自旋锁
spin_lock(&lock);      //上锁
spin_unlock(&lock);    //解锁

信号量:

信号量:当一个进程获取到信号量之后,另外一个进程也想获取信号量,此时后一个进程处于休眠状态。

特点:

1.休眠的进程是不消耗cpu资源的

2.信号量不会导致死锁

3.信号量保护的临界区可以很大,里面可以有延时,耗时,甚至休眠的操作。

4.信号量只能工作在进程上下文。不能工作于中断上下文。

5.信号量也不会关闭抢占

struct semaphore sem; //定义信号量
void sema_init(struct semaphore *sem, int val) //初始化信号量
//注意,这里的val只有初始化为1的时候才有能够解决竞态。当val初始化为0的时候代表同步机制
void down(struct semaphore *sem); //上锁
void up(struct semaphore *sem);//解锁

互斥体:

互斥体:当一个进程获取到互斥体之后,另外一个进程也想获取互斥体,此时后一个进程处于休眠状态。

特点:

1.休眠的进程是不消耗cpu资源的

2.互斥体不会导致死锁

3.互斥体保护的临界区可以很大,里面可以有延时,耗时,甚至休眠的操作。

4.互斥体只能工作在进程上下文。不能工作于中断上下文。

5.互斥体也不会关闭抢占

6.互斥体在进入休眠前会稍微等一会儿在进入休眠状态,但是对于临界区比较小的时候使用互斥体的效率是高于信号量的,优先使用互斥体

struct mutex mutex; //定义互斥体
mutex_init(&mutex); //初始化互斥体
void  mutex_lock(struct mutex *lock) //上锁
static int mutex_unlock(unsigned long *lock) //解锁

原子操作:

原子操作:将整个过程看做是一个不可被分割的整体。原子操作结构体内部本身就是一个变量,通过

对这个变量的值的修改来实现防止竞态的效果,对这个变量的值的修改是通过内联汇编完成的。

atomic_t atm = ATOMIC_INIT(1); //定义并初始化原子操作int atomic_dec_and_test(atomic_t *v) //上锁
功能:让原子变量的值减去1,如果结果为0 表示获取锁成功了
参数:@v:原子变量的地址
返回值:如果获取成功返回真,失败返回假void atomic_inc(atomic_t *v)   //将原子变量的值加1,解锁atomic_t atm = ATOMIC_INIT(-1); //定义并初始化原子操作
int atomic_inc_and_test(atomic_t *v) //上锁
功能:让原子变量的值加1,如果结果为0 表示获取锁成功了
参数:@v:原子变量的地址
返回值:如果获取成功返回真,失败返回假
void atomic_dec(atomic_t *v)   //将原子变量的值减去1,解锁

http://www.ppmy.cn/news/403812.html

相关文章

【机器学习】神经网络代价函数和反向传播算法

神经网络的代价函数 接下来我会再规定若干符号代表的含义&#xff1a; L L L表示神经网络的总层数 s i s_i si​表示的是第i层的神经元数量 如果神经网络处理的是一个二元分类问题&#xff0c;那么他的第L层就只会有一个节点&#xff1b;如果处理的是一个多元分类问题&…

【AI面试】损失函数(Loss),定义、考虑因素,和怎么来的

神经网络学习的方式,就是不断的试错。知道了错误,然后沿着错误的反方向(梯度方向)不断的优化,就能够不断的缩小与真实世界的差异。 此时,如何评价正确答案与错误答案,错误的有多么的离谱,就需要一个评价指标。这时候,损失和损失函数就运用而生。 开始之前,我们先做…

TableAPI

序言 我个人还是觉得直接使用DataStream更加直观,编程也更有灵活,控制起来也更方便.如果全靠一堆SQL或者方法来替代,你完全没法确定最终会转变成什么算子.编程逻辑不直观.而且肯定会造成跟多的资源浪费,比如状态存储的空间,算子间的转发.cuiyaonan2000163.com TableAPI Table…

最优化方法Python计算:一元函数搜索算法——二次插值法

已知连续函数 f ( x ) f(x) f(x)在 x ∗ x^* x∗近旁存在最优解 x 0 x_0 x0​。对博文《最优化方法Python计算&#xff1a;连续函数的单峰区间计算》讨论的 f ( x ) f(x) f(x)单峰区间的包围算法稍加修改&#xff0c;可算得 f ( x ) f(x) f(x)包含 x 0 x_0 x0​的单峰区间 [ a …

为什么看了那么多测试技术帖,自己都没有提升?

作为测试新手&#xff0c;最爱莫过于看各大牛发的技术贴&#xff0c;这篇很牛叉&#xff0c;那篇也很有道理&#xff0c;似乎自己看着看着也会成为高手。然而几年后&#xff0c;发现自己对专业知识的理解乱的很&#xff0c;里面更有很多自相矛盾的地方&#xff0c;这到底是哪里…

游泳耳机买什么牌子好一点?推荐四款出色的游泳耳机

游泳和跑步类似&#xff0c;短距离冲刺时&#xff0c;大脑没什么想法&#xff0c;而中长距离的有氧运动时&#xff0c;肉体是疲惫的&#xff0c;大脑是异常清晰的&#xff0c;时间却是格外难熬的。如何打发时间&#xff0c;让游泳锻炼变得不无聊&#xff0c;这是我从孩子时期就…

Esxi直通A40显卡给ubuntu20.4系统驱动安装过程记录

Esxi直通A40显卡给ubuntu20.4系统驱动安装过程记录 背景描述 PowerEdge R750&#xff08;esxi虚拟化&#xff09; 服务器已有一张T4显卡&#xff0c;后期新增一张A40显卡&#xff0c;开一台ubuntu20.4系统直通A40显卡无法开机&#xff01; 开机问题解决后安装显卡驱动也各种报…

airpods pro是按压还是触摸_数码产品:airpodspro触摸区域在哪里 触摸感应在哪

最近小编发现大家对于airpodspro触摸区域在哪里 触摸感应在哪都很感兴趣&#xff0c;那么小编也是特地整理了一些跟airpodspro触摸区域在哪里 触摸感应在哪相关的知识&#xff0c;那么今天就来分享给大家关于airpodspro触摸区域在哪里 触摸感应在哪的知识吧。 airpodspro触摸区…