linux驱动入门与开发知识点

本文深入探讨了Linux设备驱动的核心概念,包括主次设备号的静态与动态分配、设备号的查询与释放、cdev结构体及设备操作函数。详细介绍了并发控制机制,如原子变量操作、自旋锁、互斥锁、信号量和完成量的特点与应用场景。解析了原子操作的多种方法及其在资源计数中的应用。阐述了时钟机制、时间度量与延迟处理,以及中断处理过程和内存分配策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

六、主次设备号
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

静态分配设备号:register_chrdev_region() 在<fs/char_dev>定义
这些设备号在内核源码 documentation/devices.txt中找到
动态分配设备号: alloc_chrdev_region()
查看设备号: cat /proc/device() 读取/proc/devices文件获得设备号
释放设备号: unregister_chrdev_region()
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

cdev
在这里插入图片描述

open 设备 A ==》 创建 inode 结点
inode ->icdev ==> cdev字符结构体
cdev ->ops ==> A 的操作函数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

数据交换函数
copy_to_user(void __user *to , const void from,unsigned long n)
copy_from_user
( void *to , const void __user *from,unsigned long n)
put_user(local,user)
get_user(local,user)

七、并发控制机制
并发:在操作系统中,一个时间段中有几个程序同时处于就绪状态,等待调度到CPU中运行,并发容易导致竞争问题
竞争:两个或两个以上的进程同时访问一个资源,从而引起资源被无控制的修改
并发控制的机制:
原子变量操作、自旋锁、信号量、完成量
原子操作:要么不执行,要么完全执行,缺点功能简单,智能做计数操作
自旋锁(spinlock):用来标记只能有一个线程访问该对象,在同一线程多次加锁操作会造成死锁同互斥锁不同的是在锁操作需要等待的时候并不是睡眠等待唤醒,而是循环检测保持者已经释放了锁,这样做的好处是节省了线程从睡眠状态到唤醒之间内核会产生的消耗。
互斥锁(mutexlock):通常情况下锁操作失败会将该线程睡眠等待锁释放时被唤醒标记用来保证在任一时刻,只能有一个线程访问该对象。 缺点:短时
信号量:
在这里插入图片描述
在这里插入图片描述

完成量:

在这里插入图片描述

自旋锁的效率远高于互斥锁。信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用,而自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用。

原子操作
在这里插入图片描述
在这里插入图片描述

原子操作需要硬件的支持,因此是架构相关的,其API和原子类型的定义都定义在内核源码树的include/sam/atomic.h文件中,它们都是使用汇编语言实现,因为c语言并不能实现这样的操作。

原子操作主要用来实现资源计数,很多引用计数就是通过原子操作实现的。
typedef struct {int counter;}atomic_t;

(1)atomic_read(atomic_t *v)
该函数对原子类型的变量进行原子读操作,它返回原子类型的变量v的值。
(2)atomic_set(atomic_t *v,int i);
该函数设置原子类型的变量v的值为i。
(3)atomic_add(int i, atomic_t *v);
该函数给原子类型变量v增加i。
(4)atomic_sub(int i, atomic_t *v);
该函数给原子类型变量v减去i。
(5)atomic_sub_and_test(int i, atomic_t *v);
该函数从原子类型的变量v中减去i,并判断结果是否是0,如果为0,返回真,否则返回假。
(6) atomic_inc(atomic_t *v);
该函数对原子变量v原子的增加1。
(7)atomic_dec(atomic_t *v);
该函数对原子变量v原子的减少1。
(8)atomic_dec_and_test(atomic_t *v);
该函数对原子类型的变量v原子的减少1,并判断结果是否是0,如果是0,返回真,否则返回假。
(9)atomic_inc_and_test(atomic_t *v);
该函数对原子类型的变量v原子增加1,并判断结果是否是0,如果是0,返回真,否则返回假。
(10)atomic_add_negative(int i, atomic_t *v);
该函数对原子类型的变量v原子的增加I,并判断结果是否是负数,如果是,返回真,否则返回假。
(11)atomic_add_return(int i, atomic_t *v);
该函数对原子类型的变量v原子的增加i,并且返回指向v的指针。
(12)atomic_sub_return(int i, atomic_t *v);
该函数对原子累心的变量v中减去i,并且返回指向v的指针。

