STM32G0学习手册——FreeRTOS任务通知
Posted SCCELE
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32G0学习手册——FreeRTOS任务通知相关的知识,希望对你有一定的参考价值。
目录
概述
每个任务都有一个32位的通知值,可以替代二值信号量,计数信号量,事件组,也可以代替长度为1的队列。
有以下几种方式发送通知给任务:
1.有通知未读,则不覆盖通知值
2.直接覆盖通知值
3.设置通知值一个或者多个位,当做事件组来使用
4.递增/递减通知,当做信号量来使用
有以下缺点:
1.只能有一个任务接收通知消息
2.只有等待通知的任务可以被阻塞,发送通知的任务都不会因为发送失败而进入阻塞。
代替二值信号量
在FreeRTOSConfig.h里开启任务通知
/*Turn on task notifications.*/
#define configUSE_TASK_NOTIFICATIONS 1
在main.c文件里面修改代码
/* USER CODE BEGIN Includes */
#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
static TaskHandle_t AppTask_Handle = NULL;
static TaskHandle_t KeyTask_Handle = NULL;
static TaskHandle_t LedTask_Handle = NULL;
extern int f_printf(const char *format, ...);
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
static void AppTaskCreate(void);
static void KeyTaskCreate(void);
static void LedTaskCreate(void);
/* USER CODE END PFP */
int main()
{
/* USER CODE BEGIN WHILE */
BaseType_t xReturn = pdFAIL;
xReturn = xTaskCreate((TaskFunction_t)AppTaskCreate,
(const char*) "APPTASKCREATE",
(uint16_t) 128,
(void *) NULL,
(UBaseType_t) 1 ,
(TaskHandle_t*) &AppTask_Handle);
if(xReturn == pdPASS)
{
f_printf("AppTask Create PASS.\\r\\n");
vTaskStartScheduler();
}
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/* USER CODE BEGIN 4 */
static void AppTaskCreate(void)
{
BaseType_t xReturn = pdFAIL;
xReturn = xTaskCreate((TaskFunction_t)LedTaskCreate,
(const char *) "LEDTASKCREATE",
(uint16_t) 128,
(void *) NULL,
/*If the priority here is the same as the key task, printf will not print it out. */
(UBaseType_t) 2,
(TaskHandle_t *)&LedTask_Handle);
if(xReturn == pdPASS)
f_printf("LedTask Create PASS.\\r\\n");
xReturn = xTaskCreate((TaskFunction_t)KeyTaskCreate,
(const char *) "KEYTASKCREATE",
(uint16_t) 128,
(void *) NULL,
(UBaseType_t) 1,
(TaskHandle_t *)&KeyTask_Handle);
if(xReturn == pdPASS)
{
f_printf("KeyTask Create PASS.\\r\\n");
vTaskDelete(AppTask_Handle);
}
}
static void KeyTaskCreate(void)
{
while(1)
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
{
vTaskDelay(50);
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
{
xTaskNotifyGive(LedTask_Handle);
f_printf("Give LedTask_Handle PASS.\\r\\n");
}
}
vTaskDelay(100);
}
}
static void LedTaskCreate(void)
{
uint32_t ulreturn=0;
while(1)
{
ulreturn=ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
if(ulreturn==1)
{
/*It won’t be printed out at the same level*/
f_printf("LedTask TAKE PASS.\\r\\n");
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);
}
else
f_printf("LedTask TAKE FAIL.\\r\\n");
vTaskDelay(100);
}
}
/* USER CODE END 4 */
代替计数信号量
在FreeRTOSConfig.h里开启任务通知
/*Turn on task notifications.*/
#define configUSE_TASK_NOTIFICATIONS 1
在main.c文件里面修改代码
/* USER CODE BEGIN Includes */
#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
static TaskHandle_t AppTask_Handle = NULL;
static TaskHandle_t KeyTask_Handle = NULL;
static TaskHandle_t LedTask_Handle = NULL;
extern int f_printf(const char *format, ...);
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
static void AppTaskCreate(void);
static void KeyTaskCreate(void);
static void LedTaskCreate(void);
/* USER CODE END PFP */
int main()
{
/* USER CODE BEGIN WHILE */
BaseType_t xReturn = pdFAIL;
xReturn = xTaskCreate((TaskFunction_t)AppTaskCreate,
(const char *) "APPTASKCREATE",
(uint16_t) 128,
(void *) NULL,
(UBaseType_t) 1,
(TaskHandle_t*) &AppTask_Handle);
if(xReturn == pdPASS)
{
f_printf("AppTask Create PASS.\\r\\n");
vTaskStartScheduler();
}
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/* USER CODE BEGIN 4 */
static void AppTaskCreate(void)
{
BaseType_t xReturn = pdFAIL;
xReturn = xTaskCreate((TaskFunction_t)LedTaskCreate,
(const char *) "LEDTASKCREATE",
(uint16_t) 128,
(void*) NULL,
(UBaseType_t) 1,
(TaskHandle_t *)&LedTask_Handle);
if( xReturn == pdPASS)
f_printf("LED Task Create PASS.\\r\\n");
xReturn = xTaskCreate((TaskFunction_t)KeyTaskCreate,
(const char *) "KEYTASKCREATE",
(uint16_t ) 128,
(void *) NULL,
(UBaseType_t) 2,
(TaskHandle_t *)&KeyTask_Handle);
if( xReturn == pdPASS)
{
f_printf("KEY Task Create PASS.\\r\\n");
vTaskDelete(AppTask_Handle);
}
}
static void KeyTaskCreate(void)
{
while(1)
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
{
vTaskDelay(40);
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
{
xTaskNotifyGive(LedTask_Handle);
f_printf("LED TASK GIVE PASS.\\r\\n");
}
}
vTaskDelay(40);
}
}
static void LedTaskCreate(void)
{
uint32_t ulValue = 0 ;
while(1)
{
ulValue = ulTaskNotifyTake( pdFALSE , 0);
/*Greater than 0 proves that there is still a notification value that can be
*reduced by 1. Equal to 0 indicates that no notification is available
*/
if(ulValue >0)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);
f_printf("LED Task PASS.\\r\\n");
}
vTaskDelay(1500);
}
}
/* USER CODE END 4 */
代替事件组
在FreeRTOSConfig.h里开启任务通知
/*Turn on task notifications.*/
#define configUSE_TASK_NOTIFICATIONS 1
在main.c文件里面修改代码
/* USER CODE BEGIN Includes */
#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
static TaskHandle_t AppTask_Handle = NULL;
static TaskHandle_t KeyTask_Handle = NULL;
static TaskHandle_t LedTask_Handle = NULL;
extern int f_printf(const char *format, ...);
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
static void AppTaskCreate(void);
static void KeyTaskCreate(void);
static void LedTaskCreate(void);
/* USER CODE END PFP */
int main()
{
/* USER CODE BEGIN WHILE */
BaseType_t xReturn = pdFAIL;
xReturn = xTaskCreate((TaskFunction_t)AppTaskCreate,
(const char *) "",
(uint16_t) 128,
(void *) NULL,
(UBaseType_t) 1,
(TaskHandle_t *)&AppTask_Handle);
if( xReturn == pdPASS)
{
f_printf("APP Task Start.\\r\\n");
vTaskStartScheduler();
}
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/* USER CODE BEGIN 4 */
static void AppTaskCreate(void)
{
BaseType_t xReturn = pdFAIL;
xReturn = xTaskCreate((TaskFunction_t)LedTaskCreate,
(const char *) "",
(uint16_t) 128,
(void *) NULL,
(UBaseType_t) 1,
(TaskHandle_t*) &LedTask_Handle);
if( xReturn == pdPASS)
f_printf("LED TASK PASS.\\r\\n");
xReturn = xTaskCreate((TaskFunction_t)KeyTaskCreate,
(const char *) "",
(uint16_t ) 128,
(void *) NULL,
(UBaseType_t) 2,
(TaskHandle_t *) &KeyTask_Handle);
if( xReturn == pdPASS)
{
f_printf("KEY TASK PASS.\\r\\n");
vTaskDelete(AppTask_Handle);
}
}
static void KeyTaskCreate(void)
{
while(1)
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
{
vTaskDelay(40);
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
{
xTaskNotify(LedTask_Handle,0x00000001,eSetBits);
f_printf("PA0.\\r\\n");
}
}
else if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_12) == 0)
{
vTaskDelay(40);
if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_12) == 0)
{
xTaskNotify(LedTask_Handle,0x00000002,eSetBits);
f_printf("PC12.\\r\\n");
}
}
vTaskDelay(50);
}
}
static void LedTaskCreate(void)
{
uint32_t ulReturn = 0;
BaseType_t xReturn = pdFAIL;
while(1)
{
xReturn = xTaskNotifyWait( 0 , 0x00000003 , &ulReturn, portMAX_DELAY);
if(xReturn == pdTRUE)
{
if( (ulReturn & 0x1)==1)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_2);
f_printf("LED1.\\r\\n");
}
else if( (ulReturn & 0x02)==2)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);
f_printf("LED2.\\r\\n");
}
}
else
f_printf("Read Notify FAIL.\\r\\n");
vTaskDelay(1500);
}
}
/* USER CODE END 4 */
代替长度为1的消息队列
在FreeRTOSConfig.h里开启任务通知
/*Turn on task notifications.*/
#define configUSE_TASK_NOTIFICATIONS 1
在main.c文件里面修改代码
/* USER CODE BEGIN Includes */
#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
static TaskHandle_t AppTask_Handle = NULL;
static TaskHandle_t KeyTask_Handle = NULL;
static TaskHandle_t QueueTask_Handle = NULL;
static uint32_t Message = 0;
static uint32_t *printf_value=&Message;
extern int f_printf(const char *format, ...);
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
static void AppTaskCreate(void);
static void KeyTaskCreate(void);
static void QueueTaskCreate(void);
/* USER CODE END PFP */
int main()
{
/* USER CODE BEGIN WHILE */
BaseType_t xReturn = pdFAIL;
xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,
(const char *) "",
(uint16_t) 128,
(void *) NULL,
(UBaseType_t) 1,
(TaskHandle_t *) &AppTask_Handle);
if( xReturn == pdPASS)
{
f_printf("AppTask Start.\\r\\n");
vTaskStartScheduler();
}
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/* USER CODE BEGIN 4 */
static void AppTaskCreate(void)
{
BaseType_t xReturn ;
xReturn = xTaskCreate( (TaskFunction_t)QueueTaskCreate,
(const char *) "",
(uint16_t) 128,
(void *) NULL,
(UBaseType_t) 2,
(TaskHandle_t *)&QueueTask_Handle);
if( xReturn ==pdPASS )
f_printf("QueueTask Create PASS.\\r\\n");
xReturn = xTaskCreate( (TaskFunction_t)KeyTaskCreate,
(const char *) "",
(uint16_t) 128,
(void *) NULL,
(UBaseType_t) 1,
(TaskHandle_t *)&KeyTask_Handle);
if (xReturn == pdPASS)
{
f_printf("KeyTask Create PASS.\\r\\n");
vTaskDelete(AppTask_Handle);
}
}
static void KeyTaskCreate(void)
{
while(1)
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
{
vTaskDelay(80);
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
{
xTaskNotify(QueueTask_Handle, (uint32_t)Message, eSetValueWithOverwrite);
}
}
vTaskDelay(80);
}
}
static void QueueTaskCreate(void)
{
while(1)
{
/*work.*/
xTaskNotifyWait(0, 0xFFFFFFFF, printf_value, portMAX_DELAY);
f_printf("Message is :%d\\r\\n",*printf_value);
Message=*printf_value;
/*The second method works too*/
/*
xTaskNotifyWait(0, 0xFFFFFFFF, &Message, portMAX_DELAY);
f_printf("Message is :%d\\r\\n",Message);
*/
Message++;
if(Message > 10)
Message = 0;
vTaskDelay(1000);
}
}
/* USER CODE END 4 */
以上是关于STM32G0学习手册——FreeRTOS任务通知的主要内容,如果未能解决你的问题,请参考以下文章