OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4653|回复: 11

FreeRTOS无法多个任务获取同一消息队列

[复制链接]

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2020-2-24
在线时间
21 小时
发表于 2022-12-6 20:47:08 | 显示全部楼层 |阅读模式
5金钱
在Freertos中设置三个任务,一个是读取传感器并将数据放入消息队列,另外两个读取消息队列。在读取队列的两个任务中,只有优先级较高的任务可以正常读取,打印出来看到传感器数据在不断变化,另外一个较低优先级的只能读取一次,可以不停地打印出来,但是数据不变化。只保留一个读取任务的时候一切正常,无论保留的是高优先级的还是低优先级的。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2022-12-7 09:00:29 | 显示全部楼层
一、消息队列不支持:一对多和多对多。
               1、不支持:一对多
                               例如:   任务F给任务A发送按键码。
                                          任务F给任务B发送按键码。
                                          任务F给任务C发送按键码。
               2、不支持:多对多
                                例如:   任务F给任务A发送按键码。
                                          任务F务给任务B发送按键码。
                                          任务Z任务给任务A发送按键码。   


二、消息队列只支持一对一或者多对一


兄弟,看看别人的通信程序设计。


回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2022-12-7 09:05:56 | 显示全部楼层
你要么把两个读取传感器数据的任务合并成一个任务,要么在读取传感器数据的任务1中再发送消息队列给读取传感器数据的任务2.


   总之,不能将传感器任务采集的数据既通过消息队列传输给任务1,又传输给任务2,这不符合FreeRTOS消息队列的要求。
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2022-12-7 17:59:11 | 显示全部楼层
本帖最后由 nashui_sx 于 2022-12-7 18:12 编辑
霸王猫 发表于 2022-12-7 09:00
一、消息队列不支持:一对多和多对多。
               1、不支持:一对多
                             ...

都支持的这是毋庸置疑的,不然要队列有何用 一对一直接全部变量不妥了
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2022-12-7 18:01:40 | 显示全部楼层
111111.jpg
  1. #include "Temp1_Task.h"

  2. void                Temp1_Task(void *pvParameters);                            //任务函数
  3. #define             Temp1_Task_Size                                (100)//任务堆栈大小       
  4. #define             Temp1_Task_Prio                                                      1//任务优先级
  5. TaskHandle_t        Temp1_Task_Handler;                                        //任务句柄

  6. QueueHandle_t       Test_Queue_Handler;                                               //消息队列句柄
  7. #define             Test_Queue_Handler_Num                                          100//消息队列的长度
  8. #define             Test_Queue_Handler_Len                                     1//消息队列的字节数 byte

  9. void Temp1_Task_Start(void)
  10. {
  11.     BaseType_t xReturn;
  12.         Test_Queue_Handler=xQueueCreate(Test_Queue_Handler_Num,Test_Queue_Handler_Len);
  13.         xReturn=xTaskCreate((TaskFunction_t )Temp1_Task,     
  14.                         (const char*    )"Temp1_Task",   
  15.                         (uint16_t       )Temp1_Task_Size,
  16.                         (void*          )NULL,
  17.                         (UBaseType_t    )Temp1_Task_Prio,
  18.                         (TaskHandle_t*  )&Temp1_Task_Handler);
  19.     if(xReturn==pdPASS)
  20.     {
  21.         FreeRtos_printf("Success Create Temp1_Task ...\r\n");
  22.     }
  23.     else
  24.     {
  25.         FreeRtos_printf("Failure Create Temp1_Task ...\r\n");
  26.         while(1){};        
  27.     }                  
  28. }

  29. void Temp1_Task(void *pvParameters)
  30. {         
  31.     TickType_t xLastWakeTime          = xTaskGetTickCount();
  32.         u8 haha=0;
  33.         BaseType_t err;
  34.         while(1)
  35.         {
  36.                 if(Test_Queue_Handler!=NULL)
  37.                 {
  38.                         err=xQueueSend(Test_Queue_Handler,(const void * const)&haha,( TickType_t ) 0);
  39.                         FreeRtos_printf("Temp1_Task=%d\r\n",haha);
  40.                         haha++;
  41.                 }
  42.                          
  43.         vTaskDelayUntil(&xLastWakeTime,100);//vTaskDelay(1000);
  44.         }
  45. }
复制代码
  1. #include "Temp2_Task.h"

  2. void                Temp2_Task(void *pvParameters);                            //任务函数
  3. #define             Temp2_Task_Size                                (100)//任务堆栈大小       
  4. #define             Temp2_Task_Prio                                                      1//任务优先级
  5. TaskHandle_t        Temp2_Task_Handler;                                        //任务句柄

  6. void Temp2_Task_Start(void)
  7. {
  8.     BaseType_t xReturn;
  9.    
  10.         xReturn=xTaskCreate((TaskFunction_t )Temp2_Task,     
  11.                         (const char*    )"Temp2_Task",   
  12.                         (uint16_t       )Temp2_Task_Size,
  13.                         (void*          )NULL,
  14.                         (UBaseType_t    )Temp2_Task_Prio,
  15.                         (TaskHandle_t*  )&Temp2_Task_Handler);       
  16.     if(xReturn==pdPASS)
  17.     {
  18.         FreeRtos_printf("Success Create Temp2_Task ...\r\n");
  19.     }
  20.     else
  21.     {
  22.         FreeRtos_printf("Failure Create Temp2_Task ...\r\n");
  23.         while(1){};        
  24.     }                  
  25. }
  26. extern QueueHandle_t       Test_Queue_Handler;
  27. void Temp2_Task(void *pvParameters)
  28. {         
  29.         BaseType_t err;
  30.         u8 key=0;

  31.     while(1)
  32.     {
  33.                 if(Test_Queue_Handler!=NULL)
  34.                 {
  35.                         err=xQueueReceive(Test_Queue_Handler,&key,portMAX_DELAY);
  36.             if(err==pdTRUE)
  37.             {
  38.                 FreeRtos_printf("Temp2_Task=%d\r\n",key);
  39.             }
  40.                 }

  41.         vTaskDelay(1000);//vTaskDelay(1000)
  42.         }
  43. }

