STM32G0学习手册——FreeRTOS任务通知

Posted SCCELE

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32G0学习手册——FreeRTOS任务通知相关的知识,希望对你有一定的参考价值。

目录

概述

代替二值信号量

 代替计数信号量

代替事件组

代替长度为1的消息队列


概述

        每个任务都有一个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任务通知的主要内容,如果未能解决你的问题,请参考以下文章

STM32G0学习手册——FreeRTOS任务通知

STM32G0学习手册——FreeRTOS消息队列

STM32G0学习手册——FreeRTOS消息队列

STM32G0学习手册——FreeRTOS消息队列

STM32G0学习手册——FreeRTOS事件组

STM32G0学习手册——FreeRTOS事件组