当前位置: 首页 > news >正文

【FreeRTOS】(号外)任务间通讯2: 信号量- Counting Semaphore

    

    计数信号量是 FreeRTOS 提供的一种关键同步机制,其核心设计初衷是管理有限资源的高效分配与安全共享。与二值信号量(仅表示“有/无”状态)不同,计数信号量允许资源实例被多次分配和释放,适用于以下典型场景:


1. 核心特性与设计意图
  • 资源池管理
    当系统存在多个相同资源的实例(如内存块、外设句柄、网络连接池等),计数信号量通过计数器动态跟踪可用资源数量:

    • xSemaphoreCreateCounting(maxCount, initialCount)
      初始化时设定资源池的最大容量(maxCount初始可用数量(initialCount

    • xSemaphoreTake()
      申请资源,计数器递减;若计数器为 0,则任务阻塞(或立即返回,取决于阻塞时间设置)。

    • xSemaphoreGive()
      释放资源,计数器递增,唤醒等待任务。

  • 线程安全的计数器
    其底层通过原子操作确保计数器的增减是线程安全的,避免多任务竞争导致的数据错误。


2. 典型应用场景
  • 有限资源池
    例如管理 10 个可用的 UART 发送缓冲区,任务通过信号量申请/释放缓冲区。

    SemaphoreHandle_t xBufferSem = xSemaphoreCreateCounting(10, 10); // 初始化10个可用缓冲区void vTaskSender(void *pvParams) {while (1) {if (xSemaphoreTake(xBufferSem, portMAX_DELAY) { // 申请缓冲区send_data_to_uart(); // 使用资源xSemaphoreGive(xBufferSem); // 释放资源}}
    }
  • 事件计数
    统计异步事件的发生次数(如传感器数据到达次数),任务通过信号量感知事件累积量。

    SemaphoreHandle_t xEventSem = xSemaphoreCreateCounting(100, 0); // 初始无事件// 中断服务例程(ISR)中触发事件
    void vSensorISR() {BaseType_t xHigherPriorityTaskWoken = pdFALSE;xSemaphoreGiveFromISR(xEventSem, &xHigherPriorityTaskWoken); // 事件计数+1portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
  • 流量控制
    限制同时执行某操作的并发任务数(如最多 3 个任务同时访问 SD 卡)。


3. 与二值信号量的关键区别
特性计数信号量二值信号量
资源表示多实例(计数器 ≥ 0)单实例(0 或 1)
阻塞行为计数器为 0 时任务阻塞信号量为 0 时任务阻塞
适用场景资源池、事件计数、并发控制任务同步、互斥锁(需配合互斥量)

4. 使用注意事项
  • 初始化合理性
    initialCount 必须 ≤ maxCount,否则可能导致逻辑错误。

  • 优先级反转风险
    若高优先级任务因信号量阻塞,可能被中优先级任务抢占,需结合优先级继承机制(如改用互斥量)。

  • ISR 中的操作
    必须使用 xSemaphoreGiveFromISR() 或 xSemaphoreTakeFromISR(),避免在中断中阻塞。


5. 总结

    计数信号量是 FreeRTOS 中管理多实例资源的首选工具,其通过原子化计数器实现了资源的安全分配、高效回收和任务同步。正确使用该机制可显著提升系统可靠性,尤其在资源受限的嵌入式环境中。

http://www.dtcms.com/a/319643.html

相关文章:

  • NFS 服务器与iSCSI 服务器
  • USB枚举介绍 以及linux USBFFS应用demo
  • centos安装python、uv
  • Python包与虚拟环境工具全景对比:从virtualenv到uv的演进
  • python中用xlrd、xlwt读取和写入Excel中的日期值
  • python 常用条件判断语句用法
  • day44 力扣1143.最长公共子序列 力扣1035.不相交的线 力扣53. 最大子序和 力扣392.判断子序列
  • 关于时钟门控ICG的一切(与门及或门门控)
  • [论文阅读] 人工智能 + 软件工程 | 大型语言模型与静态代码分析工具:漏洞检测能力大比拼
  • 分布式事务与分布式锁
  • PCB布线
  • 大队列CT胰腺癌PANDA 模型 医生结合AI后,病灶检测灵敏度提升 8.5%,胰腺癌识别灵敏度提升 20.5%,住院医师性能接近专家水平
  • 补充一种激活函数:GeGLU
  • 关于AI应用案例计算机视觉、自然语言处理、推荐系统和生成式AI四大领域的详细技术分析。
  • 数学建模——粒子群算法
  • Gradle 全解析:Android 构建系统的核心力量
  • JavaScript构建工具
  • CSS overscroll-behavior:解决滚动穿透的 “边界控制” 专家
  • 《Day3-PyTorch 自动微分入门:从计算图到梯度下降的实践指南》
  • Redis中间件(三):Redis存储原理与数据模型
  • Dokcer创建中间件环境
  • LeetCode:347.前K个高频元素
  • 手写数字识别实战 - 从传统机器学习到深度学习
  • 13-netty基础-手写rpc-消费方生成代理-05
  • Qt——入门
  • 数据赋能(386)——数据挖掘——迭代过程
  • Spring、Spring MVC、MyBatis 和 Spring Boot的关系
  • Ethereum:如何优雅部署 NPM 包中的第三方智能合约?
  • LoadBalancingSpi
  • Beelzebub靶机