搜索
bottom↓
回复: 22

STM32H7上使用CubeMX,HAL配置UART串口DMA的坑

[复制链接]

出105入79汤圆

发表于 2021-5-31 01:34:26 | 显示全部楼层 |阅读模式
本帖最后由 qwe2231695 于 2021-5-31 02:08 编辑

近日调试一块H7的板子, 板上资源丰富,运行速度很快, 我移植了Lwip等应用,然后想简单打开一下串口, 使用DMA形式接收. 但是无论怎么设置都没有正常收发.

可以进入回调函数, 但是接收数组内容一直是0, 就像DMA没有搬运过来一样.

调试良久,终于通畅可以跑满串口带宽:

下面说我是怎么搞的:

配置UART, 再cubeMX中点选我想用得uart8 , 设置波特率.

DMA选项开启. RX要启用循环模式, 这样收到一次就会再启动一次.

ok,到这里cubeMX的配置就完了, 网上都是这么写的. 点击在CubeMX IDE 点击保存,就生成代码了.
然后我在代码端再加写一些代码:

在串口配置内, USER CODE 注释空间内添加 立刻启动接收. 接收1字节帮我DMA搬运去uart8_RXdata这个数组内.
下面写一个函数叫: HAL_UART_RxCpltCallback, 这个函数库函数其实已经声明好了, 就等着用户自己写逻辑, 每次串口接收完我指定的数目后就会自动进入.

进入这个回调函数后, 我就把uart8_Rxdata数据拿出来. 放去我逻辑缓冲区, 我在Freerots里面有个任务就是慢慢去解析这些数据的. 到这里没毛病.

下面就是把Ringbuffer内的东西打印出来.

到这整个过程就结束了. 可是结果很糟糕, 无论我发送什么字符, 都只收到0, 打印0.

开始查资料:

H7 DMA 访问空间有要求, 无法访问DTCM 0x2000000区域的RAM, 如果编程环境设置了,我的变量再这个区域, DMA就搬运不了.
参考 : https://blog.csdn.net/qq_41544116/article/details/100155203


好, 我是CubeMX IDE, 是GCC环境, 查看LD文件, 查看MAP文件
bss段 指定是在 0x24000000区域, map显示我的uart8_RXdata也是在这个区域内, 所以没问题. DMA可以访问.


又折腾半天, 想起来配置LWIP的时候, 就是要配置MPU才能正常进行以太网收发. 由于H7内核达到480Mhz, CPU访问RAM都需要透过cache才能发挥性能. 所以H7芯片做了MPU这个部分来配置内存的访问策略. CPU访问SRAM 中间有CACHE的作用. 而DMA是直接操作SRAM空间. 所以要进行Cache策略配置.
在MPU设置中加入一个区块, 把整个0x2400000空间取消buffer.


生成代码, 串口收发正常了.

之前考虑过这个方面,使用了volatlie关键字, 使用ST提供的函数: SCB_InvalidateDCache_by_Addr((uint32_t *)uart8_Rxdata,2);
都不好使.

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出105入79汤圆

 楼主| 发表于 2022-4-14 00:16:44 | 显示全部楼层
后记,在调试DMA发送的时候,需要在发送前,对DMA发送的数组做CACHE无效处理:

  1. void send_by_DMA(UART_HandleTypeDef *huart,uint8_t *buf,int len,uint8_t *dma_buf)
  2. {
  3.         //检查串口是否忙
  4.         while(huart->gState != HAL_UART_STATE_READY);
  5.        
  6.         // dma_buf数组必须使用 ALIGN_32BYTES修饰,进行32字节对齐。
  7.         memcpy(dma_buf,buf,len);
  8.         /*
  9.                 无效cache(从RAM获取真实值)+ 清除Cache(写入物理RAM),做一次同步
  10.         */
  11.         SCB_CleanInvalidateDCache_by_Addr((uint32_t *)dma_buf, len);
  12.        
  13.         // 触发DMA发送
  14.         HAL_UART_Transmit_DMA(huart,dma_buf,len);
  15. }
复制代码

出100入101汤圆

发表于 2021-5-31 03:30:09 来自手机 | 显示全部楼层
专业。st推h7就没有对常用外设Demo做过测试?

出15入178汤圆

发表于 2021-5-31 09:30:05 | 显示全部楼层
标题很简单,内容很丰富。你这个方式看起来是DMA,逻辑上性能不如中断,UART8是带了16字节的FIFO的。

出0入4汤圆

发表于 2021-5-31 09:43:50 | 显示全部楼层
我也遇到这个坑,没跳过去,临时用的中断。感觉还是换成F4靠谱点。H7太高端了,玩不透

出0入1209汤圆

发表于 2021-5-31 09:54:07 | 显示全部楼层
直接禁用Cache,然后当普通高主频MCU玩就好了,不然还有很多坑,什么字节对齐之类的。

出0入8汤圆

发表于 2021-5-31 10:27:11 | 显示全部楼层
kitten 发表于 2021-5-31 09:54
直接禁用Cache,然后当普通高主频MCU玩就好了,不然还有很多坑,什么字节对齐之类的。 ...

