嵌入式Linux驱动学习——同步互斥、阻塞

  学习原子操作和互斥信号量的使用、阻塞/非阻塞在驱动中的应用。

1 问题

  当多个应用程序同时对一个设备文件进行写操作时,可能出现问题。修改程序,使得只有一个应用程序使用驱动程序。

2 原子操作

2.1 原子操作函数

  保证了变量操作的原子性。

atomic_t v = ATOMIC_INIT(0);       
atomic_read(atomic_t *v);           
void atomic_inc(atomic_t *v);       
void atomic_dec(atomic_t *v);      
int atomic_dec_and_test(atomic_t *v); 

2.2 程序

  在按键驱动程序的基础上修改。
(1)定义原子变量

atomic_t canopen = ATOMIC_INIT(1); 

(2)在.open中判断

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

(3)在.release中复位

atomic_inc(&canopen);

3 互斥信号量

3.1 互斥信号量函数

  获取信号量,则进入临界区;失败,则休眠。

static DECLARE_MUTEX(button_lock);     
void down(struct semaphore * sem);           
int down_interruptible(struct semaphore * sem);  
int down_trylock(struct semaphore * sem);       
void up(struct semaphore * sem);           

3.2 程序

(1)定义锁

static DECLARE_MUTEX(button_lock);

(2).open添加

down(&button_lock);

(3).release添加

up(&button_lock);

4 阻塞和非阻塞

  阻塞:使用down()获取失败,则休眠。
  非阻塞:使用down_trylock()获取失败,不休眠,直接放弃。
  应用程序在打开设备时可选择使用阻塞方式还是非阻塞方式,例如

fd=open("/dev/buttons",O_RDWR);                                          //使用阻塞操作
fd = open("/dev/buttons ", O_RDWR | O_NONBLOCK);                         //使用非阻塞操作

  底层驱动通过file->f_flags查看应用层设置的参数。
  例如,在驱动中,根据应用层的设置,进行不同的处理。

if( file->f_flags & O_NONBLOCK )   //非阻塞操作
{
   if(down_trylock(&button_lock) )       //尝试获取信号量,获取不到则退出
		 return -1;
}
else   //阻塞操作
{
     down(&button_lock);         //获取信号量,获取不到则进入休眠
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值