1、二值信号量
FreeRTOS中的二值信号量是一种用于任务间同步的机制,它只能有两个状态:0 或 1。二值信号量通常用来表示某个事件是否发生,比如硬件中断发生时设置信号量为1,表示事件已发生;而任务在需要等待该事件发生时,会尝试获取信号量,若信号量为0则任务会被挂起等待,直到信号量变为1。二值信号量本质就是一个长度为1,大小为零的队列,只有0和1两种状态,通常情况下,用它来进行互斥访问或任务同步。
2、主要PAI函数
xSemaphoreCreateBinary() //使用动态方式创建二值信号量
xSemaphoreCreateBinaryStatic() //使用静态方式创建二值信号量
xSemaphoreGive() //释放信号量
xSemaphoreGiveFromISR() //在中断中释放信号量
xSemaphoreTake() //获取信号量
xSemaphoreTakeFromISR() //在中断中获取信号量
2.1 二值信号量创建
SemaphoreHandle_t xSemaphoreCreateBinary( void )
/*
参数:
无
返回值:
成功,返回对应二值信号量的句柄;
失败,返回 NULL 。
*/
2.2 二值信号量释放
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore )
/*
参数:
xSemaphore:要释放的信号量句柄
返回值:
成功,返回 pdPASS ;
失败,返回 errQUEUE_FULL 。
*/
2.3 获取二值信号量
BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore,
TickType_t xTicksToWait );
/*
参数:
xSemaphore:要获取的信号量句柄
xTicksToWait:超时时间,0 表示不超时,portMAX_DELAY表示卡死等待;
返回值:
成功,返回 pdPASS ;
失败,返回 errQUEUE_FULL 。
*/
3、STM32CubeMX配置
Timers and Semaphores -> Add -> ok
生成代码。
4、keil 5程序设计
4.1 程序初始化配置
首先在main.h中添加信号量头文件:
#include "semphr.h"
接着在freertos中对任务1、2进行信号量放入、获取函数:
4.2 任务1 信号量放入
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
uint16_t buf = 100;
BaseType_t status;
/* Infinite loop */
for(;;)
{
if(sign_1==1){
status = xSemaphoreGive(myBinarySem01Handle);
if (status == pdTRUE){
printf("二值信号量放入成功");
}
else{
printf("二值信号量放入失败\r\n");
}
sign_1=0;
}
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
4.3 信号量获取
void StartTask02(void *argument)
{
/* USER CODE BEGIN StartTask02 */
uint16_t buf;
BaseType_t status;
/* Infinite loop */
for(;;)
{
if(sign_1==2){
status = xSemaphoreTake(myBinarySem01Handle,0);
if (status == pdTRUE){
printf("二值信号量获取成功");
}
else{
printf("二值信号量获取失败\r\n");
}
sign_1=0;
}
osDelay(1);
}
/* USER CODE END StartTask02 */
}
4.4 测试
测试会发现信号量放入失败,但是获取成功。
解决办法:
造成上诉问题是因为STM32CubeMX默认已经放入一个信号量,只需要将1改成0即可。
myBinarySem01Handle = osSemaphoreNew(1, 0, &myBinarySem01_attributes);
测试结果:
问题解决!
上文如有错误恳请各位大佬指正!