当前位置:首页 > > IOT物联网小镇
[导读]作 者:道哥,10年嵌入式开发老兵,专注于:C/C、嵌入式、Linux。关注下方公众号,回复【书籍】,获取Linux、嵌入式领域经典书籍;回复【PDF】,获取所有原创文章(PDF格式)。目录kill命令和信号使用kill命令发送信号多线程中的信号信号注册和处理函数驱动程序代码示例...

作  者:道哥,10 年嵌入式开发老兵,专注于:C/C 、嵌入式、Linux

关注下方公众号,回复【书籍】,获取 Linux、嵌入式领域经典书籍;回复【PDF】,获取所有原创文章( PDF 格式)。

目录

  • kill 命令和信号

    • 使用 kill 命令发送信号

    • 多线程中的信号

    • 信号注册和处理函数

  • 驱动程序代码示例:发送信号

    • 功能需求

    • 驱动程序代码

    • 驱动模块 Makefile

    • 编译和加载

  • 应用程序代码示例:接收信号

    • 注册信号处理函数

    • 测试验证

别人的经验,我们的阶梯!

大家好,我是道哥,今天我为大伙儿解说的技术知识点是:【驱动层中,如何发送信号给应用程序】

在上一篇文章中,我们讨论的是:在应用层如何发送指令来控制驱动层的 GPIOLinux驱动实践:如何编写【 GPIO 】设备的驱动程序?。控制的方向是从应用层到驱动层

那么,如果想让程序的执行路径从下往上,也就是从驱动层传递到应用层,应该如何实现呢?

最容易、最简单的方式,就是通过发送信号

这篇文章继续以完整的代码实例来演示如何实现这个功能。

kill 命令和信号

使用 kill 命令发送信号

关于 Linux 操作系统的信号,每位程序员都知道这个指令:使用 kill 工具来“杀死”一个进程:

$ kill -9 <进程的 PID>
这个指令的功能是:向指定的某个进程发送一个信号 9,这个信号的默认功能是:是停止进程。

虽然在应用程序中没有主动处理这个信号,但是操作系统默认的处理动作是终止应用程序的执行。

除了发送信号 9kill 命令还可以发送其他的任意信号。

Linux 系统中,所有的信号都使用一个整型数值来表示,可以打开文件 /usr/include/x86_64-linux-gnu/bits/signum.h(你的系统中可能位于其它的目录) 查看一下,比较常见的几个信号是:

/* Signals. */
#define SIGINT 2 /* Interrupt (ANSI). */
#define SIGKILL 9 /* Kill, unblockable (POSIX). */
#define SIGUSR1 10 /* User-defined signal 1 (POSIX). */
#define SIGSEGV 11 /* Segmentation violation (ANSI). */
#define SIGUSR2 12 /* User-defined signal 2 (POSIX). */
...
...
#define SIGSYS 31 /* Bad system call. */
#define SIGUNUSED 31

#define _NSIG 65 /* Biggest signal number 1
(including real-time signals). */

/* These are the hard limits of the kernel. These values should not be
used directly at user level. */
#define __SIGRTMIN 32
#define __SIGRTMAX (_NSIG - 1)
信号 9 对应着 SIGKILL,而信号11SIGSEGV)就是最令人讨厌的Segmentfault

这里还有一个地方需要注意一下:实时信号和非实时信号,它俩的主要区别是:

  1. 非实时信号:操作系统不确保应用程序一定能接收到(即:信号可能会丢失);

  2. 实时信号:操作系统确保应用程序一定能接收到;

如果我们的程序设计,通过信号机制来完成一些功能,那么为了确保信号不会丢失,肯定是使用实时信号的。

从文件 signum.h 中可以看到,实时信号从 __SIGRTMIN(数值:32) 开始。

多线程中的信号

我们在编写应用程序时,虽然没有接收并处理 SIGKILL 这个信号,但是一旦别人发送了这个信号,我们的程序就被操作系统停止掉了,这是默认的动作。

那么,在应用程序中,应该可以主动声明接收并处理指定的信号,下面就来写一个最简单的实例。

在一个应用程序中,可能存在多个线程;

当有一个信号发送给此进程时,所有的线程都可能接收到,但是只能有一个线程来处理;

在这个示例中,只有一个主线程来接收并处理信号;

信号注册和处理函数

按照惯例,所有应用程序文件都创建在 ~/tmp/App 目录中。

// 文件:tmp/App/app_handle_signal/app_handle_signal.c

#include
#include
#include
#include
#include

// 信号处理函数
static void signal_handler(int signum, siginfo_t *info, void *context)
{
// 打印接收到的信号值
printf("signal_handler: signum = %d \n", signum);
}

int main(void)
{
int count = 0;
// 注册信号处理函数
struct sigaction sa;
sigemptyset(
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