502398542 发表于 2019-3-18 10:53:24

消息队列问题

串口接收大量数据,使用xQueueSendFromISR(xMessageBufferData,(void *)&byte_temp,&xHigherPriorityTaskWoken)

放入队列
一个任务使用xQueueReceive(xMessageBufferData,(void *)&byte_temp,portMAX_DELAY)取出数据

程序运行一段时间后,队列满了,(使用xQueueIsQueueFullFromISR(xMessageBufferData)和uxQueueSpacesAvailable( xMessageBufferData )查看),此时即使不再给串口发数据,队列依然是满的,也就是说,队列满一次之后,就再也无法接收新的数据了,此时程序的其他任务都能正常运行

尝试加大队列的大小,此问题依然出现,只是出现的时间长一点

请问有人遇到这种问题吗,怎么解决的?

502398542 发表于 2019-3-18 10:55:30

怀疑是xQueueReceive(xMessageBufferData,(void *)&byte_temp,portMAX_DELAY)任务不运行造成的,但是这个任务最开始是可以正常运行的,中间也没有进行过挂起或删除之类的操作

byccc 发表于 2019-3-18 11:20:42

中断消息触发的任务,要设置为高优先级才行,否则中断触发已经没有价值,还不如查询。

502398542 发表于 2019-3-18 11:22:31

byccc 发表于 2019-3-18 11:20
中断消息触发的任务,要设置为高优先级才行,否则中断触发已经没有价值,还不如查询。

恩,xQueueReceive(xMessageBufferData,(void *)&byte_temp,portMAX_DELAY)任务已经是最高优先级

502398542 发表于 2019-3-18 11:46:07

翻前面的帖子,发现我的问题和这个很相似http://www.armbbs.cn/forum.php?mod=viewthread&tid=14848&extra=page%3D1
但是没有给出解决方法

eric2013 发表于 2019-3-18 11:51:03

502398542 发表于 2019-3-18 11:46
翻前面的帖子,发现我的问题和这个很相似http://www.armbbs.cn/forum.php?mod=viewthread&tid=14848&ext ...

每次发送的是多少字节,中断频率是多少。

先判断xQueueIsQueueFullFromISR,再发

502398542 发表于 2019-3-18 12:09:38

eric2013 发表于 2019-3-18 11:51
每次发送的是多少字节,中断频率是多少。

先判断xQueueIsQueueFullFromISR,再发


1.发送的字节数和频率不固定,但是数据量很大,中断也很频繁

2.已经判断了xQueueIsQueueFullFromISR,如果队列满就直接抛弃数据了,但仍然是上面的现象,就是xQueueReceive任务进不去了,队列一直满着

502398542 发表于 2019-3-18 12:14:40

根据网上查的资料,在串口中断中加入了如下函数
                if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET) // 检查 ORE 标志
                {
                                USART_ReceiveData(USART1);
                                USART_ClearFlag(USART1,USART_FLAG_ORE);      
                }

eric2013 发表于 2019-3-18 12:19:25

502398542 发表于 2019-3-18 12:14
根据网上查的资料,在串口中断中加入了如下函数
                if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET ...
ORE的清除,直接读取SR,然后DR已经自动清除。


502398542 发表于 2019-3-18 12:23:02

eric2013 发表于 2019-3-18 12:19
ORE的清除,直接读取SR,然后DR已经自动清除。

是的,加入了这断ORE的代码之后,对上述问题并没有什么作用
现在问题归结于xQueueReceive任务运行一段时间后就无法运行了,此时队列中是有消息的

eric2013 发表于 2019-3-18 12:26:49

你这个参数是不是填错了

eric2013 发表于 2019-3-18 12:35:18

502398542 发表于 2019-3-18 12:23
是的,加入了这断ORE的代码之后,对上述问题并没有什么作用
现在问题归结于xQueueReceive任务运行一段时 ...

