9.中断编程3——按键驱动之阻塞和非阻塞实验

阻塞的概念和接口使用

在这里插入图片描述
文件io模型:
1,非阻塞
2,阻塞
3,多路复用–select/poll
4, 异步信号通知faync

阻塞: 当进程在读取外部设备的资源(数据),资源没有准备好,进程就会休眠
	linux应用中,大部分的函数接口都是阻塞
		scanf();
		read();
		write();
		accept();
驱动中需要调用
	1,将当前进程加入到等待队列头中
		add_wait_queue(wait_queue_head_t * q, wait_queue_t * wait)
	2,将当前进程状态设置成TASK_INTERRUPTIBLE
		set_current_state(TASK_INTERRUPTIBLE)
	3,让出调度--休眠
		schedule(void)

更加智能的接口,等同于上面的三个接口:
	wait_event_interruptible(wq, condition)

驱动如何去写代码
	1,等待队列头
			wait_queue_head_t

			init_waitqueue_head(wait_queue_head_t *q);
	
	2,在需要等待(没有数据)的时候,进行休眠
		wait_event_interruptible(wait_queue_head_t wq, condition) // 内部会构建一个等待队列项/节点wait_queue_t
		参数1: 等待队列头
		参数2: 条件,如果是为假,就会等待,如果为真,就不会等待
				可以用一标志位,来表示是否有数据


	3,在一个合适的时候(有数据),会将进程唤醒
		wake_up_interruptible(wait_queue_head_t *q)

		用法:
			wake_up_interruptible(&key_dev->wq_head);
			//同时设置标志位
			key_dev->key_state  = 1;

阻塞的实现——等待队列的使用

1.定义等待队列头并初始化
在这里插入图片描述
(init函数中)
在这里插入图片描述

2.在需要等待(没有数据)的时候,进行休眠
在这里插入图片描述
由于在init函数中调用了kzalloc,因此key_state=0
在这里插入图片描述
3.有数据需要去唤醒整个进程/等待队列
(key_irq_handler中断函数中)
在这里插入图片描述

非阻塞模式的实现

在这里插入图片描述

非阻塞: 在读写的时候,如果没有数据,立刻返回,并且返回一个出错码
用的会比较少,因为比较耗资源
open("/dev/key0", O_RDWR|O_NONBLOCK);
------------------------------------
驱动中需要去区分,当前模式是阻塞还是非阻塞
//如果当前是非阻塞模式,并且没有数据,立马返回一个出错码
if(filp->f_flags & O_NONBLOCK && !key_dev->key_state)
return -EAGAIN;
在这里插入图片描述

完整代码

key_driver.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/wait.h>
#include <linux/sched.h>

#define GPXCON_REG  0x11000C20
#define KEY_ENTER 28

//6.2.设计一个描述按键的数据的对象
struct key_event
{
   
	int code;//表示按键的类型
	int value;//表示按下还是抬起
};

//1.设定一个全局的设备对象
struct key_desc
{
   
	unsigned int dev_major;
	struct class *cls;
	struct device *dev;
	int irqno;
	void *reg_base;
	//按键
	struct key_event event;

	//7.1.定义等待队列头
	wait_queue_head_t wq_head;
	//7.3.表示是否有数据
	int key_state;
};
struct key_desc *key_dev;

int get_irqno_from_node
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值