FreeRTOS学习笔记(应用)-- 各种 信号量的应用场景

文章目录

在单片机上使用FreeRTOS时,信号量是任务间同步、互斥或资源管理的核心机制。FreeRTOS中常用的信号量类型包括 二进制信号量计数信号量互斥信号量(Mutex)递归互斥信号量 ,它们的应用场景有明确区分,具体如下:

1. 二进制信号量(Binary Semaphore)

二进制信号量只有两种状态:可用(1)不可用(0) ,核心用途是同步(任务间或中断与任务间的"事件通知")。

典型应用场景:
  • 中断与任务同步

    单片机的外部中断(如按键、传感器触发)通常需要快速响应,复杂逻辑(如按键防抖、数据解析)适合放在任务中处理。此时,中断服务程序(ISR)可通过释放二进制信号量"通知"任务,任务则阻塞等待信号量,实现"中断触发→任务处理"的同步。

    例:按键按下触发外部中断,ISR中调用xSemaphoreGiveFromISR()释放信号量,按键处理任务通过xSemaphoreTake()等待信号量,获取后执行按键逻辑(避免在ISR中做耗时操作)。

  • 任务间同步

    一个任务完成某操作后,通知另一个任务开始执行。例如:传感器采集任务(A)完成数据采集后,释放信号量,数据处理任务(B)等待信号量后开始处理数据,实现"A完成→B启动"的顺序控制。

2. 计数信号量(Counting Semaphore)

计数信号量的状态是一个非负整数(计数),可用于资源数量管理事件次数统计 ,计数的范围由创建时的uxMaxCount限制。

典型应用场景:
  • 有限资源管理

    当多个任务需要竞争访问有限数量的共享资源时(如缓冲区、外设通道),计数信号量的初始值设为资源总数,任务获取资源时计数减1,释放时计数加1。

    例:单片机有3个UART发送缓冲区,计数信号量初始化为3。任务需要发送数据时,先通过xSemaphoreTake()获取信号量(占用1个缓冲区),发送完成后通过xSemaphoreGive()释放(归还缓冲区),确保缓冲区不被超额占用。

  • 事件计数

    统计某事件发生的次数,任务可一次性处理多次事件。例如:高频传感器(如加速度计)每采集一次数据就释放一次信号量(计数+1),数据处理任务可通过xSemaphoreTake()一次获取多个计数(如一次处理10次采集的数据),减少任务唤醒频率。

3. 互斥信号量(Mutex)

互斥信号量本质是一种特殊的二进制信号量,用于保护共享资源 (防止多个任务同时访问导致数据混乱),核心特性是优先级继承(避免优先级反转)。

典型应用场景:
  • 共享外设/资源的互斥访问
    单片机中多个任务可能需要访问同一外设(如I2C总线、SPI设备、全局变量),此时需用Mutex确保"同一时间只有一个任务访问资源"。
    例:任务A(低优先级)和任务B(高优先级)都需要通过I2C访问温湿度传感器。任务A获取Mutex后正在操作I2C时,任务B就绪:若用普通二进制信号量,任务B会一直等待(优先级反转),而Mutex的优先级继承机制会临时提升任务A的优先级,让其快速释放资源,避免高优先级任务长期阻塞。

4. 递归互斥信号量(Recursive Mutex)

递归互斥信号量允许同一任务多次获取信号量(需对应多次释放),用于任务中存在"嵌套访问共享资源"的场景,避免自我死锁。

典型应用场景:
  • 嵌套函数访问共享资源
    当一个任务中的函数A调用函数B,且A和B都需要访问同一共享资源时,普通Mutex会导致死锁(任务已持有Mutex,再次获取时会阻塞自己)。递归Mutex允许同一任务多次获取,只需释放次数与获取次数相同即可。
    例:单片机的日志模块中,log_debug()函数调用log_write()函数,两者都需要访问日志缓冲区(共享资源)。用递归Mutex保护缓冲区,log_debug()获取后,log_write()可再次获取,避免死锁。

总结

  • 二进制信号量:侧重"同步"(事件通知),如中断-任务、任务-任务的触发。
  • 计数信号量:侧重"数量管理",如有限资源分配或事件次数统计。
  • 互斥信号量:侧重"共享资源保护",解决多任务竞争,带优先级继承。
  • 递归互斥信号量:侧重"嵌套访问保护",避免同一任务的自我死锁。

实际使用时需根据场景选择,避免滥用(如用Mutex做同步会浪费优先级继承的开销,用二进制信号量做互斥可能导致优先级反转)。

相关推荐
ndjnddjxn2 小时前
Rust学习
开发语言·学习·rust
菜鸟‍2 小时前
【后端学习】MySQL数据库
数据库·后端·学习·mysql
陈天伟教授3 小时前
基于学习的人工智能(1)机器学习
人工智能·学习
im_AMBER3 小时前
Leetcode 59 二分搜索
数据结构·笔记·学习·算法·leetcode
专注于大数据技术栈3 小时前
java学习--final
java·开发语言·学习
田里的水稻3 小时前
AI_常见“XX学习”术语速查表
人工智能·学习
Nan_Shu_6143 小时前
学习:Sass
javascript·学习·es6
天殇凉3 小时前
AC自动机学习笔记
java·笔记·学习
AA陈超4 小时前
从0开始学习 **Lyra Starter Game** 项目
c++·笔记·学习·游戏·ue5·lyra
rchmin5 小时前
Prompt Engineering 从入门到精通的系统学习路径
人工智能·学习·prompt