5.王道_信号

4.1 信号的概念

在这里插入图片描述

4.2 信号的产生

在这里插入图片描述

4.3 信号的处理

在这里插入图片描述

4.4 Linux中所有信号

  • Ctrl+Z SIGINT
  • Ctrl+/ SIGQUIT
    在这里插入图片描述

4.5 信号的实现机制

在这里插入图片描述

在这里插入图片描述

  • 连发两个信号不会马上递送,等第一个信号处理完成之后再处理第二个。

4.6 函数signal 注册信号

在这里插入图片描述

4.6.1 信号递送的流程

在这里插入图片描述

4.7 注册多个信号

在这里插入图片描述

4.8 内核不可中断状态

处于内核不可中断状态(进程控制块的state成员此时为TASK_UNINTERRUPTIBLE)的进程无法接受并处理信号。处于这种的状态的进程在 ps 中显示为D,通常这种状态出现在进程必须不受干扰地等待或者等待事件很快会发生的 时候出现,比如进程正在等待磁盘读写数据的时候。对于非嵌入式程序员而言,这种状态是几乎没办法实现。内核不可中断状态是进程等待态的一种形式。

4.9 多个信号处理同时执行

在这里插入图片描述

4.10 重新注册信号处理流程

在这里插入图片描述

signal特点

在这里插入图片描述
在这里插入图片描述

  • mask刚开始为空,当递送信号的过程中会触发一个临时屏蔽,mask会包含这个触犯的信号,当从递送返回的时候mask会删除这个信号。屏蔽的过程中如果产生信号会放入pending中.pending只放一个信号。
    在这里插入图片描述

  • 只发一个信号
    在这里插入图片描述

  • 连着发送两个信号
    在这里插入图片描述

  • 注册两种信号
    在这里插入图片描述

三个信号
在这里插入图片描述

在这里插入图片描述

  • 三个信号
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.11 函数sigaction注册信号(了解)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • sigaction和signal其他的都一样,只不过他不会重启低速系统调用

sa_flags的取值集合

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

sa_mask设置阻塞集合

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.12 系统调用sigpending

在这里插入图片描述

4.13 sigprocmask 实现全程阻塞

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.14 kill 系统调用

在这里插入图片描述

4.15 pause 和sigsuspend

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.16 sleep 和系统时间

sleep 的一种实现方法

在这里插入图片描述在这里插入图片描述

当然,POSIX标准并没有规定 sleep 采用哪种具体实现,尽管目前Linux普遍采用 nanosleep 实现
sleep ,但是为了兼容性,使用 sleep 的时候不用混用 alarm

4.17 时钟处理

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

小项目 四窗口聊天

