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

【CI130x-离在线】FreeRTOS的信号量

CI130x ALG SDK库中的audio_play_os_state_t audio_play_semaphore_give(audio_play_os_sem_t xSemaphore)函数是对 FreeRTOS 内置函数 xSemaphoreGive()的简单封装

 

/**
 * @brief 发送信号量
 *
 * @param xSemaphore 信号量句柄
 *
 * @retval AUDIO_PLAY_OS_SUCCESS 发送成功
 * @retval AUDIO_PLAY_OS_FAIL 发送失败
 */
audio_play_os_state_t audio_play_semaphore_give(audio_play_os_sem_t xSemaphore)
{
    if (pdFALSE == xSemaphoreGive(xSemaphore))
    {
        return AUDIO_PLAY_OS_FAIL;
    }    return AUDIO_PLAY_OS_SUCCESS;
}

 下面详细介绍下FreeRTOS的信号量

 

核心概念

xSemaphoreGive 是 FreeRTOS 实时操作系统中一个非常重要的函数,它的核心作用是释放一个信号量

你可以把信号量想象成一个令牌:

  • 初始状态:信号量有固定数量的令牌(对于二进制信号量是 0 或 1;对于计数信号量是 0 到 N)。

  • 获取令牌(Take):任务调用 xSemaphoreTake 来尝试获取一个令牌。如果令牌可用,任务就继续执行;如果不可用,任务可以选择等待(阻塞)直到有令牌被释放。

  • 释放令牌(Give):任务调用 xSemaphoreGive 来归还一个令牌,使其可供其他任务获取。这就像是把一个令牌放回了池子里。

简单来说:xSemaphoreGive 的作用是增加信号量的计数值,通知系统“我这边完成了,资源可用了,或者事件发生了”。


函数原型

c
 
 
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
  • 参数

    • xSemaphore:要释放的信号量的句柄。这个句柄是在你创建信号量(使用 xSemaphoreCreateBinaryxSemaphoreCreateCounting 等函数)时获得的。

  • 返回值

    • pdPASS:信号量释放成功。

    • pdFALSE:信号量释放失败。最常见的原因是在释放一个已经达到最大计数值的信号量(例如,释放一个已经被释放的二进制信号量)。


主要应用场景

xSemaphoreGive 通常用在以下三种场景中:

1. 同步(任务间同步)

一个任务(或中断服务程序)通过释放信号量来通知另一个任务某个事件已经发生

  • 示例:任务 A 等待一个按钮按下事件。

    • 任务 A 在启动时调用 xSemaphoreTake(..., portMAX_DELAY) 等待信号量,因为没有令牌,它会进入阻塞状态。

    • 当按钮被按下(在中断服务程序中),ISR 调用 xSemaphoreGiveFromISR(...) 释放信号量。

    • 任务 A 立即从 xSemaphoreTake 中退出,开始执行处理按钮按下的代码。

2. 资源管理(互斥锁)

任务在使用一个共享资源(如串口、SPI总线、全局变量)前先获取信号量(互斥锁),使用完毕后释放它,以确保同一时间只有一个任务能访问该资源。

  • 示例:两个任务都要向同一个串口发送数据。

    • 任务 A 调用 xSemaphoreTake(mutex_uart, ...) 获取互斥锁。

    • 任务 A 开始向串口发送数据。

    • 此时任务 B 也调用 xSemaphoreTake(mutex_uart, ...) 试图获取互斥锁,但因为锁已被 A 持有,任务 B 会进入阻塞状态。

    • 任务 A 发送完数据后,调用 xSemaphoreGive(mutex_uart) 释放互斥锁。

    • 锁被释放后,任务 B 被唤醒并成功获取到锁,然后开始发送它的数据。

3. 生产者和消费者(计数信号量)

生产者任务释放信号量(增加计数值)来表示它生产了多少个项目,消费者任务获取信号量来表示它消费了多少个项目。

  • 示例:一个生产者任务向消息队列填充数据,一个消费者任务从队列中取出数据。

    • 初始时,一个计数信号量的计数值为 0,表示队列为空。

    • 生产者:每向队列成功发送一条消息后,就调用 xSemaphoreGive(count_sem),将信号量计数值加 1。

    • 消费者:在从队列读取消息前,先调用 xSemaphoreTake(count_sem, ...)。如果有信号量(计数值 > 0),表示队列中有消息,它取出消息并将计数值减 1。如果计数值为 0,则消费者等待。


重要注意事项

  1. 不能在中断服务程序(ISR)中使用 xSemaphoreGive

    • 在 ISR 中,必须使用其专用版本 xSemaphoreGiveFromISR(),它进行了特殊的优化,不会进行可能导致上下文切换的任务调度(直到中断退出)。

  2. 不要释放一个你没有获取的信号量

    • 这主要针对互斥锁(Mutex)。互斥锁具有优先级继承机制,并且必须由获取它的同一个任务来释放。随意释放一个未被获取的互斥锁会导致系统行为异常。

    • 对于二进制信号量和计数信号量,通常可以由不同的任务进行 Give 和 Take。

  3. 释放已满的信号量

    • 对于一个二进制信号量,如果它的值已经是 1(可用),再次调用 xSemaphoreGive 将会失败,并返回 pdFALSE。这在设计上通常被视为一个编程错误。

    • 对于一个最大计数值为 N 的计数信号量,如果其计数值已经达到 N,再次调用 xSemaphoreGive 也会失败。

总结

 
 
方面 解释
核心作用 增加信号量的计数值,使其可用。
使用场景 任务同步、资源管理(互斥)、生产者-消费者模型。
调用者 任务(Task)。
在ISR中使用 必须使用 xSemaphoreGiveFromISR
返回值 pdPASS(成功)或 pdFALSE(失败,通常因为信号量已满)。

希望这个解释能帮助你彻底理解 xSemaphoreGive

http://www.hskmm.com/?act=detail&tid=39648

相关文章:

  • 践行 “学思行”,解锁学习新境界
  • 【ArcMap】按属性表复制字段并上移一段距离
  • CF1060
  • 以专注筑基,以实践致远
  • 2025.10.24 测试
  • 102302139 尚子骐 数据采集与融合作业1
  • CF1152F2 Neko Rules the Catniverse (Large Version) 题解
  • Audacity:开源音频编辑器的完整指南
  • 123456789
  • 【CI130x】音频传输的数据结构——FreeRTOS的消息队列
  • 量子力学作业3
  • #20232408 2025-2026-1 《网络系统与攻防技术》实验三实验报告 - 20232408
  • C_结构体学习_1
  • 嵌入式音频开发很好的博主
  • 实验3 C语言函数应用编程
  • 人工智能之编程基础 Python 入门:第一章 Python 的简介和安装
  • P5405 [CTS2019] 氪金手游 题解
  • 杂记选做 #1
  • 20232319 2025-2026-1 《网络与系统攻防技术》实验三实验报告
  • 2025.10.26 闲话-单位根反演
  • 题解:B4205 [常州市赛 2021] 特殊字符
  • 郭念海 - coder
  • 数据采集与融合技术实践第一次作业
  • ECC 学习笔记
  • 转化漏斗(随笔)
  • Halcon算法——区域生长
  • Windows11文件夹右键-删除多余选项-加快打开速度
  • 20231326《密码系统设计》第五周预习报告
  • 2025年实木家具厂家权威推荐榜:原木/全实木/北美黑胡桃/樱桃木/榫卯工艺/高端定制/全屋整装,烘干/白胚/木蜡油保养工艺深度解析
  • 2025年摘星搜荐怎么样:全面评测摘星AI的功能与优势