复制代码
  1. #include "Temp3_Task.h"

  2. void                Temp3_Task(void *pvParameters);                            //任务函数
  3. #define             Temp3_Task_Size                                (100)//任务堆栈大小       
  4. #define             Temp3_Task_Prio                                                      1//任务优先级
  5. TaskHandle_t        Temp3_Task_Handler;                                        //任务句柄

  6. void Temp3_Task_Start(void)
  7. {
  8.     BaseType_t xReturn;
  9.    
  10.         xReturn=xTaskCreate((TaskFunction_t )Temp3_Task,     
  11.                         (const char*    )"Temp3_Task",   
  12.                         (uint16_t       )Temp3_Task_Size,
  13.                         (void*          )NULL,
  14.                         (UBaseType_t    )Temp3_Task_Prio,
  15.                         (TaskHandle_t*  )&Temp3_Task_Handler);
  16.     if(xReturn==pdPASS)
  17.     {
  18.         FreeRtos_printf("Success Create Temp3_Task ...\r\n");
  19.     }
  20.     else
  21.     {
  22.         FreeRtos_printf("Failure Create Temp3_Task ...\r\n");
  23.         while(1){};        
  24.     }                  
  25. }

  26. extern QueueHandle_t       Test_Queue_Handler;
  27. void Temp3_Task(void *pvParameters)
  28. {         
  29.         BaseType_t err;
  30.         u8 key=0;

  31.     while(1)
  32.     {
  33.                 if(Test_Queue_Handler!=NULL)
  34.                 {
  35.                         err=xQueueReceive(Test_Queue_Handler,&key,portMAX_DELAY);
  36.             if(err==pdTRUE)
  37.             {
  38.                 FreeRtos_printf("Temp3_Task=%d\r\n",key);
  39.             }
  40.                 }

  41.         vTaskDelay(1000);//vTaskDelay(1000)
  42.         }
  43. }
复制代码


回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2022-12-7 18:05:23 | 显示全部楼层
你这种情况可能是队列发送的慢  两个等着获取 只能高优先级获取到    你尝试该下代码发快点 都获取慢点应该就好了或者获取的任务一样优先级 时间片轮换就能依次获取了
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2022-12-7 18:10:45 | 显示全部楼层
本帖最后由 nashui_sx 于 2022-12-7 18:12 编辑

给你验证了下刚才的代码
任务1:vTaskDelayUntil(&xLastWakeTime,2000);//vTaskDelay(1000);
任务2:不变
任务3:提高优先级#define             Temp3_Task_Prio                                                      5//任务优先级

22222.jpg

回复

使用道具 举报

0

主题

451

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3316
金钱
3316
注册时间
2016-3-19
在线时间
815 小时
发表于 2023-3-30 11:52:41 | 显示全部楼层
nashui_sx 发表于 2022-12-7 18:10
给你验证了下刚才的代码
任务1:vTaskDelayUntil(&xLastWakeTime,2000);//vTaskDelay(1000);
任务2:不变 ...

如果发送的快  接收的慢   程序运行一段时间后  是不是就会出现发送数据丢失的情况?

理论上都支持  是不是实际使用过程中要慎重使用啊?

感觉还是得结合实际功能选择一种适合的方式

Nothing is impossible
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2023-3-30 12:53:25 | 显示全部楼层
unnormal 发表于 2023-3-30 11:52
如果发送的快  接收的慢   程序运行一段时间后  是不是就会出现发送数据丢失的情况?

理论上都支持   ...

是的 发送得快处理的慢一会队列满了 入队失败
回复

使用道具 举报

0

主题

451

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3316
金钱
3316
注册时间
2016-3-19
在线时间
815 小时
发表于 2023-3-30 13:36:47 | 显示全部楼层
nashui_sx 发表于 2023-3-30 12:53
是的 发送得快处理的慢一会队列满了 入队失败

好的   谢谢您的解答
Nothing is impossible
回复

使用道具 举报

0

主题

11

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
348
金钱
348
注册时间
2013-11-27
在线时间
47 小时
发表于 2023-5-8 15:00:55 | 显示全部楼层
xQueuePeek,只接收,不删除。
回复

使用道具 举报

0

主题

451

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3316
金钱
3316
注册时间
2016-3-19
在线时间
815 小时
发表于 2023-5-10 08:27:00 | 显示全部楼层
longdeng84 发表于 2023-5-8 15:00
xQueuePeek,只接收,不删除。

发送队列采用 xQueueOverwrite

xQueuePeek   尽量采用 portMAX_DELAY
Nothing is impossible
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 17:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表