502398542 发表于 2019-6-25 11:27:45

串口中断溢出

stm32f1串口接收中断程序,波特率115200,优先级在所有外设中断中最高,进入中断后只把接到的数据放入队列(队列足够大),退出中断
接收大量数据时,偶尔会发生丢数情况,丢数时会先触发串口溢出中断,
将波特率改为38400,问题解决
这么说,把串口收到的数据放入队列所需的时间很长吗?这个时间会导致115200波特率的情况下串口中断溢出?

eric2013 发表于 2019-6-25 12:06:49

FreeRTOS的消息队列是数据的复制粘贴,你每次发多少数据。

502398542 发表于 2019-6-25 12:41:37

eric2013 发表于 2019-6-25 12:06
FreeRTOS的消息队列是数据的复制粘贴,你每次发多少数据。

每次大概要收几千个字节,降低波特率可以解决问题,我打算再试试不用队列直接用数组,或者dma方式,能不能不丢数

502398542 发表于 2019-6-25 12:44:11

串口中断代码如下
void USART1_IRQHandler(void)
{
        u8 byte_temp = 0;
        BaseType_t xHigherPriorityTaskWoken = pdFALSE; /* Initialised to pdFALSE. */
        if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET) // 检查 ORE 标志
        {
                        USART_ReceiveData(USART1);
                        USART_ClearFlag(USART1,USART_FLAG_ORE);      
        }
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收到数据          
        {       
                USART_ClearITPendingBit(USART1, USART_IT_RXNE);
                byte_temp = USART_ReceiveData(USART1);

                        if (xQueueIsQueueFullFromISR(xMessageBufferM2900Data) == pdFALSE)       
                        {               
                                xQueueSendFromISR(xMessageBufferM2900Data, (void *)&byte_temp, &xHigherPriorityTaskWoken);
                                portYIELD_FROM_ISR(xHigherPriorityTaskWoken);               
                        }
               
        }               
}

eric2013 发表于 2019-6-25 13:59:58

502398542 发表于 2019-6-25 12:44
串口中断代码如下
void USART1_IRQHandler(void)
{


你这个每次发1个字节,完全无压力的。

我看下你的freertos创建,每个单元的大小是多少

502398542 发表于 2019-6-25 14:46:01

eric2013 发表于 2019-6-25 13:59
你这个每次发1个字节,完全无压力的。

我看下你的freertos创建,每个单元的大小是多少

任务和队列创建在文件里

eric2013 发表于 2019-6-25 15:19:29

502398542 发表于 2019-6-25 14:46
任务和队列创建在文件里

是这个吧
xMessageBufferM2900Data = xQueueCreate(200, sizeof(u8));

按说完全没问题的,你每次发发送了一个数据。

502398542 发表于 2019-6-25 15:32:45

eric2013 发表于 2019-6-25 15:19
是这个吧
xMessageBufferM2900Data = xQueueCreate(200, sizeof(u8));



是这个,我在很多地方用uxQueueSpacesAvailable测试过队列空间,没有溢出
我的测试方法是,在中断里放一个大数组,收到就放数组里,在硬件上接一个串口转usb到电脑上监测,偶尔出现中断数组里的数比电脑监测的少一个,引起这个问题的原因就是串口溢出中断被触发了一次,只有降低波特率才不会触发溢出中断
下图是中断优先级的截图

eric2013 发表于 2019-6-26 09:12:11

502398542 发表于 2019-6-25 15:32
是这个,我在很多地方用uxQueueSpacesAvailable测试过队列空间,没有溢出
我的测试方法是,在中断里放一 ...

这里我们简单换算下,比如你的波特率是115200,那么串口接收中断的大约频率就是115200/8 = 14KHz,

对于F1系列来说,这个频率还是略高的。然后你测试下你的串口中断服务程序执行一次需要多少时间。

502398542 发表于 2019-6-26 14:15:29

eric2013 发表于 2019-6-26 09:12
这里我们简单换算下,比如你的波特率是115200,那么串口接收中断的大约频率就是115200/8 = 14KHz,

对 ...

好像也说不通,如果串口接收中断频率是14khz,每次进中断就是71.4us,
串口中断程序运行时间实测大概1.8us,按照这个结果是不会溢出的

502398542 发表于 2019-6-26 14:18:46

eric2013 发表于 2019-6-26 09:12
这里我们简单换算下,比如你的波特率是115200,那么串口接收中断的大约频率就是115200/8 = 14KHz,

对 ...

也可能在某种特定情况下串口中断服务程序耗时会比较长,发生溢出,但是这就不好抓了

eric2013 发表于 2019-6-27 09:04:55

502398542 发表于 2019-6-26 14:18
也可能在某种特定情况下串口中断服务程序耗时会比较长,发生溢出,但是这就不好抓了

这样的话就只能老办法了,仅创建一个串口中断和串口消息处理任务排查了。

502398542 发表于 2019-6-27 11:26:51

eric2013 发表于 2019-6-27 09:04
这样的话就只能老办法了,仅创建一个串口中断和串口消息处理任务排查了。

有没有什么办法,可以在串口中断执行程序中加一个计数器或定时器,如果串口中断执行时间比平时长,就能通过这个计数器的值看到了(串口中断优先级最高的情况下)

eric2013 发表于 2019-6-28 08:52:27

502398542 发表于 2019-6-27 11:26
有没有什么办法,可以在串口中断执行程序中加一个计数器或定时器,如果串口中断执行时间比平时长,就能通 ...

进入后可以开一个抢占优先级比串口搞的定时器。定一个时间。

502398542 发表于 2019-6-28 09:14:15

eric2013 发表于 2019-6-28 08:52
进入后可以开一个抢占优先级比串口搞的定时器。定一个时间。

嗯,我试试,多谢
页: [1]
查看完整版本: 串口中断溢出