个人名片:
专栏导航:
文章介绍:
目录:
一、APP 怎么读取按键值
在做单片机开发时,要读取 GPIO 按键,我们通常是执行一个循环,不断地检测 GPIO 引脚电平有没有发生变化。但是在 Linux 系统中,读取 GPIO 按键要考虑到效率,引入了很多种方法:查询方式(非阻塞)、休眠-唤醒(阻塞方式)、 poll 方式、异步通知方式。这 4 种方法并不仅仅用于 GPIO 按键,在所有的 APP 调用驱动程序过程中,都是使用这些方法。通过这 4 种方式的学习,我们可以掌握如下知识:
1.1 驱动的基本技能:
中断、休眠、唤醒、poll 等机制。
这些基本技能是驱动开发的基础,其他大型驱动复杂的地方是它的框架及设计思想,但是基本技术就这些。
1.2 APP 开发的基本技能:
阻塞 、非阻塞、休眠、poll、异步通知。
二、妈妈怎么知道孩子醒了
妈妈怎么知道卧室里小孩醒了?
2.1 时不时进房间看一下:查询方式
简单,但是累
2.2 进去房间陪小孩一起睡觉,小孩醒了会吵醒她:休眠-唤醒
不累,但是妈妈干不了活了
2.3 妈妈要干很多活,但是可以陪小孩睡一会,定个闹钟:poll 方式
要浪费点时间,但是可以继续干活。
妈妈要么是被小孩吵醒,要么是被闹钟吵醒。
2.4 妈妈在客厅干活,小孩醒了他会自己走出房门告诉妈妈:异步通知
妈妈、小孩互不耽误
这 4 种方法没有优劣之分,在不同的场合使用不同的方法。
三、APP 读取按键的 4 种方法
APP 去读取按键和举例的场景很相似,也有 4 种方法:
查询方式 休眠-唤醒方式 poll 方式 异步通知方式
第 2、3、4 种方法,都涉及中断服务程序。中断,就像小孩醒了会哭闹一样, 中断不经意间到来,它会做某些事情:唤醒 APP、向 APP 发信号。
所以,在按键驱动程序中,中断是核心。
实际上,中断无论是在单片机还是在 Linux 中都很重要。在 Linux 中,中断的知识还涉及进程、线程等。
写一个驱动程序的套路
写一个驱动程序的套路
3.1 查询方式
这种方法最简单:和之前的LED驱动程序类似,之前是写引脚来改变高低电平,现在我们是不断读取引脚来查询是否发生电平的变化
驱动程序中构造、注册一个 file_operations 结构体,里面提供有对应的 open,read 函数。
3.2 休眠-唤醒方式
驱动程序中构造、注册一个 file_operations 结构体,里面提供有对应的 open,read 函数。
3.3 poll 方式
上面的休眠-唤醒方式有个缺点:如果用户一直没操作按键,那么 APP 就会永远休眠。 我们可以给 APP 定个闹钟,这就是 poll 方式。
驱动程序中构造、注册一个 file_operations 结构体,里面提供有对应的 open,read,poll 函数。
3.4 异步通知方式
3.4.1 异步通知的原理:发信号
异步通知的实现原理是:内核给 APP 发信号。信号有很多种,这里发的是 SIGIO。
驱动程序给应用程序发信号,应用程序收到信号后执行它的信号处理函数
驱动程序中构造、注册一个file_operations 结构体,里面提供有对应的 open,read,fasync函数。
3.4.2 应用程序之间发信号示例代码
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void my_sig_func(int signo)
{
printf("get a signal : %d\n", signo);
}
int main(int argc, char **argv)
{
int i = 0;
signal(SIGIO, my_sig_func); //事件处理函数,如果这里没有事件处理函数,则收到应用程序的信号就会停下退出,如果有事件处理函数,则收到应用程序后先执行事件处理函数再继续执行不会停止进程
while (1)
{
printf("Hello, world %d!\n", i++);
sleep(2);
}
return 0;
}
book@100ask:~/05_嵌入式Linux驱动开发基础知识/source/03_signal_example$ gcc -o signal signal.c
book@100ask:~/05_嵌入式Linux驱动开发基础知识/source/03_signal_example$ ./signal
重新开一个进程查询ID
book@100ask:~$ ps -A
book@100ask:~$ kill -SIGIO 4491
这样另一边的进程就收到信息了
四、驱动程序提供能力,不提供策略
我们的驱动程序可以实现上述 4 种提供按键的方法,但是驱动程序不应该限制 APP 使用哪种方法。
这就是驱动设计的一个原理:提供能力,不提供策略。就是说,你想用哪种方法都行,驱动程序都可以提供;但是驱动程序不能限制你使用哪种方法 。