https://blog.youkuaiyun.com/qq_34337272/article/details/81252853
https://wenwen.sogou.com/z/q829320294.htm
跟互斥锁一样,一个执行单元要想访问被自旋锁保护的共享资源,必须先得到锁,在访问完共享资源后,必须释放锁。如果在获取自旋锁时,没有任何执行单元保持该锁,那么将立即得到锁;如果在获取自旋锁时锁已经有保持者,那么获取锁操作将自旋在那里,直到该自旋锁的保持者释放了锁。
自旋锁
在这里插入图片描述
在这里插入图片描述

1)因此, 应用到自旋锁的核心规则是任何代码必须, 在持有自旋锁时, 是原子性的. 它不能睡眠; 事实上, 它不能因为任何原因放弃处理器, 除了服务中断(并且有时即便此时也不行)
2)避免这个陷阱需要在持有自旋锁时禁止中断( 只在本地 CPU ). 有各种自旋锁函数会为你禁止中断( 我们将在下一节见到它们 ). 但是, 一个完整的中断讨论必须等到第 10 章了.
3) 最后一个重要规则是自旋锁必须一直是尽可能短时间的持有. 你持有一个锁越长, 另一个进程可能不得不自旋等待你释放它的时间越长, 它不得不完全自旋的机会越大. 长时间持有锁也阻止了当前处理器调度, 意味着高优先级进程 – 真正应当能获得 CPU 的 –
自旋锁的其他变种
1.TicketLock
2.CLHLock
3. MCSLock
在这里插入图片描述

信号量
在这里插入图片描述

完成量
在这里插入图片描述

八、阻塞与同步
在这里插入图片描述
在这里插入图片描述

九、时钟机制
时间度量与时间延迟
在这里插入图片描述

Linux驱动延时
短时延迟:=忙等待
static inline void ndelay(unsigned long x) //纳秒延迟
static inline void udelay(unsigned long usecs) //微秒延迟
static inline void msleep(unsigned int msecs) //毫秒延迟
毫秒延迟==》将等待的进程睡眠(放入等待队列,当延时到达时,唤醒等待队列中的进程),而不是忙等待
void msleep(unsigned int msecs) //不能被打断
unsigned long msleep_interruptible(unsigned int msecs) 可以被中断打断(触发)
static inline void ssleep(unsigned int seconds) //不能被打断
长时延迟
unsigned long timeout = jiffies + 3*Hz
while(time_before(jiffies,timeout))

中断
同步中断:在指令执行过程中,即使有中断的到来,只要指令还没执行完,CPU就不会去执行中断。
异步中断:随时产生,产生中断时不考虑与处理器的时钟同步问题。
中断信号线= 中断输入线(接收中断信号引脚)+中断输出线(发送中断信号引脚)
中断组成:
ARM处理核心----中断控制器(中断优先级+中断屏蔽寄存器)-----多个中断源
(中断控制器通过优先级进行判断,通过引脚将中断请求发送到ARM处理器核心)
中断处理过程:
1)外设产生中断信号(电信号)->中断控制器
2)中断控制器不断检测中断信号
while(检测中断信号)
{
3) if(多个信号) 判断优先级,优先中断编号小的;
else
4)将中断号放进CPU的数据总线I/O端口中
}
5)中断控制器发送信号->CPU的INTR引脚
6)CPU在指令周期的适当时刻,会分析该信号,决定中断类型。根据中断号确定中断处理函数
7)When(中断是由外部设备引起),会发送一个应答信号给中断控制器的端口B,让端口B设置成一个中断挂起值表示中断正在执行该中断,不允许该中断再一次产生
申请中断线
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

按键驱动
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

十、内存分配
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Vmalloc malloc free kmalloc

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Vmalloc:分配虚拟地址连续,但物理地址不连续的内存。Vmalloc 分配的页在虚拟地址空间是连续的

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Slab:后备高速缓存

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

物理地址与虚拟地址转换
在这里插入图片描述

IO内存访问流程
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总线、设备、驱动
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值