驱动程序的高级机制使用初步

来源:互联网 发布:大数据采集平台 编辑:程序博客网 时间:2024/05/17 22:30

一、异步通知

1、目的:为了使驱动控制通知应用程序执行操作,同进程之间发信号signal

2、方法: 应用程序: fcntl(fd , F_SETOWN , pid)  指定一个进程作为文件的“属主(filp->owner)”,这样内核才知道信号要发给哪个进程

oflags = fcntl(fd , F_GETFL)

fcntl(fd, F_SETFL, Oflags | FASYNC);在设备文件中添加FASYNC标志,驱动中就会调用将要实现的test_fasync函数

驱动程序:test_fasync 函数调用fasync_helper(fd , filp , on , &button_async)初始化button_async结构

在设备资源可获得后,调用kill_fasync()函数激发相应的信号》》应用程序中的signal将会被激发


二、同步

1、目的:同一时刻只能有一个应用程序打开设备,即驱动程序

2、方法一分析:

if (--canopen != 0){    canopen++;    return -EBUSY;}正常执行
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">//</span><span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">用一个变量canopen = 1,当一个进程执行驱动open函数时,if(--canopen != 0)为假,则正常执行,当另一个进程也驱动open函数时,此时canopen为0</span><span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">,则不能继续往下执行</span>

但是--canopen并不是原子操作,执行这条语句会有很多步骤,也就会被另一个程序打断,从而要求使用原子操作

3、方法二分析:atomic_t v = ATOMIC_INT(0)   //定义原子变量v并初始化为0

atomic_read (atomic_t *v) ;    //返回原子变量的值

void atomic_inc (atomic_t *v) ;    //原子变量增加1

void atomic_dec (atomic_t *v) ;    //原子变量减少1

int atomic_dec_and_test(atomic_t *v) /  /自减操作后测试其是否为0,为0则返回true,否则返回false

if (!atomic_dec_and_test(&canopen)){atomic_inc(&canopen);return -EBUSY;}

三、互斥

1、信号量是用于保护临界区的一种常用方法,只有得到信号量的进程才能执行临界区代码。当获取不到时进入休眠等待状态。

2、用一个宏定义互斥锁:static DECLARE_MUTEX(button_lock); 

3、获取信号量:down(&button_lock)获取信号量     ;//第二次执行到这会休眠

4、释放信号量:up(&button_lock)

四、阻塞

1、阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。

被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。

2、非阻塞操作是指进程在不能进行设备操作时并不挂起,它或者被放弃,或者被不停的查询,直至可以进行操作为止。

3、fd = open("...." , O_RDWR | O_NONBLOCK) 表示为非阻塞操作,默认情况为阻塞

4、驱动open函数使用阻塞与非阻塞

5、驱动read函数使用阻塞与非阻塞


谢谢韦老师的视频讲解



0 0
原创粉丝点击