DMA 串口传输原理解析

之前有个同事因为用串口查询方式发送数据,被我说了一顿,明明有 dma 资源,竟然放着不用,对于鱼鹰这种性能强迫症来说,肯定无法忍受,所以当时就和他说,有时间你把它改一下。
谁知道过了好几个月他才有时间弄这个,然后还是出了问题,没法子,只能找我解决了。
现象是这样的,使用查询方式,一点问题没有,从机可以正常接收数据,一旦换成 dma,从机就无法正常解析数据了,从机缓存的数据也不正确。
因为当时我也一脸懵逼,也不知道他做了什么操作导致的,毕竟他调用的 dma 发送函数都是鱼鹰很久以前写的,也是久经考验的代码,不可能出现问题才对。
所以在没有头绪的情况下,直接同时调试两颗单片机了。
对,你没有看错,就是使用两个调试器同时调试两个单片机。
很简单,就在下面的图中选择即可,估计有很多老司机都不知道这个吧。(不同工程)
这样一台电脑就可以同时调试主机和从机了。
当时首先查看了 dma 外设和 uart 寄存器情况,发现并没有问题(毕竟如果这个错了,再怎么查应用代码也是没用的,排查问题要讲究先后顺序)。
又在线查了一会发现,如果我在 dma 发送函数后打上断点,从机是可以正常解析的,这一点又让我疑惑了,所以为了防止从机代码可能有问题,直接让同事用一个串口模块接收数据。
串口助手显示,发送的字节数是正确的,但是只有帧头几个字节对的,其它字节全是错的。
一看到这里,鱼鹰大概就知道了,大概率是 dma 发送缓冲区被篡改了,一查函数调用,瞬间就明白了是怎么回事,函数调用大概如下(细节没有展示):
void dma_send(dma_channel_typedef *dmax, void *buff, uint8_t size){  dmax->cndtr = size;  dmax->cmar  = buff;}
void send_data(){  uint8_t buff[8];  buff[0] = 1;  buff[1] = 2;     ……  dma_send(dma1, buff, 8); }
竟然用局部数组变量作为 dma 发送的缓冲区,鱼鹰也是醉了。
那么为什么查询方式下,这样的代码不会出错,dma 方式就错了?
要解答这样的问题,基础必须扎实:
1、dma 传输原理
2、局部变量存放位置与特性。
只要知道这两点,这个问题就很容易避免。
但事实上,很多人只会大概用,根本没有真正理解。
dma  串口传输凭什么说效率高?是因为它让串口速率传输更快了吗?一个字节传输本来要 1 ms,用 dma 只要 0.5 ms?估计很多人都是这么理解的吧。
事实上,dma 并没有加快传输速率,只不过是把传输的任务转交给专业的而言《数据传输还用 cpu?不如交给 dma 吧!》,而 cpu 就可以专心干剩下的事情。
注意这里的转交一词,cpu 把必要的传输信息(比如传输地址、大小等)告诉 dma 后,一般会启动 dma,之后立刻运行后面的代码,但此时 dma 缓存地址里面的数据并没全部发送出去,如果这个缓存用的是局部变量,离开这个函数后,局部变量被回收,并会继续给其他函数使用,此时这个缓存的数据就被篡改了,这样 dma 发送出去的数据当然不正确。
所以,从这个角度来说,dma 并没有加快串口本身的传输速度,只是解放了 cpu 资源而已。但是 cpu 被解放了, dma 所使用的 缓存 资源可不能也随之解放呀,只能等发送完毕后才能释放。所以最简单的方法是在 缓存 前面加一个 static 。
那么为什么查询不会出问题呢?查询是把所有缓存中的数据发送出去后,才会离开当前函数,这样局部变量始终存在,也就不会有问题了,不像 dma 一样扔到缓存里面就溜之大吉,局部变量也随之溜了。
但是,还有一种特殊的局部变量,也能达到全局的效果。这就是操作系统中的主函数的局部变量。
void  task(){  uint32_t buff[32]; // 局部变量,但效果和全局变量差不多。  while(1)  {  }}
因为任务一般会被死循环包含,永不退出(前提条件),所以这里的局部变量也就不会被释放掉,所以有些情况下,为了更好的使用资源,会采用这种方式。
好了,今天的分享到此结束,有收获的话,记得三连支持一波呦!


具有快速断电模式的高性能四路DVGA LMH6523介绍
如何提升运算放大器的输出电流驱动能力
大家认识一下:高压线的安全距离
一款适合LED照明的驱动电源的开关电源芯U6315!
HLS系列 – High Level Synthesis(HLS) 从一个最简单的fir滤波器开始4
DMA 串口传输原理解析
Visual Studio Code - 如何在Visual Studio Code(VS Code)中构建和调试RL78项目
谁是国产手机之王
组合开关应用和主要技术参数
3分钟了解Reality+算法!艾睿热成像户外新一代图像处理技术
接近开关与继电器的接法
stm8和stm32的区别和特点
Tektronix DPO7354数字示波器3.5GHz
高影响力部署中的商业云安全
DS28EL15 DeepCover嵌入式安全解决方案
1%系列和5%系列贴片电阻的区别
移动基站通信电源系统设计
联发科芯片不敌高通芯片,魅族转投高通之下
如何挑选合适的直线电机?这些元素要掌握
期待!全新诺基亚X5和诺基亚X7即将推出