FreeRTOS中的四种信号量类型(二值信号量、计数信号量、互斥信号量、递归互斥信号量)各自具有专用和共用的API函数。以下是它们的分类说明:
一、二值信号量(Binary Semaphore)
用途:任务同步、简单互斥(非优先级继承)。
专用API:
-
创建:
SemaphoreHandle_t xSemaphoreCreateBinary(void);
初始化时信号量为空(不可用),需调用
xSemaphoreGive()
释放。 -
过时API(不推荐):
void vSemaphoreCreateBinary(SemaphoreHandle_t xSemaphore);
需预先定义句柄,初始状态为可用。
二、计数信号量(Counting Semaphore)
用途:管理多资源池、事件计数。
专用API:
- 创建:
参数指定最大计数值和初始值。SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, UBaseType_t uxInitialCount);
三、互斥信号量(Mutex)
用途:资源互斥访问,支持优先级继承。
专用API:
- 创建:
初始状态为可用(未被占用)。SemaphoreHandle_t xSemaphoreCreateMutex(void);
四、递归互斥信号量(Recursive Mutex)
用途:同一任务重复获取同一互斥量。
专用API:
- 创建:
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex(void);
- 递归操作:
必须成对调用,释放次数需等于获取次数。xSemaphoreTakeRecursive(SemaphoreHandle_t xMutex, TickType_t xBlockTime); xSemaphoreGiveRecursive(SemaphoreHandle_t xMutex);
共用API函数
所有信号量类型均可使用以下API:
-
获取信号量:
xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xBlockTime);
- 用于二值、计数、互斥信号量(递归互斥需用
TakeRecursive
)。 xBlockTime
:阻塞时间(portMAX_DELAY
表示无限等待)。
- 用于二值、计数、互斥信号量(递归互斥需用
-
释放信号量:
xSemaphoreGive(SemaphoreHandle_t xSemaphore);
- 用于二值、计数、互斥信号量(递归互斥需用
GiveRecursive
)。
- 用于二值、计数、互斥信号量(递归互斥需用
-
删除信号量:
void vSemaphoreDelete(SemaphoreHandle_t xSemaphore);
-
中断安全操作:
xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore, BaseType_t *pxHigherPriorityTaskWoken); xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore, BaseType_t *pxHigherPriorityTaskWoken);
- 仅适用于二值和计数信号量,不可用于互斥量。
-
查询当前计数值:
UBaseType_t uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore);
- 返回信号量的当前计数值(二值信号量返回0或1)。
注意事项
- 互斥量限制:不可在中断中使用,无
FromISR
版本。 - 递归互斥量:必须使用
TakeRecursive
/GiveRecursive
,否则导致崩溃。 - 优先级反转:互斥量通过优先级继承避免,二值信号量无此机制。
- 初始化差异:二值信号量初始为空,互斥量初始为可用。
通过合理选择信号量类型及对应的API,可高效实现任务同步、资源管理及临界区保护。