硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2846|回复: 14
收起左侧

[FreeRTOS] 串口中断溢出

[复制链接]

20

主题

72

回帖

132

积分

初级会员

积分
132
发表于 2019-6-25 11:27:45 | 显示全部楼层 |阅读模式
stm32f1串口接收中断程序,波特率115200,优先级在所有外设中断中最高,进入中断后只把接到的数据放入队列(队列足够大),退出中断
接收大量数据时,偶尔会发生丢数情况,丢数时会先触发串口溢出中断,
将波特率改为38400,问题解决
这么说,把串口收到的数据放入队列所需的时间很长吗?这个时间会导致115200波特率的情况下串口中断溢出?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2019-6-25 12:06:49 | 显示全部楼层
FreeRTOS的消息队列是数据的复制粘贴,你每次发多少数据。
回复

使用道具 举报

20

主题

72

回帖

132

积分

初级会员

积分
132
 楼主| 发表于 2019-6-25 12:41:37 | 显示全部楼层
eric2013 发表于 2019-6-25 12:06
FreeRTOS的消息队列是数据的复制粘贴,你每次发多少数据。

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

使用道具 举报

20

主题

72

回帖

132

积分

初级会员

积分
132
 楼主| 发表于 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);               
                        }
               
        }               
}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2019-6-25 13:59:58 | 显示全部楼层
502398542 发表于 2019-6-25 12:44
串口中断代码如下
void USART1_IRQHandler(void)
{

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

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

使用道具 举报

20

主题

72

回帖

132

积分

初级会员

积分
132
 楼主| 发表于 2019-6-25 14:46:01 | 显示全部楼层
eric2013 发表于 2019-6-25 13:59
你这个每次发1个字节,完全无压力的。

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

任务和队列创建在文件里

main.c

37.6 KB, 下载次数: 8

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2019-6-25 15:19:29 | 显示全部楼层
502398542 发表于 2019-6-25 14:46
任务和队列创建在文件里

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

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

使用道具 举报

20

主题

72

回帖

132

积分

初级会员

积分
132
 楼主| 发表于 2019-6-25 15:32:45 | 显示全部楼层
eric2013 发表于 2019-6-25 15:19
是这个吧
xMessageBufferM2900Data = xQueueCreate(200, sizeof(u8));

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

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2019-6-26 09:12:11 | 显示全部楼层
502398542 发表于 2019-6-25 15:32
是这个,我在很多地方用uxQueueSpacesAvailable测试过队列空间,没有溢出
我的测试方法是,在中断里放一 ...

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

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

回复

使用道具 举报

20

主题

72

回帖

132

积分

初级会员

积分
132
 楼主| 发表于 2019-6-26 14:15:29 | 显示全部楼层
eric2013 发表于 2019-6-26 09:12
这里我们简单换算下,比如你的波特率是115200,那么串口接收中断的大约频率就是115200/8 = 14KHz,

对 ...

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

使用道具 举报

20

主题

72

回帖

132

积分

初级会员

积分
132
 楼主| 发表于 2019-6-26 14:18:46 | 显示全部楼层
eric2013 发表于 2019-6-26 09:12
这里我们简单换算下,比如你的波特率是115200,那么串口接收中断的大约频率就是115200/8 = 14KHz,

对 ...

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

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2019-6-27 09:04:55 | 显示全部楼层
502398542 发表于 2019-6-26 14:18
也可能在某种特定情况下串口中断服务程序耗时会比较长,发生溢出,但是这就不好抓了

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

使用道具 举报

20

主题

72

回帖

132

积分

初级会员

积分
132
 楼主| 发表于 2019-6-27 11:26:51 | 显示全部楼层
eric2013 发表于 2019-6-27 09:04
这样的话就只能老办法了,仅创建一个串口中断和串口消息处理任务排查了。

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

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2019-6-28 08:52:27 | 显示全部楼层
502398542 发表于 2019-6-27 11:26
有没有什么办法,可以在串口中断执行程序中加一个计数器或定时器,如果串口中断执行时间比平时长,就能通 ...

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

使用道具 举报

20

主题

72

回帖

132

积分

初级会员

积分
132
 楼主| 发表于 2019-6-28 09:14:15 | 显示全部楼层
eric2013 发表于 2019-6-28 08:52
进入后可以开一个抢占优先级比串口搞的定时器。定一个时间。

嗯,我试试,多谢
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-28 13:41 , Processed in 0.336780 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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