linux驱动编写之进程独占驱动
一、描述
嵌入式开发系统中,有各种硬件资源,而有些硬件资源使用时候是需要进程独占的。也就是说,同一时刻只有一个进程允许使用这个硬件资源,其他的进程只能放弃执行或者挂起等待。在设计其对应驱动的时候,就需要做独占处理。
example:
led灯驱动,4盏LED灯,在open的时候调用驱动,对其引脚进行配置。如果没有进程独占驱动的处理机制,效果如下:


根据测试结果可以得到结论,调用了4次应用程序led_test,每一次调用open("/dev/leds", 0),都返回了一个/dev/leds的fd,fd是相同的,都是3。应用程序led_test的4次运行,都成功得到了执行,进程pid号分别为680、681、682、683。当调用open("/dev/leds", 0)时候,对应的就会调用驱动的leds_open函数,然后进行4次初始化。
所以要实现只有一个进程使用该leds驱动,就需要在驱动模块的leds_open函数动手脚,具体实现方法如下。
二、原子操作
1、定义一个全局原子变量
static atomic_t open_ability = ATOMIC_INIT();
2、修改drivers_open函数
static int drivers_open(struct inode *inode, struct file *file)
{
if (!atomic_dec_and_test(&open_ability))
{
atomic_inc(&open_ability);
return -EBUSY;
}
............
}
如果是第一次打开或者处于关闭之后未打开状态,那么可以打开,if判断为false,执行之后的open代码段;如果已经打开了,就不能打开,返回-EBUSY.
3、修改drivers_close函数
int drivers_close(struct inode *inode, struct file *file)
{
atomic_inc(&open_ability);
............
return ;
}
打开之后,关闭驱动文件,就需要释放open_ability.
4、实现思路总结
通过引入一个变量open_ability,为硬件驱动设计一个锁,只允许一个进程对其独占;当进程使用完驱动之后,就可以释放这个资源,以提供给其他应用程序来使用。
5、测试效果

可以看到第一次打开驱动成功,但是第二次打开驱动失败了。而且,这种方法实现的效果是,直接由驱动程序返回打开失败的消息-EBUSY.
三、信号量--互斥锁
1、定义一个互斥锁,并将互斥锁初始值设为1
static DECLARE_MUTEX(leds_lock); //利用宏来实现定义,并初始化
2、修改drivers_open函数
static int drivers_open(struct inode *inode, struct file *file)
{
/* 获取信号量,如果没有获得,那么就进入睡眠状态 */
down(&leds_lock);
............
}
3、修改drivers_close函数
int drivers_close(struct inode *inode, struct file *file)
{
............
up(&leds_lock);
return ;
}
4、实现思路总结
利用互斥锁,来实现对硬件驱动的独占,显然是很适合的,因为互斥锁设计的初衷就是来解决这类问题。
5、测试效果

可以看到第一次成功打开了驱动,第二次进入了不可中断的休眠状态。也就是说,当pid号645的应用程序led_test调用调用open("/dev/leds", 0)时候,驱动程序中的down(leds_lock)令进程进入了不可中断的休眠状态,直到第一次运行pid号644的应用程序led_test释放互斥锁,才能够重新得到运行。

备注:STAT一栏中的,S代表“休眠状态”;D代表“不可中断的休眠状态”。
6、与原子操作实现的区别
原子操作,当第二次打开驱动文件的时候,直接返回-EBUSY,也就是说是非阻塞的;而互斥锁的这种方法,当第二次打开驱动文件的时候,由驱动程序中的down()函数迫使进程进入不可中断的休眠状态,可以说是阻塞的。
不过,如果将down()函数换成down_trylock()函数,实现的效果也是非阻塞的。
参考资料:韦东山linux视频教程
linux驱动编写之进程独占驱动的更多相关文章
- Linux驱动编写(块设备驱动代码)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 按照ldd的说法,linux的设备驱动包括了char,block,net三种设备.char设备 ...
- linux驱动编写(电源管理驱动)
对于嵌入式设备来说,合适的电源管理,不仅可以延长电池的寿命,而且可以省电,延长设备运行时间,在提高用户体验方面有很大的好处.所以,各个soc厂家在这方面花了很多的功夫.下面,我们可以看看linux是如 ...
- v4l2驱动编写篇【转】
转自:http://blog.csdn.net/michaelcao1980/article/details/53008418 大部分所需的信息都在这里.作为一个驱动作者,当挖掘头文件的时候,你可能也 ...
- Linux驱动之按键驱动编写(中断方式)
在Linux驱动之按键驱动编写(查询方式)已经写了一个查询方式的按键驱动,但是查询方式太占用CPU,接下来利用中断方式编写一个驱动程序,使得CPU占有率降低,在按键空闲时调用read系统调用的进程可以 ...
- linux驱动学习笔记---实现中断下半部以及驱动编写规范(七)【转】
转自:https://blog.csdn.net/weixin_42471952/article/details/81609141 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协 ...
- Linux I2C设备驱动编写(一)
在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I2C driver 某个I2C设备的设备驱动,可以以driver理解. I2C client 某个I2C ...
- 【转】Linux I2C设备驱动编写(一)
原文网址:http://www.cnblogs.com/biglucky/p/4059576.html 在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I ...
- Linux驱动之按键驱动编写(查询方式)
在Linux驱动之LED驱动编写已经详细介绍了一个驱动的编写过程,接着来写一个按键驱动程序,主要是在file_operations结构中添加了一个read函数.还是分以下几步说明 1.查看原理图,确定 ...
- Linux驱动之LED驱动编写
从上到下,一个软件系统可以分为:应用程序.操作系统(内核).驱动程序.结构图如下:我们需要做的就是写出open.read.write等驱动层的函数.一个LED驱动的步骤如下: 1.查看原理图,确定需要 ...
随机推荐
- Echarts简单案例
官网: http://echarts.baidu.com/index.html 文档: http://echarts.baidu.com/echarts2/doc/doc.html <html ...
- gulp使用 笔记
全局安装gulp,也需要本地安装gulp插件.全局安装gulp是为了执行gulp任务,本地安装gulp则是为了调用gulp插件的功能 //导入工具包 require('node_modules里对应模 ...
- Linux环境下运行简单java程序
一.安装java 1.下载jdk8 登录网址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213315 ...
- Tsung 超详细的的tsung性能测试资料
超详细的的tsung性能测试资料 by:授客 QQ:1033553122 由于篇幅问题,采用链接分享的形式 下载连接:理解Tsung配置文件 下载连接:基准测试方法 下载连接:Tsung XML配置文 ...
- loadrunner 脚本开发-int型变量和字符串的相互转换
脚本开发-int型变量和字符串的相互转换 by:授客 QQ:1033553122 字符串转化为int型变量 Action2() { int j = 0; j = atoi("12345&qu ...
- Angular基础(二) 组件的使用
一.简单操作 a) 使用Angular CLI可以快速创建项目框架,先运行 $ npm install –g @angular/cli@1.0.0安装CLI,为CLI的位置设置环境变量,然后就可以 ...
- Python实现批量梯度下降算法
# -*- coding: UTF-8 -*- import numpy as npimport math # 定义基础变量learning_rate = 0.1n_iterations = 1000 ...
- forfiles命令详解
目录复制命令: xcopy //server/bak/*.* d:/serverbak /s /e /v /c / d /y /h at 05:30 shutdown ...
- 记录:一个SQL SERVER奇怪的问题。
今天遇到了一个奇怪的问题.始终没搞清楚是怎么回事.先记一下 1.首先有张表a,包含字段 编号.日期(varchar(250)),数值 发生日期字段有非正常日期字符串,有NULL,空字符串,可能是误触键 ...
- Alpha冲刺! Day1 - 磨刀
Alpha冲刺! Day1 - 磨刀 序章 Alpha冲刺开始的比印象中的计划早,翻回去看系统设计那篇作业博客的实践时间安排表格发现不!见!了!! 因为计划提前,但又必须在编码开始之前把所有逻辑讨论清 ...