STM32CubeIDE+FreeRTOS任務通知實驗


任務通知代替消息隊列是在 FreeRTOS 中創建了三個任務, 其中兩個任務是用於接收任務通知,另一個任務發送任務通知。三個任務獨立運行,發送消息任務是通過檢測按鍵的按下情況來發送消息通知,另兩個任務獲取消息通知,在任務通知中沒有可用的通知之前就一直等待消息,一旦獲取到消息通知就把消息打印輸出  

創建工程RTOS_TaskNotify,

配置HCLK,使用內部晶振,頻率為180MHZ(根據板子設置)

 

 

將SYS中時基源(Timebase Source)改為除SysTick之外的任意定時器即可,如:

配置板載的按鍵KEY1和KEY2

 

 

配置FreeRTOS,使用CMSIS_V1,

 

 定義三個任務,SendTask、ReceiveTask01和ReceiveTask02

  

 

 

Ctrl + S生成代碼

修改代碼,

1,在main.h中添加

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

2,在mian.c中添加

/* USER CODE BEGIN PFP */
int _write(int file , char *ptr,int len)
{
    int i = 0;
    for(i = 0;i<len;i++)
        ITM_SendChar((*ptr++));
    return len;
}
/* USER CODE END PFP */
...
...
...
/* USER CODE BEGIN 2 */
  printf("starting...\n");
/* USER CODE END 2 */

3,在main.c中修改3個任務入口函數的內容

 

/* USER CODE BEGIN Header_StartSendTask */
/**
  * @brief  Function implementing the SendTask thread.
  * @param  argument: Not used 
  * @retval None
  */
/* USER CODE END Header_StartSendTask */
void StartSendTask(void const * argument)
{
  /* USER CODE BEGIN 5 */
    BaseType_t xReturn = pdPASS;/* 定義一個創建信息返回值,默認為 pdPASS */
    char test_str1[] = "this is a mail test 1";/* 消息 test1 */
    char test_str2[] = "this is a mail test 2";/* 消息 test2 */
  /* Infinite loop */
  for(;;)
  {
      if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1)
      {
          osDelay(5);
          if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1)
          {
              while(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1);
              xReturn = xTaskNotify(ReceiveTask01Handle,
                                              (uint32_t)test_str1,
                                      eSetValueWithOverwrite);
              if(xReturn == pdPASS)
                  printf("ReceiveTask01_Handle Mission notification release successful!!!\n");
          }
      }
      if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1)
      {
          osDelay(5);
          if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1)
          {
              while(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1);
              xReturn = xTaskNotify(ReceiveTask02Handle,
                                              (uint32_t)test_str2,
                                      eSetValueWithOverwrite);
              if(xReturn == pdPASS)
                  printf("ReceiveTask02_Handle Mission notification release successful!!!\n");
          }
      }
      osDelay(10);
  }
  /* USER CODE END 5 */ 
}
/* USER CODE BEGIN Header_StartReceiveTask01 */
/**
* @brief Function implementing the ReceiveTask01 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartReceiveTask01 */
void StartReceiveTask01(void const * argument)
{
  /* USER CODE BEGIN StartReceiveTask01 */
    BaseType_t xReturn = pdTRUE;/* 定義一個創建信息返回值,默認為 pdPASS */
    char *r_char;
  /* Infinite loop */
  for(;;)
  {
      //獲取任務通知 ,沒獲取到則一直等待
      xReturn=xTaskNotifyWait(0x0,
                                      UINT8_MAX,
                              (uint32_t *)&r_char,
                              osWaitForever);
      if(xReturn == pdTRUE)
          printf("ReceiveTask01 received %s\n",r_char);
  }
  /* USER CODE END StartReceiveTask01 */
}
/* USER CODE BEGIN Header_StartReceiveTask02 */
/**
* @brief Function implementing the ReceiveTask02 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartReceiveTask02 */
void StartReceiveTask02(void const * argument)
{
  /* USER CODE BEGIN StartReceiveTask02 */
    BaseType_t xReturn = pdTRUE;/* 定義一個創建信息返回值,默認為 pdPASS */
    char *r_char;
  /* Infinite loop */
  for(;;)
  {
      //獲取任務通知 ,沒獲取到則一直等待
      xReturn=xTaskNotifyWait(0x0,
                                      UINT8_MAX,
                              (uint32_t *)&r_char,
                              osWaitForever);
      if(xReturn == pdTRUE)
          printf("ReceiveTask02 received %s\n",r_char);
  }
  /* USER CODE END StartReceiveTask02 */
}

修改完畢后點擊 小錘子 構建工程,然后點擊Debug,按如下步驟配置ITM調試

 

 

 

 全速運行之前一定要先點擊SWV ITM data Console 頁面中的紅色圓圈

 

現象:

分析:SendTask檢測按鍵,KEY1按下,向ReceiveTask01Handle發送任務通知;KEY2按下,向ReceiveTask02Handle發送任務通知。

ReceiveTask01獲取任務通知 ,沒獲取到則一直等待,獲取到之后打印提示信息和消息內容。

ReceiveTask02獲取任務通知 ,沒獲取到則一直等待,獲取到之后打印提示信息和消息內容。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM