FreeRTOS 信号量 HAL
时间: 2025-01-09 11:55:34 浏览: 1
### FreeRTOS 中基于 HAL 的信号量使用方法
#### 创建和初始化信号量
为了在 STM32 上利用 HAL 库配合 FreeRTOS 实现信号量操作,首先需要创建一个信号量句柄。这可以通过 `xSemaphoreCreateBinary()` 或者 `xSemaphoreCreateCounting()` 函数来完成,具体取决于应用需求是采用二值还是计数型信号量。
对于二值信号量,在按键按下时可以触发一次性的状态改变;而对于计数型,则允许累积多次事件的发生[^3]。
```c
// 定义全局变量保存信号量句柄
SemaphoreHandle_t xBinarySemaphore;
void SystemInit(void){
// 初始化硬件外设...
// 创建二值信号量并将其初始值设置为0
xBinarySemaphore = xSemaphoreCreateBinary();
}
```
#### 发布(给予)信号量
当某个条件满足或者特定事件发生时,比如外部中断被激活或是定时器超时时,应该通过调用 `xSemaphoreGive()` 来发布该信号量给等待它的其他任务。需要注意的是,如果尝试在一个已经处于“已给出”的状态下再次发出相同的信号量,此动作不会生效,因为每次发布的信号量都必须由相应的获取操作所匹配[^1]。
```c
void EXTI_LineInterruptHandler(void){
BaseType_t xHigherPriorityTaskWoken;
if(/* 检查是否是由目标IO引起的中断 */){
// 给予信号量, 并检查是否有更高优先级的任务被唤醒
xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
```
#### 获取(接收)信号量
另一个任务可以在其循环体内不断试图获取这个信号量,直到它变为可用为止。通常会指定一定的时间期限去阻塞当前线程直至获得所需的资源。一旦成功接收到信号量,意味着之前设定的那个特殊条件下发生的事件已经被处理过了。
```c
void vTaskCode( void * pvParameters )
{
for( ;; ){
if ( xSemaphoreTake( xBinarySemaphore, ( TickType_t ) 10 ) == pdTRUE )
{
/* Critical section of code here */
// 执行临界区代码...
/* End critical section. Don't forget to release the semaphore
before leaving this block! */
}else {
// 如果未能及时得到信号量则执行这里的内容
}
}
}
```
阅读全文