#include "stm32f10x.h" // 包含STM32标准外设库(寄存器定义与驱动API) #include <stdint.h> // 标准整数类型支持 #include <stdio.h> // 用于调试打印输出 #include "Delay.h" // ============================= // 硬件连接定义(根据实际电路修改) // ============================= #define TRIG_PIN GPIO_Pin_8 // 连接超声模块Trig脚的IO口(PA8) #define ECHO_PIN GPIO_Pin_9 // 连接超声模块Echo脚的IO口(PA9) #define USART_TX USART1 // 串口发送通道选择 #define BAUD_RATE 9600 // 波特率设置 volatile uint32_t captureTimeStamp = 0; // 存储捕获到上升沿的时间戳(全局变量) volatile float distanceCm = 0.0f; // 最终计算出的距离值(厘米单位) void SystemClockConfig(void); // 系统时钟初始化函数声明 void UsartInit(void); // 串口通信初始化函数声明 void TimCaptureInit(void); // 定时器输入捕获模式配置函数声明 static void InterruptHandler(void); // 中断服务例程原型定义 int main(void) { // -------------------------------------- // 第一步:基础环境搭建 // -------------------------------------- SystemClockConfig(); // ① 配置HSE为系统主频源并分配各外设时基 UsartInit(); // ② 初始化串口参数(波特率/数据位等) TimCaptureInit(); // ③ 设置定时器的输入捕获模式及预处理功能 // -------------------------------------- // 第二步:主循环逻辑处理 // -------------------------------------- while (1) { if (distanceCm > 0) { // 确保有效测量结果可用时才进行后续操作 printf("Distance: %.2f cm\r", distanceCm); // 通过串口发送格式化的距离信息 Delay_ms(500); // 等待半秒避免频繁刷新屏幕影响观察效果 } } } // ============================================ // 系统时钟树形结构配置(72MHz主频典型设置) // ============================================ void SystemClockConfig(void) { RCC->CR |= (1 << 0); // 启用HSE晶体振荡器开始工作 while (!(RCC->CR & (1 << 16))) {} // 轮询等待直到稳定就绪标志位置位成功 FLASH->ACR |= FLASH_ACR_PRFTBE; // 开启预取指缓存加速程序执行效率 RCC->CFGR |= RCC_CFGR_SWS_1; // 切换至外部高速晶振作为主干线时钟源 while (RCC->CFGR & RCC_CFGR_SWS) // 确认已完成切换动作前保持阻塞状态 ; // 空循环等待过渡完成 RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // 使能GPIOA端口时钟供应以便后续操作寄存器 } // ============================================ // 异步串行通讯接口初始化(基于USART1) // ============================================ void UsartInit(void) { // GPIO重映射配置 - 将TX/RX功能引脚路由到默认物理位置 RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // 使能交替功能IO组控制单元访问权限 AFIO->MAPR &= ~AFIO_MAPR_USART1_REMAP; // 取消高级外设重定向映射关系恢复原始布局 // 初始化USART参数结构体实例对象创建过程 USART_InitTypeDef usartSetting; usartSetting.USART_BaudRate = BAUD_RATE; // 设置传输速率参数值大小合适范围可调 usartSetting.USART_WordLength = USART_WordLength_8b; // 数据帧长度固定为8位字符格式兼容常用终端设备规范要求 usartSetting.USART_StopBits = USART_StopBits_1; // 每个包结尾添加单个停止位保证同步可靠性更高些 usartSetting.USART_ParityControl = USART_ParityControl_No;// 禁用奇偶校验减少开销提高吞吐量性能指标表现良好 usartSetting.USART_Mode = USART_Mode_TxOnly; // 仅开启发送模式节省资源占用情况较轻量化设计考虑因素之一 usartSetting.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用硬件流控机制简化连线复杂度降低成本优势明显存在 USART_Init(USART1, &usartSetting); // 应用上述配置到具体硬件模块中去生效设置项内容细节部分完全匹配预期目标达成合作共赢局面形成! USART_Cmd(USART1, ENABLE); // 激活外设开始正常工作状态转换过程顺利完成使命召唤任务下达执行命令序列启动运行起来! NVIC_EnableIRQ(USART1_IRQn); // 使能相关中断请求优先级排序处理机制建立完善体系结构保障响应速度足够快满足实时性需求挑战成功克服困难险阻前行不止步伐稳健有力支撑整个项目进展顺利推进下去直至胜利彼岸抵达为止! } // ============================================ // 定时器输入捕获模式配置(捕获上升沿触发中断) // ============================================ void TimCaptureInit(void) { // 配置ECHO信号接收引脚为浮空输入模式 GPIO_InitTypeDef gpioCfg; gpioCfg.GPIO_Pin = ECHO_PIN; // 指定要使用的特定管脚编号对应连接到外部设备上去 gpioCfg.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 设置为悬浮输入状态允许外部信号直接驱动该线路而无需额外上拉电阻等辅助元件支持即可正常工作! GPIO_Init(GPIOA, &gpioCfg); // 将以上设置应用于指定的物理接口之上让其具备预期电气特性满足设计要求规格书所述各项性能指标达标合格方可投入使用阶段测试验证效果如何? // 初始化TIM2参数结构体实例对象创建过程 TIM_TimeBaseInitTypeDef timBase; timBase.TIM_Period = 0xFFFF; // 设定最大计数周期防止溢出现象发生导致错误累计效应恶化实验结果可靠性降低的风险因素存在可能性增大! timBase.TIM_Prescaler = 0; // 不对时钟源做任何分频处理保持原始频率特性不变简单粗暴有效解决问题的方法往往就是最好的解决方案之一! timBase.TIM_CounterMode = TIM_CounterMode_Up; // 采用向上递增式计数方式产生锯齿波形适合于大多数常见应用场景比如音频合成器中的振荡器核心部件就是这样工作的原理一样的道理相通的嘛学以致用活学活用才是王道真理所在之处无人不知无人不晓了吧大概如此这般模样呈现在你眼前供你欣赏品味其中的奥妙之处难以言表只能意会不能言传的境界达到了! TIM_TimeBaseInit(TIM2, &timBase); // 把刚才精心挑选出来的一组参数打包发送给底层驱动程序去执行相应的动作指令集落实政策到位形成有效的生产力工具为企业创造价值最大化效益产出比最优解找到了! // 设置输入捕获预处理单元的工作模式 TIM_ICInitTypeDef timIcCfg; timIcCfg.TIM_Channel = TIM_Channel_1; // 选择通道1作为捕获源入口点位置标识符唯一性保证正确路由路径建立成功! timIcCfg.TIM_ICPolarity = TIM_ICPolarity_Rising; // 只对正弦波正斜率变化敏感也就是上升沿触发事件响应机制启动捕获流程开始记录时间差数值信息保存下来供后续分析使用! timIcCfg.TIM_ICSelection = TIM_ICSelection_DirectTI; // 直接耦合输入信号不经过任何衰减网络过滤环节保留原始波形特征完整性更好一些! timIcCfg.TIM_ICPrescaler = TIM_ICPSC_CM_OFF; // 关闭预分频因子设置以确保最高灵敏度捕捉能力发挥到极致水平展现非凡实力证明自身价值所在! TIM_ICInit(TIM2, &timIcCfg); // 应用所有配置项到对应的硬件寄存器中去使其生效开始履行岗位职责使命必达决心坚定不移勇往直前奋斗不息精神值得学习借鉴推广开来! // 使能更新中断请求并启动定时器运行起来! TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 允许更新事件发生时产生中断请求信号传递给CPU进行处理安排调度任务优先级排序等工作内容! TIM_Cmd(TIM2, ENABLE); // 正式启动定时器模块进入工作状态等待外部事件发生触发相应回调函数执行相应操作步骤流程顺序井然有序地进行下去直至完成任务目标达成为止! } // ============================================ // 定时器更新中断服务例程(处理回波信号) // ============================================ static void InterruptHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { // 检查是否由更新事件引发的中断请求 uint32_t matchPoint = TIM_GetCapture1(TIM2); // 获取当前捕获到的值存入变量中以便后续计算使用! float elapsedUs = (float)(matchPoint * 1.0f / SystemCoreClock); // 根据时钟频率换算出经过的时间微秒数近似值计算公式推导过程如下所示:总周期数÷主频=耗时时长! distanceCm = (elapsedUs / 58.0f) / 2.0f; // 根据声速公式计算距离:(微秒÷58μs/cm)再除以二得到单程长度结果即为所求答案! TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除挂起的标志位防止重复进入同一中断处理程序造成死循环现象出现影响系统稳定性! } } // ============================================ // 软件延时函数实现(非精确版简易替代方案) // ============================================ void DelayMs(uint32_t ms) { uint32_t count; for (count = 0; count < ms * 8000UL; count++) { __NOP(); } // 通过空操作指令消耗CPU周期达到延迟目的注意不同编译器优化级别会影响实际效果需要酌情调整参数值大小! }
10-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值