06.休眠与唤醒
实验说明¶
该部分内容基于中断实验修改,只会有少部分不同,其实休眠感觉就是一种阻塞IO的用法。
修改细节¶
首先注册一个唤醒等待队列
在read函数中,调用read的时候就等待唤醒,当g_key为真的时候才会执行read相关任务
/* 实现对应的open/read/write等函数,填入file_operations结构体 */
static ssize_t gpio_key_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
int err;
wait_event_interruptible(gpio_key_wait, g_key);
err = copy_to_user(buf, &g_key, 4);
g_key = 0;
return 4;
}
在中断服务函数中,触发中断,就执行唤醒API,这样,就实现了休眠和唤醒
static irqreturn_t gpio_key_isr(int irq, void *dev_id)
{
struct key_dev *gpio_key = dev_id;
int val;
val = gpiod_get_value(gpio_key->gpiod);
printk("key %d %d\n", gpio_key->gpio, val);
g_key = (gpio_key->gpio << 8) | val;
wake_up_interruptible(&gpio_key_wait);
return IRQ_HANDLED;
}
实验测试文件如下
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
/*
* ./button_test /dev/100ask_button0
*
*/
int main(int argc, char **argv)
{
int fd;
int val;
/* 1. 判断参数 */
if (argc != 2)
{
printf("Usage: %s <dev>\n", argv[0]);
return -1;
}
/* 2. 打开文件 */
fd = open(argv[1], O_RDWR);
if (fd == -1)
{
printf("can not open file %s\n", argv[1]);
return -1;
}
while (1)
{
/* 3. 读文件 */
read(fd, &val, 4);
printf("get button : 0x%x\n", val);
}
close(fd);
return 0;
}