——高级字符驱动程序操作(按键的阻塞和非阻塞测试)
该测试修改自韦东山视频教程第一期最后一课,阻塞非阻塞。作为高级字符驱动程序操作的最后总结~。
阻塞操作
是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。
非阻塞操作
进程在不能进行设备操作时并不挂起,它或者放弃,或者不停地查询,直至可以进行操作为止。
fd = open("...", O_RDWR | O_NONBLOCK); //阻塞方式打开设备文件方法。
驱动中添加如下部分实现阻塞和非阻塞的操作:
点击(此处)折叠或打开
-
static int buttons_int_block_noblock_drv_open(struct inode *inode, struct file *file)
-
{
-
int ret;
-
if(file->f_flags & O_NONBLOCK)
-
{
-
if(down_trylock(&button_lock))
-
return -EBUSY;
-
}
-
else
-
{
-
/*open方法中获取信号量,第一次执行可以获取信号量,第二个进程在第一个进程没有释放信号量是无法open*/
-
down_interruptible(&button_lock);
-
}
-
ret = request_irq(IRQ_EINT8, buttons_irq,IRQT_BOTHEDGE,"KEY1",&pins_desc[0]); //pins_desc[0]传递给buttons_irq
-
ret = request_irq(IRQ_EINT11,buttons_irq,IRQT_BOTHEDGE,"KEY2",&pins_desc[1]);
-
ret = request_irq(IRQ_EINT13,buttons_irq,IRQT_BOTHEDGE,"KEY3",&pins_desc[2]);
-
ret = request_irq(IRQ_EINT14,buttons_irq,IRQT_BOTHEDGE,"KEY4",&pins_desc[3]);
-
ret = request_irq(IRQ_EINT15,buttons_irq,IRQT_BOTHEDGE,"KEY5",&pins_desc[4]);
-
ret = request_irq(IRQ_EINT19,buttons_irq,IRQT_BOTHEDGE,"KEY6",&pins_desc[5]);
-
return 0;
-
}
-
-
ssize_t buttons_int_block_noblock_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
-
{
-
int ret;
-
if(size != 1) //读取单个按键
-
return -EINVAL;
-
if(file->f_flags & O_NONBLOCK)
-
{
-
if(!ev_press)
-
return -EAGAIN;
-
}
-
else
-
{
-
wait_event_interruptible(button_waitq, ev_press); //如果没有按键动作,休眠,让出CPU
-
}
-
-
ret = copy_to_user(buf, &key_val, 1); //返回键值
-
ev_press = 0;
-
return 1;
- }
点击(此处)折叠或打开
-
#include <fcntl.h>
-
#include <stdio.h>
-
-
int main(int argc,char **argv)
-
{
-
int fd,ret;
-
unsigned char key_val;
-
int cnt = 0;
-
-
//fd = open("/dev/mini2440_buttons", O_RDWR);
-
fd = open("/dev/mini2440_buttons", O_RDWR | O_NONBLOCK);
-
if(fd < 0)
-
{
-
printf("can't open\n");
-
}
-
-
while(1)
-
{
-
ret = read(fd,&key_val,1);
-
printf("key_val = 0x%x,ret = %d\n",key_val,ret);
-
sleep(5);
-
}
-
return 0;
- }