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获取任务通知 ,没获取到则一直等待,获取到之后打印提示信息和消息内容。

 

 

posted @ 2019-12-12 15:15  飞起的小田  阅读(1825)  评论(0编辑  收藏  举报