串口读取操作中,我们想要获得更好的数据的接收的实时性,来避免burst写入带来的数据丢失,想要更加快速的处理读入的数据,这是我们的希望.
关于读取操作:
1. 帧的定长不定长问题: 这里有人提出了使用IDLE 中断来判断一帧或者一次数据接收完成.我写了一下简单代码,没有测试极限速度.
思路:a. 中断中判断RX和IDLE ,其中RX来读数据到buffer[n] ,IDLE来终结这次读写,并记下已读取的数据的数目. b. 在主循环或者一个任务中根据a中的数据数目和收到的数据buffer[n]来处理数据帧,具体使用状态机或者简单的判断都可以.
弱点: 如果遇到串口的发送方burst发送,导致buffer[n] 写入超过n个,但IDLE并没有终结读写,这种情况下 可以: a. 增加buffer深度 b. 使用乒乓操作 ,双buffer .其中.a并不会增加系统的响应时间,因为在burst读取中,虽然写buffer写的很深,这个过程中并没有对这个buffer中的数据进行读取,这是不如乒乓操作的地方,b中一个buffer满,那么这个buffer就可以释放给解析的任务去做了.
2. 高速读取问题: 使用dma去把串口的数据搬到buffer上去,这个基本的思路,它有几个变形.
2-1:使用dma读取,使用IDLE中断判断一帧结束:
优点:对于不定长的帧,满足了速度和不定长的灵活要求.可以使用ringbuffer来在主循环中读取到当前的写入位置,来让处理和收数据同步,提高了实时性.
缺点:burst 读写爆buffer的问题,无法解决,完备性欠佳.
2-2:使用dma读取,使用双buffer缓冲,使用dma的自己的 写入完成中断来切换buffer.
优点:如果出现爆buffer,是说当前buffer写入完成,另一个buffer没有读完,这种情况可以通过关闭dma直到另一个buffer可以用为止来满足完备性的需求.速度上也是有优势的,因
收数据和读取数据时同时的基本.
缺点:只在一个buffer满了之后才去处理,这里不如ringbuffer的数据处理的实时性高.
未完待续...
其中仍有逻辑错误,我需要补充实验来看效果.
|