你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

优化图片刷新速度而引出的SDIO DMA疑问

[复制链接]
huangxuejia-292 发布时间:2018-5-29 01:51
前几天,做了图片显示的实验,将一张24BIT的BMP从SD卡显示到TFT LCD上。
LCD用FSMC控制。
速度真他慢,真像PPT的渐变效果。

测试了一下,300ms一屏,实在无法忍受。
决定看看时间都浪费在哪里。
测试1:
如果刷一种颜色到LCD,只要10ms。
程序就是用FOR循环将320*240个U16发到LCD。
测试2:
屏蔽从SD卡读数据,只执行将原来图片显示中显示的代码。
运行时间27ms。应该算正常,毕竟有不少的数据处理。

也就是说,读数据画了270ms。要优化,就只能从大头入手,毕竟你就算把图片数据处理全优化掉,也才17ms。
根据本人多人经验:只要涉及到数据读取速度的优化,有一个屡试不爽的方法,就是一次读多一点的数据

由于RAM不够,不可能将图片一次性全部读到RAM,原来的程序是每次读一行,那么我们现在就改为一次读10行吧。

测试3:
改为一次读10行或者20行,测试,时间300ms?


经验失效?
不应该,毕竟多年经验。而且时间确实是浪费在读数据啊?
分析一下读数据,并输出LOG调试,发现问题:
1 每次读一行,FATFS文件系统调用SD卡接口时,只会读一个SECTOR。
2 每次读多行,FATFS文件系统调用SD卡接口时,会读取多个SECTOR。但是,但是,由于SD卡使用DMA,需要4字节对齐。
  程序中对指针进行判断,如果不是四字节对齐,那么就改为一次读一个SECTOR。
如果关键路径在SD卡读sector数据,那么,我们的优化就没有效果,这当然正常,毕竟我读再多,你还是每次读一个sector。

测试4:
把4字节对齐的处理屏蔽,就用原来的读多块,不对齐只会造成数据错,功能还是能跑的。
实测,100ms,但是图片确实显示不对了,有点拖影。
(如果4字节 DMA不对齐,读写会有1-3个字节的偏移;2字节DMA补对齐,则会有1个字节的偏移;这也是一个经验)

那么说:
读多一点数据,这个经验还是有效的

但是字节对齐还是个问题啊?

百度,GOOGLE:
http://bbs.21ic.com/icview-561094-1-1.html
"STM32F2/F4的DMA支持拆分重组了,也就是buffer可以是非对齐的方式(需要在配置时使能)。
如果是F1,常用的方法是自己准备一块4字节对齐的buffer,当应用程序传进来的buffer不对齐时,使用自己的buffer,并与应用程序的buffer做memcpy。
当然,应用程序要尽量避免使用不对齐的buffer."

看文档:
“9.3.10 可编程数据宽度、封装/解封、字节序”

看代码:
  1. SDDMA_InitStructure.DMA_Channel = SD_SDIO_DMA_CHANNEL;
  2.   SDDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;
  3.   SDDMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)BufferSRC;
  4.   SDDMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
  5.   SDDMA_InitStructure.DMA_BufferSize = BufferSize;
  6.   SDDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  7.   SDDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  8.   SDDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  9.   SDDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  10.   SDDMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  11.   SDDMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  12.   SDDMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
  13.   SDDMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  14.   SDDMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
  15.   SDDMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;
复制代码
既然可以设置外设跟内存的字长,那么说明两者可以设置不同字长啊,也就是文档中所说的封装,也就是别人说的拆分重组吧?

测试5:
DMA_MemoryDataSize改为DMA_MemoryDataSize_Byte.
图片显示正常,刷屏时间100ms.

求证:
查阅多家开发板例程代码,好像都是判断地址,不是4字节对齐就改为一次读一个sector然后拷贝数据。
心里犯嘀咕,难道改为byte会有啥隐藏问题?

请给位坛友大神指点指点,是否可以改为Byte?
改为Byte会有啥隐患?
300ms到100ms的优化,还是很有诱惑的。

评分

参与人数 1 ST金币 +6 收起 理由
MrJiu + 6 神马都是浮云

查看全部评分

收藏 评论1 发布时间:2018-5-29 01:51

举报

1个回答
MrJiu 回答时间:2018-5-29 11:01:55
思考的确实很好!!!

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版