i.MX6ULL终结者Linux阻塞和非阻塞IO实验阻塞IO实验

我们在按键中断实验的基础上来完成阻塞IO的实验,在上一章的按键中断实验中,我们通过read函数while循环的方式读取按键状态,这种方法缺点很明显,会导致有很高的CPU占用率。我们来看一下通过while循环的方式CPU的使用率,使用上一章的key_irq.ko模块和key_irq_test应用程序,先加载驱动模块,然后执行应用程序:

modprobe  key_irq
./key_irq_test  /dev/imx6uirq &

使用“top”命令查看key_irq_test程序的CPU使用率,如图 1所示:
在这里插入图片描述

图 1

可以看到key_irq_test程序的CPU使用率为97.2%,仅仅是一个按键程序就会导致这么高的CPU使用率效率是非常低的。所以一般是不会采用这种方法的,只是在实验中使用一下,在本节中我们就是用阻塞IO来实现一下。

1 驱动程序编写

本实验例程路径:i.MX6UL终结者光盘资料/06_Linux驱动例程/11_key_waitqueue
创建key_waitqueue.c文件,在key_irq.c文件的基础上进行修改,添加阻塞相关的代码。具体内容如下:

 1 #include <linux/types.h>
  2 #include <linux/kernel.h>
  3 #include <linux/delay.h>
  4 #include <linux/ide.h>
  5 #include <linux/init.h>
  6 #include <linux/module.h>
  7 #include <linux/errno.h>
  8 #include <linux/gpio.h>
  9 #include <linux/cdev.h>
 10 #include <linux/device.h>
 11 #include <linux/of.h>
 12 #include <linux/of_address.h>
 13 #include <linux/of_gpio.h>
 14 #include <linux/semaphore.h>
 15 #include <linux/timer.h>
 16 #include <linux/of_irq.h>
 17 #include <linux/irq.h>
 18 #include <asm/mach/map.h>
 19 #include <asm/uaccess.h>
 20 #include <asm/io.h>
 21 
 22 #define IMX6UIRQ_CNT 1 /* 设备号个数 */
 23 #define IMX6UIRQ_NAME "blockio" /* 名字 */
 24 #define KEY0VALUE 0X01 /* KEY0 按键值 */
 25 #define INVAKEY 0XFF /* 无效的按键值 */
 26 #define KEY_NUM 1 /* 按键数量 */
 27 
 28 /* 中断 IO 描述结构体 */
 29 struct irq_keydesc {
   
 30         int gpio; /* gpio */
 31         int irqnum; /* 中断号 */
 32         unsigned char value; /* 按键对应的键值 */
 33         char name[10]; /* 名字 */
 34         irqreturn_t (*handler)(int, void *); /* 中断服务函数 */
 35 };
 36 
 37 /* imx6uirq 设备结构体 */
 38 struct imx6uirq_dev{
   
 39         dev_t devid; /* 设备号 */
 40         struct cdev cdev; /* cdev */
 41         struct class *class; /* 类 */
 42         struct device *device; /* 设备 */
 43         int major; /* 主设备号 */
 44         int minor; /* 次设备号 */
 45         struct device_node *nd; /* 设备节点 */
 46         atomic_t keyvalue; /* 有效的按键键值 */
 47         atomic_t releasekey; /* 标记是否完成一次完成的按键 */
 48         struct timer_list timer; /* 定义一个定时器*/
 49         struct irq_keydesc irqkeydesc[KEY_NUM]; /* 按键 init 述数组 */
 50         unsigned char curkeynum; /* 当前 init 按键号 */
 51 
 52         wait_queue_head_t r_wait; /* 读等待队列头 */
 53 };
 54 
 55 struct imx6uirq_dev imx6uirq; /* irq 设备 */
 56 
 57 /* @description : 中断服务函数,开启定时器 
 58  * 定时器用于按键消抖。
 59  * @param - irq : 中断号
 60  * @param - dev_id : 设备结构。
 61  * @return : 中断执行结果
 62  */
 63 static irqreturn_t key0_handler(int irq, void *dev_id)
 64 {
   
 65         struct imx6uirq_dev *dev = (struct imx6uirq_dev*)dev_id;
 66 
 67         dev->curkeynum = 0;
 68         dev->timer.data = (volatile long)dev_id;
 69         mod_timer(&dev->timer, jiffies + msecs_to_jiffies(10));
 70
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值