硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5222|回复: 14
收起左侧

[SD/SDIO] STM32H7的SDIO自带的DMA控制器数据传输的地址是强制4字节对齐,这就非常不方便了

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 2019-6-14 13:13:07 | 显示全部楼层 |阅读模式
问题由来:
F4系列也有DMA传输的四字节对齐问题,但是DMA可以配置为字节对齐传输,这就非常省事,修改下DMA配置即可。
而H7自带的DMA就非常不方便了,地址强制4字节对齐:
QQ截图20190614125931.jpg

问题分析:
HAL的SDIO DMA传输不管这些,直接就是把用户设置的地址赋值给上面的寄存器,也就是HAL库不管字节对齐问题,需要用户自己去处理:
HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)

{
     xxxxxx
     hsd->Instance->IDMABASE0 = (uint32_t) pData ;
}

一般情况下应用,大家看不出来这个问题,在用户使用emWin那种边加载边显示图片的时候,问题就出来了(因为很难保证每次的读取都是4字节对齐的)。
问题反映到fatfs上就是这个buf不是4字节对齐的
QQ截图20190614130646.jpg

处理办法:
方法一:
可以在这里先判断是否是4字节对齐的,如果不是对齐的,动态申请一块区域做存储,并做首地址对齐后做传输,传输结束后再复制到buf里面。

方法二:
还有个办法就是使用MDMA,这种方式修改的工作量就有点大了。

方法三:
对于fatfs这种文件系统,如果读取的数据量大于512字节(小于等于512字节没问题的),改成分批读写即可,只是这种方式不能使用Multiblock传输了,速度慢。

大家看看有没有更加快捷的办法解决这个问题。




回复

使用道具 举报

609

主题

3049

回帖

4896

积分

至尊会员

积分
4896
发表于 2019-6-14 14:36:22 | 显示全部楼层
如果想要兼容性好,工作稳定的话,建议还是 512 比较靠谱
回复

使用道具 举报

32

主题

262

回帖

363

积分

高级会员

积分
363
发表于 2019-6-14 15:28:30 | 显示全部楼层
最简单的就是字节对齐,这个最好处理, 虽然速度会下降一些
回复

使用道具 举报

18

主题

321

回帖

375

积分

高级会员

积分
375
发表于 2019-6-15 10:49:34 | 显示全部楼层
感谢硬汉老大
回复

使用道具 举报

18

主题

321

回帖

375

积分

高级会员

积分
375
发表于 2019-11-28 09:03:28 | 显示全部楼层
请问一下方法一:
可以在这里先判断是否是4字节对齐的,如果不是对齐的,动态申请一块区域做存储,并做首地址对齐后做传输,传输结束后再复制到buf里面。
判断四字节对齐可以理解,如果不对齐,就补齐也可以理解。在使用RTOS的时候,直接malloc的内存应该是四字节对齐的,这个API不是已经交给DMA传输了吗?为什么传输结束后还要复制到buf里?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
 楼主| 发表于 2019-11-28 09:13:44 | 显示全部楼层
王海靖 发表于 2019-11-28 09:03
请问一下方法一:
可以在这里先判断是否是4字节对齐的,如果不是对齐的,动态申请一块区域做存储,并做首 ...

malloc不管4字节对齐吧,这个我还真没有测试过。

要复制的,因为你的数据是DMA到你申请的缓冲区了,时间要搞到buff里面才可以供应用使用。
回复

使用道具 举报

18

主题

321

回帖

375

积分

高级会员

积分
375
发表于 2019-11-28 11:22:14 | 显示全部楼层
eric2013 发表于 2019-11-28 09:13
malloc不管4字节对齐吧,这个我还真没有测试过。

要复制的,因为你的数据是DMA到你申请的缓冲区了,时 ...

那应该是先判断数据是否是四字节对齐,对这个进行malloc处理之后,在复制到BUFF之后,再调用 SDIO_DMA();这样理解对吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
 楼主| 发表于 2019-11-28 15:52:43 | 显示全部楼层
王海靖 发表于 2019-11-28 11:22
那应该是先判断数据是否是四字节对齐,对这个进行malloc处理之后,在复制到BUFF之后,再调用 SDIO_DMA( ...

malloc申请的换成4字节对齐后,做DMA,之后复制到buff即可
回复

使用道具 举报

18

主题

321

回帖

375

积分

高级会员

积分
375
发表于 2019-11-28 16:39:12 | 显示全部楼层
eric2013 发表于 2019-11-28 15:52
malloc申请的换成4字节对齐后,做DMA,之后复制到buff即可

看错了,你这个地方是读数据,我一直想成写数据了。这下明白了。
回复

使用道具 举报

4

主题

166

回帖

178

积分

初级会员

积分
178
发表于 2023-12-18 14:49:38 | 显示全部楼层
现在的RLFATFS是怎么处理的这个,速度还挺快的吧
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
 楼主| 发表于 2023-12-19 08:07:50 | 显示全部楼层
yuanzhongda 发表于 2023-12-18 14:49
现在的RLFATFS是怎么处理的这个,速度还挺快的吧

也是做对齐,在CMSIS-Driver软件包里面有对应的驱动。
回复

使用道具 举报

4

主题

166

回帖

178

积分

初级会员

积分
178
发表于 2023-12-20 08:32:31 | 显示全部楼层
eric2013 发表于 2023-12-19 08:07
也是做对齐,在CMSIS-Driver软件包里面有对应的驱动。

具体用的你开始说的三个方法中的哪一个
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
 楼主| 发表于 2023-12-20 09:02:42 | 显示全部楼层
yuanzhongda 发表于 2023-12-20 08:32
具体用的你开始说的三个方法中的哪一个




12.png
回复

使用道具 举报

4

主题

166

回帖

178

积分

初级会员

积分
178
发表于 2023-12-20 09:11:26 | 显示全部楼层

这个我看到了,这个不是直接赋值没对齐吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
 楼主| 发表于 2023-12-20 09:32:13 | 显示全部楼层
yuanzhongda 发表于 2023-12-20 09:11
这个我看到了,这个不是直接赋值没对齐吗

FlashFS有分配专门的内存块,调用这个接口方式的时候,形参已经做处理了。你可以这里的打印下每次给的数据是否4字节对齐了。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-29 17:48 , Processed in 0.222345 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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