OpenEdv-开源电子网

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

难题!!!处理连续不断的串口数据,如何提高系统实时性?

[复制链接]

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
发表于 2016-9-3 13:16:39 | 显示全部楼层 |阅读模式
100金钱
开发板:stm32F103战舰
实验内容:串口以115200波特率被动接收外部数据源,实现对数据解析储存到SD和SD卡数据gprs发送
构架:串口采用DMA接收数据,内建环形缓冲队列
环形缓冲队列参数:写指针  读指针  有效数据量
方案1:在DMA传输完成中断中使用双直线缓冲A&B,当A满后DMA目标地址切换到B,并且发送A满信号量给任务A(将直线缓冲A中的数据写到环形队列中),
           由此实现乒乓缓冲
方案2:DMA目标地址设置为环形队列首地址,当环形队列满后再重新设置为首地址

方案分析:方案1中双直线缓冲的大小与实时性时矛盾的,假如此时串口只接收到一条数据,系统并不能处理它只有等该数据所在的直线缓冲满后才能处理,
               其次双缓冲频繁切换可能会造成数据丢失
               方案2中对环形队列的写指针和有效数据量不好管理,由于缓行缓冲比较大所以切换频率会比方案1小很多

任务构架:任务1:解析环形缓冲中的数据并存储(SDIO+DMA)到sd卡中
               任务2:读取sd卡中的数据通过gprs发送至服务器
               任务3:刷新屏幕任务
               任务4:系统参数配置任务

目前主要的问题:任务1中环形缓冲中的有效数据不能及时处理完,未处理的数据会被新来的数据覆盖掉
                        其次由于任务1目前发生的状况任务2、3可能无法具有实时性,数据会一直积压在本地无法发送出去,只有等数据处理完才能执行

不知谁有过类似的经验处理此类问题,当前串口波特率115200,数据源是源源不断得发送数据过来

有兴趣或经验的朋友欢迎前来探讨

我是一只菜鸟,但我会大鹏展翅
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
发表于 2016-9-3 14:24:25 | 显示全部楼层
你就开一块缓存,平时存起来,定时进来读不行么?看你的意思数据量好像也不大,只不过是源源不断。
自在随心
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-3 14:57:39 | 显示全部楼层
yuzeyuan1 发表于 2016-9-3 14:24
你就开一块缓存,平时存起来,定时进来读不行么?看你的意思数据量好像也不大,只不过是源源不断。

1s过来1万个字节,我每次进去读得越多处理时间就需要越久
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
发表于 2016-9-3 15:03:45 | 显示全部楼层
战舰水手 发表于 2016-9-3 14:57
1s过来1万个字节,我每次进去读得越多处理时间就需要越久

我想简单了。
任务1、2、3都不是什么好惹的货色,哪一个都要占不少时间。不能分开执行么,干完1再干2、3
自在随心
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2016-9-3 20:12:54 | 显示全部楼层
战舰水手 发表于 2016-9-3 14:57
1s过来1万个字节,我每次进去读得越多处理时间就需要越久

1w字节=10KB
SD卡写入速度一般是远远大于10KB/S的.

环形队列,应该可以解决你的问题啊.

队列单个大小设置为2K字节,  大小为10个.
这样可以缓存20K字节,也就是2秒钟的数据.

然后写SD卡的时候,每次写入1个队列单位(2K字节),这样不应该会有队列全满的情况存在!
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2016-9-3 20:14:41 | 显示全部楼层
另外,必须是方案2.
环形队列,实际上就是做FIFO,很简单的.
给你我们阿波罗开发板录音机实验的FIFO代码:

[mw_shl_code=cpp,true]
u8 *sairecbuf1;                        //SAI1 DMA接收BUF1
u8 *sairecbuf2;                 //SAI1 DMA接收BUF2

//REC录音FIFO管理参数.
//由于FATFS文件写入时间的不确定性,如果直接在接收中断里面写文件,可能导致某次写入时间过长
//从而引起数据丢失,故加入FIFO控制,以解决此问题.
vu8 sairecfifordpos=0;        //FIFO读位置
vu8 sairecfifowrpos=0;        //FIFO写位置
u8 *sairecfifobuf[SAI_RX_FIFO_SIZE];//定义10个录音接收FIFO

FIL* f_rec=0;                        //录音文件       
u32 wavsize;                        //wav数据大小(字节数,不包括文件头!!)
u8 rec_sta=0;                        //录音状态
                                                //[7]:0,没有开启录音;1,已经开启录音;
                                                //[6:1]:保留
                                                //[0]:0,正在录音;1,暂停录音;

