> 文章列表 > FreeRTOS - 二值信号量

FreeRTOS - 二值信号量

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:信号量获取失败

注意事项

只能在中断中调用,没有阻塞功能

三.任务

FreeRTOS - 二值信号量

3.1CubeMX生成二值信号量

在FreeRTOS中找到Times and Semaphore

FreeRTOS - 二值信号量

在Binary Semaphores中添加

FreeRTOS - 二值信号量

四.代码实现

  • 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配置

FreeRTOS - 二值信号量

等待信号量到,才开始执行任务。提高CPU占有利用率