Chinaunix首页 | 论坛 | 博客
  • 博客访问: 208502
  • 博文数量: 32
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 850
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-22 15:50
文章存档

2014年(16)

2013年(16)

分类: 嵌入式

2014-01-09 11:15:46

            Linux设备驱动程序
                        ——高级字符驱动程序操作(按键的阻塞和非阻塞测试)
    该测试修改自韦东山视频教程第一期最后一课,阻塞非阻塞。作为高级字符驱动程序操作的最后总结~。
阻塞操作    
    是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。
非阻塞操作  
    进程在不能进行设备操作时并不挂起,它或者放弃,或者不停地查询,直至可以进行操作为止。
    fd = open("...", O_RDWR | O_NONBLOCK);    //阻塞方式打开设备文件方法。 
驱动中添加如下部分实现阻塞和非阻塞的操作:

点击(此处)折叠或打开

  1. static int buttons_int_block_noblock_drv_open(struct inode *inode, struct file *file)
  2. {
  3.     int ret;
  4.     if(file->f_flags & O_NONBLOCK)
  5.     {
  6.         if(down_trylock(&button_lock))
  7.             return -EBUSY;
  8.     }
  9.     else
  10.     {
  11.     /*open方法中获取信号量,第一次执行可以获取信号量,第二个进程在第一个进程没有释放信号量是无法open*/
  12.         down_interruptible(&button_lock);
  13.     }
  14.     ret = request_irq(IRQ_EINT8, buttons_irq,IRQT_BOTHEDGE,"KEY1",&pins_desc[0]);    //pins_desc[0]传递给buttons_irq
  15.     ret = request_irq(IRQ_EINT11,buttons_irq,IRQT_BOTHEDGE,"KEY2",&pins_desc[1]);
  16.     ret = request_irq(IRQ_EINT13,buttons_irq,IRQT_BOTHEDGE,"KEY3",&pins_desc[2]);
  17.     ret = request_irq(IRQ_EINT14,buttons_irq,IRQT_BOTHEDGE,"KEY4",&pins_desc[3]);
  18.     ret = request_irq(IRQ_EINT15,buttons_irq,IRQT_BOTHEDGE,"KEY5",&pins_desc[4]);
  19.     ret = request_irq(IRQ_EINT19,buttons_irq,IRQT_BOTHEDGE,"KEY6",&pins_desc[5]);
  20.     return 0;
  21. }

  22. ssize_t buttons_int_block_noblock_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
  23. {        
  24.     int ret;
  25.     if(size != 1)            //读取单个按键
  26.         return -EINVAL;
  27.     if(file->f_flags & O_NONBLOCK)
  28.     {
  29.         if(!ev_press)
  30.             return -EAGAIN;
  31.     }
  32.     else
  33.     {
  34.         wait_event_interruptible(button_waitq, ev_press);    //如果没有按键动作,休眠,让出CPU
  35.     }
  36.     
  37.     ret = copy_to_user(buf, &key_val, 1);                    //返回键值
  38.     ev_press = 0;
  39.     return 1;        
  40. }
测试程序:

点击(此处)折叠或打开

  1. #include <fcntl.h>
  2. #include <stdio.h>

  3. int main(int argc,char **argv)
  4. {
  5.     int fd,ret;
  6.     unsigned char key_val;
  7.     int cnt = 0;
  8.     
  9.     //fd = open("/dev/mini2440_buttons", O_RDWR);    
  10.     fd = open("/dev/mini2440_buttons", O_RDWR | O_NONBLOCK);    
  11.     if(fd < 0)
  12.     {
  13.         printf("can't open\n");
  14.     }
  15.     
  16.     while(1)
  17.     {
  18.         ret = read(fd,&key_val,1);
  19.         printf("key_val = 0x%x,ret = %d\n",key_val,ret);
  20.         sleep(5);
  21.     }
  22.     return 0;
  23. }
完整代码:buttons_int_block_noblock_drv.rar
阅读(2715) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~