//读取录音FIFO
//buf:数据缓存区首地址
//返回值:0,没有数据可读;
//      1,读到了1个数据块
u8 rec_sai_fifo_read(u8 **buf)
{
        if(sairecfifordpos==sairecfifowrpos)return 0;
        sairecfifordpos++;                //读位置加1
        if(sairecfifordpos>=SAI_RX_FIFO_SIZE)sairecfifordpos=0;//归零
        *buf=sairecfifobuf[sairecfifordpos];
        return 1;
}
//写一个录音FIFO
//buf:数据缓存区首地址
//返回值:0,写入成功;
//      1,写入失败
u8 rec_sai_fifo_write(u8 *buf)
{
        u16 i;
        u8 temp=sairecfifowrpos;//记录当前写位置
        sairecfifowrpos++;                //写位置加1
        if(sairecfifowrpos>=SAI_RX_FIFO_SIZE)sairecfifowrpos=0;//归零  
        if(sairecfifordpos==sairecfifowrpos)
        {
                sairecfifowrpos=temp;//还原原来的写位置,此次写入失败
                return 1;       
        }
        for(i=0;i<SAI_RX_DMA_BUF_SIZE;i++)sairecfifobuf[sairecfifowrpos]=buf;//拷贝数据
        return 0;
}

//录音 SAI_DMA接收中断服务函数.在中断里面写入数据
void rec_sai_dma_rx_callback(void)
{      
        if(rec_sta==0X80)//录音模式
        {  
                if(DMA2_Stream5->CR&(1<<19))rec_sai_fifo_write(sairecbuf1);        //sairecbuf1写入FIFO
                else rec_sai_fifo_write(sairecbuf2);                                                //sairecbuf2写入FIFO
        }
} [/mw_shl_code]

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 14:06:58 | 显示全部楼层
正点原子 发表于 2016-9-3 20:14
另外,必须是方案2.
环形队列,实际上就是做FIFO,很简单的.
给你我们阿波罗开发板录音机实验的FIFO代码:
...

谢谢原子哥的回答,我的FIFO与您提供的功能是一致的,现在主要的问题是任务1中是先解析数据后存放到sd卡的,这个解析是占据时间的,导致这个任务的处理速度跟不上中断任务引发的对FIFO写操作。
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

58

主题

359

帖子

0

精华

高级会员

Rank: 4

积分
987
金钱
987
注册时间
2014-9-29
在线时间
261 小时
发表于 2016-9-5 14:16:28 | 显示全部楼层
1是不行的
用ringbuffer很好
以前没用DMA都能处理过来
用DMA得总是改起始地址  没试过
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 14:31:20 | 显示全部楼层
yuzeyuan1 发表于 2016-9-3 15:03
我想简单了。
任务1、2、3都不是什么好惹的货色,哪一个都要占不少时间。不能分开执行么,干完1再干2、3

遗留的还是FIFO会被写入数据覆盖的问题
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 14:31:51 | 显示全部楼层
闪电之舞 发表于 2016-9-5 14:16
1是不行的
用ringbuffer很好
以前没用DMA都能处理过来

ringbuffer是什么
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 14:39:27 | 显示全部楼层
闪电之舞 发表于 2016-9-5 14:16
1是不行的
用ringbuffer很好
以前没用DMA都能处理过来

好像就是我的FIFO   不用DMA的话接收中断太频繁了
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 15:19:54 | 显示全部楼层
正点原子 发表于 2016-9-3 20:14
另外,必须是方案2.
环形队列,实际上就是做FIFO,很简单的.
给你我们阿波罗开发板录音机实验的FIFO代码:
...

原子哥还有一个问题就是 我现在用的是f103  如果换f407的话我解析算法运行的时间应该就可以缩减了吧   波特率仍然是115200而解析数据的速度提高   不过现在我还在优化我的算法,但是再怎么优化我也得从FIFO中解析出每一条数据(20字节),编好序号存入sd卡
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 15:23:14 | 显示全部楼层
正点原子 发表于 2016-9-3 20:14
另外,必须是方案2.
环形队列,实际上就是做FIFO,很简单的.
给你我们阿波罗开发板录音机实验的FIFO代码:
...

原子哥还有一个问题就是 我现在用的是f103  如果换f407的话我解析算法运行的时间应该就可以缩减了吧   波特率仍然是115200而解析数据的速度提高   不过现在我还在优化我的算法,但是再怎么优化我也得从FIFO中解析出每一条数据(20字节),编好序号存入sd卡
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 15:24:46 | 显示全部楼层
正点原子 发表于 2016-9-3 20:14
另外,必须是方案2.
环形队列,实际上就是做FIFO,很简单的.
给你我们阿波罗开发板录音机实验的FIFO代码:
...

也用双缓冲的方法刷过字库,但那是拿到什么存什么,中间也没繁琐的数据解析过程
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

58

主题

359

帖子

0

精华

高级会员

Rank: 4

积分
987
金钱
987
注册时间
2014-9-29
在线时间
261 小时
发表于 2016-9-5 17:05:50 | 显示全部楼层
不知道你要处理的数据量是有多大,环形缓冲区都不行。。。
解析也没那么麻烦吧
回复

使用道具 举报

14

主题

219

帖子

0

精华

高级会员

Rank: 4