改了,不用消息队列了,仅仅发送个信号量的消息通知,试试,如果这都有问题,那程序估计设置的有问题了。

ps:FreeRTOS信号量也是基于消息队列实现的。

502398542 发表于 2019-3-18 14:06:51

eric2013 发表于 2019-3-18 12:35
改了,不用消息队列了,仅仅发送个信号量的消息通知,试试,如果这都有问题,那程序估计设置的有问题了。 ...

程序改为,串口收到数据放到自己写的缓存里,通过vTaskNotifyGiveFromISR通知任务处理数据,运行一段时间后,中断中发出通知,但是数据处理任务ulTaskNotifyTake接不到,现象类似于xQueueReceive

不管哪种方式,如果在数据处理任务中加入一个延时vTaskDelay(2),问题就解决了,但这个解决办法影响了数据的实时性

还需要继续找问题原因

eric2013 发表于 2019-3-18 15:13:47

502398542 发表于 2019-3-18 14:06
程序改为,串口收到数据放到自己写的缓存里,通过vTaskNotifyGiveFromISR通知任务处理数据,运行一段时间 ...

最后还有个事情,你的NVIC优先级是设置为4吧,最好搞成4,然后将串口中断服务程序的优先级设置为FreeRTOS受管理的中断里面最高的。

502398542 发表于 2019-3-18 16:24:50

eric2013 发表于 2019-3-18 15:13
最后还有个事情,你的NVIC优先级是设置为4吧,最好搞成4,然后将串口中断服务程序的优先级设置为FreeRTOS ...

我正在看中断这块,有点疑问
nvic设置是4
串口中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY                        0xf
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY        1
#define configKERNEL_INTERRUPT_PRIORITY                 ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY <<4)
#define configMAX_SYSCALL_INTERRUPT_PRIORITY         ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << 4 )

请问这样配置,可以安全的在中断函数里调用freertos的API吗

eric2013 发表于 2019-3-18 16:35:33

502398542 发表于 2019-3-18 16:24
我正在看中断这块,有点疑问
nvic设置是4
串口中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPrior ...

那没问题了。

502398542 发表于 2019-3-18 16:41:38

本帖最后由 502398542 于 2019-3-18 16:45 编辑

eric2013 发表于 2019-3-18 16:35
那没问题了。
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY                        0xf
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY      1

根据配置优先级1-15可以受freertos管理,我的串口优先级显示是16,不受管理?如果我理解的不对,请问这样配置,哪些优先级的中断是受管理的?
在当前 配置下,程序正常跑,一旦收到串口数据,停在configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );



502398542 发表于 2019-3-18 17:00:58

eric2013 发表于 2019-3-18 16:35
那没问题了。

不好意思,看错了,configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );是由于别的中断配置错误引起的

eric2013 发表于 2019-3-19 02:28:13

502398542 发表于 2019-3-18 17:00
不好意思,看错了,configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );是由于别的中断配置错误 ...

好的,那看来是其它问题导致的了。

brightzeng 发表于 2019-5-14 09:59:36

我也遇到了同样的问题,使用队列在串口中断中发送数据,然后创建了一个任务接收。一开始是可以的,但是运行一段时间后(时间不定),只要是队列满了以后接收任务就停掉了。我调试了很久了,监控过数据队列状态,发现是队列一满,接收任务进入了就绪态,但是已经回不去了。 不知道是解决? 还请硬汉兄指教!感谢!

brightzeng 发表于 2019-5-14 19:31:04

已经解决了,是我内部函数造成的问题,不是队列引发的。{:16:}

eric2013 发表于 2019-5-15 00:20:03

brightzeng 发表于 2019-5-14 19:31
已经解决了,是我内部函数造成的问题,不是队列引发的。

非常抱歉,没有及时回复你:handshake

yydongfang 发表于 2020-11-25 15:59:09

解决了吗碰到一样的问题
页: [1]
查看完整版本: 消息队列问题