• 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...
    ");
    /* 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!!!
    ");
              }
          }
          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!!!
    ");
              }
          }
          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
    ",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
    ",r_char);
      }
      /* USER CODE END StartReceiveTask02 */
    }

    修改完毕后点击 小锤子 构建工程,然后点击Debug,按如下步骤配置ITM调试

     

     全速运行之前一定要先点击SWV ITM data Console 页面中的红色圆圈

    现象:

    分析:SendTask检测按键,KEY1按下,向ReceiveTask01Handle发送任务通知;KEY2按下,向ReceiveTask02Handle发送任务通知。

    ReceiveTask01获取任务通知 ,没获取到则一直等待,获取到之后打印提示信息和消息内容。

    ReceiveTask02获取任务通知 ,没获取到则一直等待,获取到之后打印提示信息和消息内容。

  • 相关阅读:
    AES算法,DES算法,RSA算法JAVA实现
    spring官方学习地址
    逐步理解SpringMVC
    sublime前端开发工具常用技巧
    谈谈关键字new
    关于mybatisgenerator的问题
    AOPjdk动态代理的思考
    关于java解析xml文件出现的问题
    Java注解
    git向码云上传代码总结
  • 原文地址:https://www.cnblogs.com/tianxxl/p/12029350.html
Copyright © 2020-2023  润新知