FreeRTOS - 二值信号量
一.信号量定义
信号量(semaphore),多任务环境下使用的一种设施,负责协调多个任务,以保证任务能够正确,合理的使用公共资源。
二.二值信号量应用函数
函数原型 |
#include “FreeRTOS.h” #include “semphr.h” SemaphoreHandle_t xSemaphoreCreateBinary( void ); |
功能概述 |
创建二值信号量,并返回信号量句柄。 创建完成后,信号量状态为空。 |
参数 |
None |
返回值 |
NULL:堆空间不足 Any other value :信号量句柄 |
注意事项 |
configSUPPORT_DYNAMIC_ALLOCATION必须置为1 |
函数原型 |
#include “FreeRTOS.h” #include “semphr.h” BaseType_t xSemaphoreGive( SemaphoreHandle_t ① xSemaphore ); |
功能概述 |
任务间释放信号量 |
参数 |
①:信号量句柄 |
返回值 |
pdPASS:信号量释放成功 pdFAIL: 此信号量,拥有者不是任务,任务需获取到信号量,才可以释放信号 |
注意事项 |
None |
函数原型 |
#include “FreeRTOS.h” #include “semphr.h” BaseType_t xSemaphoreGiveFromISR( ①SemaphoreHandle_t xSemaphore, ②BaseType_t *pxHigherPriorityTaskWoken ); |
功能概述 |
中断,任务间释放信号量 |
参数 |
①:信号量句柄 ②:表示在释放信号量成功后,是否进行上下文切换,保证高优先级任务立刻执行,FreeRTOS V7.3.0以后变为可选参数,直接设置为NULL |
返回值 |
pdTRUE:信号量释放成功 errQUEUE_FULL:信号量已经可用 |
注意事项 |
None |
函数原型 |
#include “FreeRTOS.h” #include “semphr.h” BaseType_t xSemaphoreTake( ①SemaphoreHandle_t xSemaphore, ②TickType_t xTicksToWait ); |
功能概述 |
任务间获取信号量 |
参数 |
①:信号量句柄 ②:如果信号量不是立即可用,任务则进入阻塞状态,传入的等待多少个tick值,传入portMAX_DELAY任务将无限期等待中 |
返回值 |
pdPASS:信号量获取成功 pdFAIL:信号量获取失败 |
注意事项 |
只能在执行的任务中调用 |
函数原型 |
#include “FreeRTOS.h” #include “semphr.h” BaseType_t xSemaphoreTakeFromISR( ①SemaphoreHandle_t xSemaphore, ②signed BaseType_t *pxHigherPriorityTaskWoken ); |
功能概述 |
中断中获取信号量 |
参数 |
①:信号量句柄 ②:表示在获取信号量成功后,是否进行上下文切换,保证高优先级任务立刻执行,FreeRTOS V7.3.0以后变为可选参数,直接设置为NULL |
返回值 |
pdPASS:信号量获取成功 pdFAIL:信号量获取失败 |
注意事项 |
只能在中断中调用,没有阻塞功能 |
三.任务
3.1CubeMX生成二值信号量
在FreeRTOS中找到Times and Semaphore
在Binary Semaphores中添加
四.代码实现
-
gpio.c
中断回调函数在gpio中实现
extern osSemaphoreId CPUPrintfBinarySemHandle;
//按键检测回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(Key1_Pin == GPIO_Pin) //判断按下的GPIO{if ( HAL_GPIO_ReadPin(GPIOA,GPIO_Pin) == GPIO_PIN_RESET) //按下按键,导通{
// HAL_Delay(10); //软件去抖动 if( HAL_GPIO_ReadPin(GPIOA,GPIO_Pin) == GPIO_PIN_RESET){
// HAL_GPIO_WritePin(GPIOB,Led_Red_Pin,GPIO_PIN_RESET);
// HAL_GPIO_WritePin(GPIOB,Led_Green_Pin,GPIO_PIN_SET);/*建立标志位*/keyStatus = Key_down;printf("按键已按下/r/n");xSemaphoreGiveFromISR(CPUPrintfBinarySemHandle,NULL);}}else{if( HAL_GPIO_ReadPin(GPIOA,GPIO_Pin) == GPIO_PIN_SET) // 高电平,未准备好 {
// HAL_Delay(10); //软件去抖动 if( HAL_GPIO_ReadPin(GPIOA,GPIO_Pin) == GPIO_PIN_SET){ // HAL_GPIO_WritePin(GPIOB,Led_Red_Pin,GPIO_PIN_SET); //关闭红灯
// HAL_GPIO_WritePin(GPIOB,Led_Green_Pin,GPIO_PIN_RESET); //开启绿灯/*建立标志位*/keyStatus = Key_up;printf("按键已抬起/r/n");}}}}
}
-
FreeRTOS.c
void Key_Task(void const * argument)
{/* USER CODE BEGIN Key_Task */keyStatus = Key_reset;/* Infinite loop */for(;;){if(xSemaphoreTake(CPUPrintfBinarySemHandle,portMAX_DELAY) == pdPASS){//挂起LED任务memset(u8TaskListBuff,0,400);vTaskGetRunTimeStats((char*)u8TaskListBuff);printf("Name Abs Time Time\\r\\n");printf("******************************************************\\r\\n");printf("%s",u8TaskListBuff);printf("******************************************************\\r\\n");keyStatus = Key_reset;}}/* USER CODE END Key_Task */
}
-
vTaskGetRunTimeStats
vTaskGetRunTimeStats() 来协助分析操作系统当前 task CPU 占用状态,以帮助优化 task 优先级
函数原型为:
voidvTaskGetRunTimeStats( char *pcWriteBuffer )
CubeMX配置
等待信号量到,才开始执行任务。提高CPU占有利用率