当前位置: 首页 > 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.lryc.cn/news/612839.html

相关文章:

  • 前端发布 发布前端项目流程
  • Spring AI + Redis:构建高效AI应用缓存方案
  • 华为 2025 校招目标院校
  • 杂谈:大模型与垂直场景融合的技术趋势
  • 高通芯片漏洞被在野利用,谷歌发布紧急安卓补丁
  • Swift 实战:高效设计 Tic-Tac-Toe 游戏逻辑(LeetCode 348)
  • ansible-playbook之yum
  • Daemon Tools for Mac —— 专业虚拟光驱与磁盘映像工具
  • LeetCode 面试经典 150_数组/字符串_除自身以外数组的乘积(13_238_C++_中等)(前缀积)
  • 数据结构初阶(5)队列
  • java - 深拷贝 浅拷贝
  • KT148A 语音芯片自研板烧录方案:接口预留与电路连接指南
  • 线上业务突然流量掉 0 ?一次 DNS 污染排查与自救实录
  • itextPdf获取pdf文件宽高不准确
  • 无人机航拍数据集|第8期 无人机海上目标检测YOLO数据集3641张yolov11/yolov8/yolov5可训练
  • BES2700量产项目
  • 7. 什么是事件委托
  • 经营帮:重构企业经营全流程,打造产业互联网新生态
  • 上位机知识篇---AT指令
  • LabVIEW实验室测试框架
  • 复合机器人破局之路:如何逆袭突围
  • 强化学习详解:从理论到前沿的全面解析
  • 知识随记-----Qt 实用技巧:自定义倒计时按钮防止用户频繁点击
  • GitHub 趋势日报 (2025年08月06日)
  • 网络安全与软件定义汽车的发展
  • 【LLM】扩散模型与自回归模型:文本生成的未来对决
  • 分布式事务与分布式锁
  • “物联网+职业本科”:VR虚拟仿真实训室的发展前景
  • USB枚举介绍 以及linux USBFFS应用demo
  • 抖音、快手、视频号等多平台视频解析下载 + 磁力嗅探下载、视频加工(提取音频 / 压缩等)