完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近看了下串口驱动 v2,其中接收缓存区使用了 ringbuffer。 在使用 DMA 方式接收时,是直接用循环接收方式将数据直接写入 ringbuffer 指向的内存区中,在接收中断中(IDLE、或 DMA 中断)根据收到的数据长度,使用 rt_serial_update_write_index 函数调整 ringbuffer 的写指针的位置。 rt_serial_update_write_index 函数里会判断需要调整的偏差值是否大于 ringbuffer 的空闲空间,如果大于,则最多只调整空闲空间这么多。 这里我感觉有个问题,DMA 接收的数据已经收到了,并且已经覆盖了原有的数据,就算写指针位置更新不会超过空闲空间数量,那后续的数据也已经不正确了。 不知道是不是我的理解有哪里不对,望大佬指教。 |
|
相关推荐
7个回答
|
|
serialX
|
|
|
|
你的实现和 v2 的实现有一个差别是你有 DMA 缓存和串口缓存的区分,在 DMA 中断里进行数据复制,而 v2 的是直接将数据存入串口缓存。
不管缓存区多大,总有特殊情况会有溢出的可能。 我的疑问在于 v2 既然做了判断,当新收到的数据量超出了 ringbuffer 的空闲空间,就最多只给写指针增加空闲空间这么大的数量,但其实数据已经往后继续存了,已经覆盖了最旧的数据了,而写指针更新后指向的位置并不是最新的数据所在的位置,而是将 ringbuffer 刚好写满的位置。 我觉得覆盖就覆盖了,这个避免不了,但应该保证最新的位置是正确的,如果覆盖了就还得同步更新读指针。 |
|
|
|
v2 是保留最老的数据,把最新的丢掉。serialX 把最老的数据删掉
|
|
|
|
按我的理解,说 v2 是保留旧数据,丢弃新数据好像也不对。
因为 DMA 一直在收,缓存区的数据一直是最新的。 但是 ringbuffer 满了之后,读写指针就不会再更新了。 所以 ringbuffer 满了之后,数据和指针就对不上了,整个缓存就乱了。 除非是在缓存区刚满的时刻就立马关闭 DMA 传输,但是我没看到有这个操作,并且这个操作也不好实现,因为 DMA 中断只有几个固定点才有(1/4,1/2,3/4,1), DMA 并不知道当前读指针在哪里。 |
|
|
|
强力推荐 serialX
|
|
|
|
这个缓冲区的问题我倒是有个小建议,可以不用每次 DMA 传输之后再复制一次数据。
把循环 DMA 改为普通模式,ringbuffer 的缓冲区大小设置为 DMA 单次传输长度的整数倍。 第一次 DMA 传输从 ringbuffer 缓冲区的头部开始,后面每次传输结束中断中将传输首地址往后挪一个传输长度开始下一次 DMA。 一直挪到 ringbuffer 的最后一个缓存块之后,重新开始从头部传输。如此循环。 如果 ringbuffer 的缓存区大小本身不大的话,则直接用循环 DMA,开启 1/4 中断,ringbuffer 接收到缓存区大小 3/4 的数据则认为满。这样就不用每次都配置 DMA,浪费的空间也不多。如果缓存区大,浪费 1/4 就太多了,用上面的方法更好些。 每个 DMA 中断中更新 ringbuffer 的写指针,如果缓存区满,数据被覆盖,则同时更新读指针。 |
|
|
|
第一种方式的 DMA 变成单次了。需要重新配置和启动 DMA 。而且 DMA 满中断了以后,再收下一个数据前能不能完美切换到一块,这是个问题。
第二种方式要求 DMA 有那么多中断线。中断次数减少,意味着 ringbuffer 索引修改变滞慢。 serialX 的二级缓存机制是考虑了降低中断次数的同时,又不过多降低应用层响应数据的延迟。接收缓存的配备,又能在应用层来不及响应的情况下缓存数据,不至于丢数据。高低速应用兼顾的。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
753 浏览 0 评论
AI模型部署边缘设备的奇妙之旅:如何在边缘端部署OpenCV
2714 浏览 0 评论
tms320280021 adc采样波形,为什么adc采样频率上来波形就不好了?
1368 浏览 0 评论
1955 浏览 0 评论
1523 浏览 0 评论
75000 浏览 21 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 13:34 , Processed in 0.920533 second(s), Total 81, Slave 65 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号