LWIP要开启cache

出105入79汤圆

 楼主| 发表于 2021-5-31 14:14:40 | 显示全部楼层
是的, 想要用以太网和LWIP要开启D I cache

出1310入193汤圆

发表于 2021-5-31 14:41:11 | 显示全部楼层
CubeMX,HAL配置的程序   快捷方便   一旦有bug的时候  往往要十倍时间去查找

出100入101汤圆

发表于 2021-5-31 14:47:18 | 显示全部楼层
qwe2231695 发表于 2021-5-31 14:14
是的, 想要用以太网和LWIP要开启D I cache

请问为啥要开启cache?没有cache的型号,一样可以跑lwip啊?

出105入79汤圆

 楼主| 发表于 2021-5-31 14:59:57 | 显示全部楼层
fengyunyu 发表于 2021-5-31 14:47
请问为啥要开启cache?没有cache的型号,一样可以跑lwip啊?

还是以太网控制器和RAM的访问问题,  不开的话以太网控制器无法工作.

出100入113汤圆

发表于 2021-5-31 16:06:40 | 显示全部楼层
https://www.amobbs.com/thread-5720860-1-1.html

串口 DMA,我关了 Cache ,DMA 一个字节时都会出错的,看我这个帖子。不知道这个 Bug 是否修复,我提交给了代理,没给我答复。

出0入85汤圆

发表于 2021-6-2 16:09:54 | 显示全部楼层
好久没上amobbs很多年不用ST MCU了,加油很棒.

出0入0汤圆

发表于 2022-5-2 15:36:12 | 显示全部楼层
H7 和uart dma相关的还有另外一个大坑,坑了我两天时间

出105入79汤圆

 楼主| 发表于 2022-5-2 21:14:20 | 显示全部楼层
krguang 发表于 2022-5-2 15:36
H7 和uart dma相关的还有另外一个大坑,坑了我两天时间
(引用自14楼)

  能否分享一下,简单描述一下就好,串口是重要底层功能一定要稳

出0入0汤圆

发表于 2022-5-3 09:30:22 | 显示全部楼层
saccapanna 发表于 2021-5-31 16:06
https://www.amobbs.com/thread-5720860-1-1.html

串口 DMA,我关了 Cache ,DMA 一个字节时都会出错的, ...
(引用自11楼)

H7么我试了没什么问题啊,也是CubeMX生成的。不过我用的是DMA_CIRCULAR模式

https://github.com/cctv180/STM32 ... /bsp/src/bsp_uart.c

出0入0汤圆

发表于 2022-5-7 09:21:57 | 显示全部楼层
cctv02 发表于 2022-5-3 09:30
H7么我试了没什么问题啊,也是CubeMX生成的。不过我用的是DMA_CIRCULAR模式

https://github.com/cctv180 ...
(引用自16楼)

第一次串口不要选dma,生成项目后,再加上dma,再生成,dma初始化会在uart初始化之后,会导致dma失效。

出0入0汤圆

发表于 2022-5-7 12:33:47 | 显示全部楼层
krguang 发表于 2022-5-7 09:21
第一次串口不要选dma,生成项目后,再加上dma,再生成,dma初始化会在uart初始化之后,会导致dma失效。 ...
(引用自17楼)

下次我注意下,目前没发现这个情况

出0入75汤圆

发表于 2022-5-7 13:31:44 | 显示全部楼层
krguang 发表于 2022-5-7 09:21
第一次串口不要选dma,生成项目后,再加上dma,再生成,dma初始化会在uart初始化之后,会导致dma失效。 ...
(引用自17楼)

初始化顺序在CubeMX里可以调,不需要靠生成2次控制顺序。

出0入0汤圆

发表于 2022-5-7 21:38:49 | 显示全部楼层
Doding 发表于 2022-5-7 13:31
初始化顺序在CubeMX里可以调,不需要靠生成2次控制顺序。
(引用自19楼)

请教下在哪儿调,我刚打开cube翻了一圈没找到。
这个bug是这样的,如果你第一次初始化串口的时候打开了dma,那么dma的初始化函数会在串口的初始化之前,这样是没问题的。
但是如果你一开始初始化串口的时候没有带上dma,生成代码之后又加上的dma,这样dma的初始化函数会在串口的初始化函数之后。这样dma没法正常使用。

出0入75汤圆

发表于 2022-5-9 09:46:10 | 显示全部楼层
krguang 发表于 2022-5-7 21:38
请教下在哪儿调,我刚打开cube翻了一圈没找到。
这个bug是这样的,如果你第一次初始化串口的时候打开了dm ...
(引用自20楼)

Project Manager -> Advaced Settings

出0入0汤圆

发表于 2022-5-10 09:57:46 | 显示全部楼层
Doding 发表于 2022-5-9 09:46
Project Manager -> Advaced Settings
(引用自21楼)

找到了,谢谢,居然还有这功能,以前没发现

出100入312汤圆

发表于 2022-5-16 06:27:06 来自手机 | 显示全部楼层
收藏,学习
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 20:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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