嵌入式Linux异步通知方式

在线课堂:https://www.100ask.net/index(课程观看)
论  坛:http://bbs.100ask.net/(学术答疑)
开 发 板:https://100ask.taobao.com/ (淘宝)
     https://weidongshan.tmall.com/(天猫)
交流群一:QQ群:869222007(鸿蒙开发/Linux/嵌入式/驱动/资料下载)
交流群二:QQ群:536785813(单片机-嵌入式)
公 众 号:百问科技


版本 日期 作者 说明
V1 2020 韦东山 摘自《嵌入式Linux应用开发完全手册》
  1. 功能介绍
    所谓同步,就是“你慢我等你”。
    那么异步就是:你慢那你就自己玩,我做自己的事去了,有情况再通知我。
    所谓异步通知,就是 APP 可以忙自己的事,当驱动程序用数据时它会主动给 APP 发信号,这会导致 APP执行信号处理函数。
    仔细想想“发信号”,这只有 3 个字,却可以引发很多问题:
    ① 谁发:驱动程序发
    ② 发什么:信号
    ③ 发什么信号:SIGIO
    ④ 怎么发:内核里提供有函数
    ⑤ 发给谁:APP,APP 要把自己告诉驱动
    ⑥ APP 收到后做什么:执行信号处理函数
    ⑦ 信号处理函数和信号,之间怎么挂钩:APP 注册信号处理函数

小孩通知妈妈的事情有很多:饿了、渴了、想找人玩。
Linux 系统中也有很多信号,在 Linux 内核源文件 include\uapi\asm-generic\signal.h 中,有很多信号的宏定义:
在这里插入图片描述
驱动程序通知 APP 时,它会发出“SIGIO”这个信号,表示有“IO 事件”要处理。
就 APP 而言,你想处理 SIGIO 信息,那么需要提供信号处理函数,并且要跟 SIGIO 挂钩。这可以通过一个 signal 函数来“给某个信号注册处理函数”,用法如下:
在这里插入图片描述
除了注册 SIGIO 的处理函数,APP 还要做什么事?想想这几个问题:

① 内核里有那么多驱动,你想让哪一个驱动给你发 SIGIO 信号?
APP 要打开驱动程序的设备节点。

② 驱动程序怎么知道要发信号给你而不是别人?
APP 要把自己的进程 ID 告诉驱动程序。

③ APP 有时候想收到信号,有时候又不想收到信号:
应该可以把 APP 的意愿告诉驱动:设置 Flag 里面的 FASYNC 位为 1,使能“异步通知”。

  1. 应用编程
    应用程序要做的事情有这几件:

① 编写信号处理函数:

static void sig_func(int sig)
{
    
    
int val;
read(fd, &val, 4);
printf("get button : 0x%x\n", val);
}

② 注册信号处理函数:

signal(SIGIO, sig_func);

③ 打开驱动:

fd = open(argv[1], O_RDWR);

④ 把进程 ID 告诉驱动:

fcntl(fd, F_SETOWN, getpid());

⑤ 使能驱动的 FASYNC 功能:

flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags | FASYNC);

猜你喜欢

转载自blog.csdn.net/thisway_diy/article/details/109802159
今日推荐