FreeRTOS 的信号量
关于信号量的使用
- 二值信号量: 二值信号量是一种最简单的信号量,它只有两个状态,即已上锁和未上锁。
- 互斥信号量: 互斥信号量是一种高级信号量,它可以实现多个任务对同一资源的互斥访问。
- 递归信号量: 递归信号量是一种高级信号量,它可以实现多个任务对同一资源的递归访问。
- 计数信号量: 计数信号量是一种高级信号量,它可以实现多个任务对同一资源的并发访问。
- 事件标志组: 事件标志组是一种高级信号量,它可以实现多个任务对同一事件的并发访问。
- 队列: 队列是一种高级信号量,它可以实现多个任务对同一资源的并发访问。
1. 二值信号量的使用
- 二值信号量的使用方法如下:
- 创建信号量:
- 获取信号量:
- 释放信号量:
- 删除信号量:
- 举例代码:
c
#include "FreeRTOS.h"
#include "semphr.h"
SemaphoreHandle_t xSemaphore;
void vTask1(void *pvParameters)
{
while (1)
{
// 获取信号量
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE)
{
// 信号量获取成功,执行任务
// ...
// 释放信号量
xSemaphoreGive(xSemaphore);
}
else
{
// 信号量获取失败,执行其他任务
// ...
}
}
}
void vTask2(void *pvParameters)
{
while (1)
{
// 获取信号量
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE)
{
// 信号量获取成功,执行任务
// ...
// 释放信号量
xSemaphoreGive(xSemaphore);
}
else
{
// 信号量获取失败,执行其他任务
// ...
}
}
}
int main(void)
{
// 创建二值信号量
xSemaphore = xSemaphoreCreateBinary();
// 创建任务1
xTaskCreate(vTask1, "Task1", 256, NULL, 1, NULL);
// 创建任务2
xTaskCreate(vTask2, "Task2", 256, NULL, 2, NULL);
// 启动任务调度器
vTaskStartScheduler();
return 0;
}
- 典型应用:
有两个任务需要同步时,可以使用二值信号量来实现。是一个任务完成后,释放信号量,另一个任务获取信号量,继续执行。比如在串口通讯中,我们经常需要在发送完串口数据后,等待接收对方传过来的数据.但是数据的接收可以使用非阻塞的回调函数来实现,这就造成一个问题,当发送完数据后,数据的接收是在另一个线程里接收的,当前的发送数据的线程怎么知道数据接收完成呢?这就需要使用二值信号量来实现同步。
- 创建二值信号量:
```c
SemaphoreHandle_t xSemaphore;
xSemaphore = xSemaphoreCreateBinary();- 获取信号量:
c
if(xSemaphoreTake(xSettingSemaphore, (TickType_t)1000) == pdTRUE){
// 信号量获取成功
}
else
{
// 信号量获取失败,或是超时
}- 在接收线程中,如果收到数据,就会释放信号量:
c
xSemaphoreGive(xSettingSemaphore);这样就实现的了两个任务之间的同步。
