15个必装节点解锁ComfyUI完整潜能:告别AI绘画的“功能短板”
2026/5/10 13:43:20
**二值信号量(Binary Semaphore)**是FreeRTOS提供的一种简单而强大的同步工具,它只有两个可能值:0或1。
形象理解:二值信号量就像公共卫生间的占用指示灯:
二值信号量实质上是一个队列长度为1的特殊队列!在FreeRTOS内核中:
这种实现使二值信号量具有队列的所有优势,包括任务阻塞和优先级继承等特性。
当多个任务需要访问共享资源(如全局变量、外设)时,二值信号量能确保任一时刻只有一个任务能访问该资源:
// 任务想要访问共享资源时 xSemaphoreTake(xMutexSemaphore, portMAX_DELAY); // 获取访问权 // 访问共享资源 xSemaphoreGive(xMutexSemaphore); // 释放访问权实现"任务A必须在任务B之前完成"的先后依赖关系:
// 任务A完成工作后 xSemaphoreGive(xSyncSemaphore); // 发出"我完成了"的信号 // 任务B开始前 xSemaphoreTake(xSyncSemaphore, portMAX_DELAY); // 等待任务A完成 // 开始任务B的工作FreeRTOS使用优先级管理等待同一信号量的多个任务:
| 函数 | 描述 | 使用场景 |
|---|---|---|
xSemaphoreCreateBinary() | 创建二值信号量(不会自动释放) | 需要初始状态为"不可用"的场景 |
vSemaphoreCreateBinary() | 创建二值信号量(创建后自动释放一次) | 需要初始状态为"可用"的场景 |
xSemaphoreTake() | 获取信号量(将信号量由1变为0) | 任务中获取信号量 |
xSemaphoreGive() | 释放信号量(将信号量由0变为1) | 任务中释放信号量 |
xSemaphoreTakeFromISR() | 中断中获取信号量 | 中断服务程序中获取信号量 |
xSemaphoreGiveFromISR() | 中断中释放信号量 | 中断服务程序中释放信号量 |
| 特性 | 二值信号量 | 互斥信号量 |
|---|---|---|
| 优先级继承 | ❌ 没有 | ✅ 有 |
| 适用场景 | 任务同步、中断同步 | 互斥访问共享资源 |
| 中断使用 | ✅ 可以在中断中使用 | ❌ 不能在中断中使用 |
| 优先级翻转 | ❌ 会导致优先级翻转 | ✅ 通过优先级继承解决优先级翻转 |
| 创建函数 | xSemaphoreCreateBinary() | xSemaphoreCreateMutex() |
SemaphoreHandle_t xSyncSemaphore; void TaskA(void *pvParameters) { while(1) { // 执行任务A的工作 // ... // 任务A完成,通知任务B xSemaphoreGive(xSyncSemaphore); vTaskDelay(pdMS_TO_TICKS(1000)); } } void TaskB(void *pvParameters) { while(1) { // 等待任务A完成 xSemaphoreTake(xSyncSemaphore, portMAX_DELAY); // 任务B开始工作 // ... vTaskDelay(pdMS_TO_TICKS(500)); } } int main() { xSyncSemaphore = xSemaphoreCreateBinary(); xTaskCreate(TaskA, "TaskA", 128, NULL, 1, NULL); xTaskCreate(TaskB, "TaskB", 128, NULL, 2, NULL); vTaskStartScheduler(); }SemaphoreHandle_t xISRSemaphore; void vISRHandler(void) { // 中断处理 // ... // 释放信号量,通知任务 BaseType_t xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(xISRSemaphore, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } void TaskHandler(void *pvParameters) { while(1) { // 等待中断通知 xSemaphoreTake(xISRSemaphore, portMAX_DELAY); // 处理中断事件 // ... } }xSemaphoreGive()释放信号量,才能被获取二值信号量是FreeRTOS中实现任务同步和中断同步的利器,它简单高效,特别适合以下场景:
理解二值信号量的底层原理(队列长度为1的特殊队列)有助于我们更准确地使用它,避免优先级翻转等问题。在实际开发中,应根据具体需求选择合适的同步机制,二值信号量、互斥信号量和计数信号量各有其最佳适用场景。