Chinaunix首页 | 论坛 | 博客
  • 博客访问: 150944
  • 博文数量: 44
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 407
  • 用 户 组: 普通用户
  • 注册时间: 2015-11-10 13:28
个人简介

仰望星空

文章分类
文章存档

2016年(22)

2015年(22)

我的朋友

分类: 嵌入式

2015-12-09 15:49:03

一、原子操作
    加入原子操作的目的就是多个应用程序同时调用驱动程序, 原子操作的特性是在自增、自减等操作过程中不会被打断,防止两个应用程序同时调用驱动程序情况的发生,其使用过程如下:
static atomic_t canopen = ATOMIC_INIT(1);     //定义原子变量并初始化为1
然后在XXX_open( )函数中这样初始化。
static int sixth_drv_open(struct inode *inode, struct file *file)
{
    if (!atomic_dec_and_test(&canopen))
    {
        atomic_inc(&canopen);
        return -EBUSY;
    }
............
}
当原子量自减一次后,检测其为0时返回ture,此时不会进入if中。当不为0时会进入if中,返回-EBUSY,表示资源不可用。

二、信号量
     
这个比原子操作更加简单了,信号量(semaphore)是用于保护临界区的一种常用方法,只有得到信号量的进程才能执行临界区代码。
当获取不到信号量时,进程进入休眠等待状态。
首先要定义一个互斥锁 static DECLARE_MUTEX(button_lock);     //定义互斥锁
然后在xxx_open( )中获取信号量   down(&button_lock); 第一次调用xxx_open()时,会获得这个信号量,第二次调用时,就不会获得信号量了,会一直陷入休眠的状态。
在xxx_close( )中释放信号量  up(&button_lock);

三、阻塞
    是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。
被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。直接分析代码:
这是xxx_open( )函数中的代码:

点击(此处)折叠或打开

  1. if (file->f_flags & O_NONBLOCK)
  2.     {
  3.         if (down_trylock(&button_lock))
  4.             return -EBUSY;
  5.     }
  6.     else
  7.     {
  8.         /* 获取信号量 */
  9.         down(&button_lock);
  10.     }
其中O_NONBLOCK 是非阻塞的一个标志,也就是当文件以非阻塞方式打开时,如果阻塞,直接返回-1;
    但是当以阻塞方式打开时,会获取信号量;
以下时xxx_read( )中的代码:

点击(此处)折叠或打开

  1. if (file->f_flags & O_NONBLOCK)
  2.     {
  3.         if (!ev_press)
  4.             return -EAGAIN;
  5.     }
  6.     else
  7.     {
  8.         /* 如果没有按键动作, 休眠 */
  9.         wait_event_interruptible(button_waitq, ev_press);
  10.     }
当非阻塞方式打开时,如果没有中断发生,则直接返回-1;
当以阻塞方式打开时,如果有没有按键动作,就休眠了;



阅读(2801) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~