积分
598
金钱
598
注册时间
2014-4-14
在线时间
76 小时
发表于 2016-9-5 17:34:20 | 显示全部楼层
方案1就不用考虑了,你数据量那么大,只能用环形队列,而且你还得考虑任务1不会占用太多的CPU时间导致任务无法切换,不管怎么说,你这很坑,尤其是用103,能用407最好用起来,环形队列满了也就那么几种情况,要么单个节点缓存开的不够大,要么队列数不够,还有就是CPU时间全让任务1占用了,导致任务2无法运行。说真的,你这需求跟我这一样坑,我领导还要求我用OV2460在103上实现录像,录完了,还要发出去~~真TM吐血!
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 18:26:42 | 显示全部楼层
GS1101923161 发表于 2016-9-5 17:34
方案1就不用考虑了,你数据量那么大,只能用环形队列,而且你还得考虑任务1不会占用太多的CPU时间导致任务 ...

我已经计划换407了  顺便还看了下F7     主频提高算法占用时间至少少了   这两天先反思下算法
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 18:29:10 | 显示全部楼层
闪电之舞 发表于 2016-9-5 17:05
不知道你要处理的数据量是有多大,环形缓冲区都不行。。。
解析也没那么麻烦吧

115200波特率我实际测了1s连续发过来1W多字节,我要从环形队列里解析出每条数据  还要去重算法  还要存  还不能耽误gprs实时性
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 18:35:46 | 显示全部楼层
GS1101923161 发表于 2016-9-5 17:34
方案1就不用考虑了,你数据量那么大,只能用环形队列,而且你还得考虑任务1不会占用太多的CPU时间导致任务 ...

你的还好吧   又不是边录边发   我TM这还有去重算法要做   它1s来10000多(实测也接近了),我1s之内得处理完这么多数据存下来      1s之内剩下来的那么一点时间还要读sd卡gprs发送     各种和服务器的校验就不说了
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2016-9-5 18:37:29 | 显示全部楼层
正点原子 发表于 2016-9-3 20:12
1w字节=10KB
SD卡写入速度一般是远远大于10KB/S的.

原子哥  2k不是直接可以存的  我还要解析去重
我是一只菜鸟,但我会大鹏展翅
回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8017
金钱
8017
注册时间
2014-8-13
在线时间
1594 小时
发表于 2016-9-6 07:22:51 | 显示全部楼层
没做过。这里无责任胡诌一下


串口用空闲中断+DMA接收(论坛有人发了代码,我尝试寄存器模式的F4,只能空闲中断,如果DMA的话,会丢失数据长度信息)
接收一次数据就处理一次,随时接收随时处理。
另外接收缓冲区参考linux的EPOLL或者Winidows下的IOCP的应用层,每次接收之前都malloc一段新内存(参考原子内存管理实验),
接收完数据并处理完之后,free掉这段内存。

如果处理的非常慢,跟不上接收的话,那就把接收到的N个缓冲压入FIFO队列。
如果FIFO队列把所有的内存占用了,那你只能换性能更高的MCU了。
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
发表于 2016-9-6 08:11:59 | 显示全部楼层
战舰水手 发表于 2016-9-3 14:57
1s过来1万个字节,我每次进去读得越多处理时间就需要越久

你确定?115200波特率,每秒11520字节,撑死也就11520字节,你这个不间断发送数据啊。如果不分包,整包数据那么大,缓存也够大的了。
ps:用FIFO,定时读或者低优先级不间断读(类似USB大数据通讯,数据来了就不间断处理,但是优先级一定要低),只要不为空就可以读,实时性由系统来保证。
回复

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2016-9-6 08:16:32 | 显示全部楼层
感觉双缓冲可以解决问题。另外刷屏太占时间,尽量减少屏幕的刷新次数和刷新范围
回复

使用道具 举报

14

主题

219

帖子

0

精华

高级会员

Rank: 4

积分
598
金钱
598
注册时间
2014-4-14
在线时间
76 小时
发表于 2016-9-6 08:52:20 | 显示全部楼层
战舰水手 发表于 2016-9-5 18:35
你的还好吧   又不是边录边发   我TM这还有去重算法要做   它1s来10000多(实测也接近了),我1s之内得处 ...

但是我那设备不止是录像,还有其他任务,比如录音啊、打电话啊、各种数据采集啊等等,坑的要死,结果导致的结果就是,CPU时间全让录像占用了,其他任务基本没时间跑,哎!!
回复

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2016-9-6 09:53:51 | 显示全部楼层
串口部分用DMA+空闲中断的方式先试试看,另外解析数据收到多少解析多少,边解析边存入SD卡也不行吗?
我的博客:http://blog.csdn.net/itdo_just
回复

使用道具 举报

30

主题

1170

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1993
金钱
1993
注册时间
2016-2-16
在线时间
527 小时
发表于 2016-9-6 10:17:01 | 显示全部楼层
用DMA加上环形缓存队列,DMA有个过半中断,同时开启过半中断和完成中断,这样就能同时起到你一开始1和2的效果了。
现在问题感觉就是你处理数据的时间,不知道要多长,跟得上速度不
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11537
金钱
11537
注册时间
2014-4-1
在线时间
1314 小时
发表于 2016-9-6 10:32:56 | 显示全部楼层

串口是很慢的通信方式。
现在重点已经不是串口,而是如何协调这么些任务。


回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-25 18:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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