[STM32H7] STM32H7B0VBT6使用Free RTOS配置SD卡 LCD显示 DMA冲突

[复制链接]
39|18
晓伍 发表于 2026-5-10 14:52 | 显示全部楼层 |阅读模式
裸机可以用,但是freertos无法使用
原因是内存 分配,内存管理问题,可以将显示和SD卡内存分开
从 0 开始,长度为 32 KB 的内存区域,其结束后的下一个地址(即第 32 KB 开始的地址)是:

0x00008000

计算过程
起始地址: 0x00000000
长度: 32 KB
换算为字节: 32 times 1024 = 32,768 字节
换算为十六进制:
    32 = 2^5
    1 text{ KB} = 2^{10}
    32 text{ KB} = 2^5 times 2^{10} = 2^{15}
    2^{15} 在十六进制中对应 0x8000
最后一个有效字节地址: 0x00007FFF
第 32 KB 开始的地址: 0x00007FFF + 1 = 0x00008000

结合 STM32H7 的实际应用

如果你是将这个偏移量应用到 SRAM1 (0x24000000) 上:

基准地址: 0x24000000
偏移量: 32 KB (0x8000)
计算结果: 0x24000000 + 0x8000 = 0x24008000

这个地址在哪里?
它位于 SRAM1 的最前端。
    0 ~ 32KB: 0x24000000 ~ 0x24007FFF
    32KB 开始: 0x24008000 (你问的这里)
    32KB ~ 64KB: 0x24008000 ~ 0x2400FFFF

MPU 配置提示
如果你打算用 MPU 保护从 0x24000000 开始的 32 KB 区域:
Base Address: 0x24000000
Size: MPU_REGION_SIZE_32KB
覆盖范围: 0x24000000 到 0x24007FFF
下一个可用地址: 0x24008000

如果你是想把变量放在 32 KB 之后 的位置(避开前 32KB):
请使用地址 0x24008000。

快速对照表 (基于 0x24000000 起始)
偏移大小   十六进制偏移   目标地址 (0x24000000 + 偏移)   说明
32 KB   0x8000   0x24008000   第 32KB 开始

64 KB   0x10000   0x24010000   第 64KB 开始

128 KB   0x20000   0x24020000   第 128KB 开始

256 KB   0x40000   0x24040000   第 256KB 开始

512 KB   0x80000   0x24080000   SRAM1 结束,SRAM2 开始




————————————————
版权声明:本文为CSDN博主「Miko-one」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42949957/article/details/158579055

公羊子丹 发表于 2026-5-11 08:13 | 显示全部楼层
H7系列DMA必须用非缓存RAM,我怀疑你是把LCD和SD卡的缓冲区放同一段内存了,按楼主方法分开地址基本都能解决。
周半梅 发表于 2026-5-11 08:14 | 显示全部楼层
这问题挺常见的!FreeRTOS下内存重叠最容易导致DMA冲突,建议把SD卡放前32KB,LCD从0x24008000开始,互不干扰。
帛灿灿 发表于 2026-5-11 08:15 | 显示全部楼层
你检查过MPU配置吗?H7如果开了MPU,没给DMA区域设可共享、非缓存,裸机正常、RTOS必挂,我踩过这个坑。
童雨竹 发表于 2026-5-11 08:16 | 显示全部楼层
我建议直接用__attribute__((section))指定内存段,把LCD、SD卡、栈堆全部分开,比手动算地址更安全不易错。
万图 发表于 2026-5-11 08:17 | 显示全部楼层
H7的RAM1和RAM2地址差很多,楼主这个地址对照表太实用了,我每次配DMA都直接查表,省得自己算半天还出错。
Wordsworth 发表于 2026-5-11 08:18 | 显示全部楼层
提醒一下,FreeRTOS的任务栈也别和DMA缓冲区抢地址,最好把栈放RAM2,数据缓冲区放RAM1,彻底避免冲突。
Bblythe 发表于 2026-5-11 08:19 | 显示全部楼层
我之前H7B0也遇到一模一样的问题,裸机没问题一跑系统就死机,按楼主方法内存分区后,LCD和SD卡同时用都很稳。
Pulitzer 发表于 2026-5-11 08:20 | 显示全部楼层
好奇问下,你用的是SDMMC+DMA还是SPI+DMA?我用SDMMC时必须把缓冲区放在32KB对齐地址,不然直接传输失败。
Uriah 发表于 2026-5-11 08:21 | 显示全部楼层
可以试试把Heap4堆管理器移到非DMA区域,再给LCD和SD卡单独分配固定地址内存,能彻底解决RTOS下的内存争抢问题。
Clyde011 发表于 2026-5-11 08:22 | 显示全部楼层
H7的DMA对地址对齐要求特别严,楼主给的0x8000偏移刚好是32KB对齐,照着这个地址放缓冲区,基本不会出异常。
海滨消消 发表于 2026-5-11 10:50 | 显示全部楼层
将LCD的帧缓冲区和SD卡DMA缓冲区分别指定到不同的SRAM区域,避免共享同一内存块。
elephant00 发表于 2026-5-11 10:55 | 显示全部楼层
使用__attribute__((aligned(32)))对齐缓冲区地址,避免Cache Line交叉导致的DMA错误。
flycamelaaa 发表于 2026-5-11 11:26 | 显示全部楼层
在FreeRTOS config文件中增加configTOTAL_HEAP_SIZE,使系统堆不挤占你划分的专用内存区域。
甜心puppy 发表于 2026-5-11 11:50 | 显示全部楼层
在链接脚本中为LCD显存单独划分一块SRAM,SD卡DMA用后面的地址。
jcky001 发表于 2026-5-11 12:27 | 显示全部楼层
检查DMA传输方向,如果是从内存到外设的固定内容,该内存区域应设为只读,避免任务写入干扰。
onlycook 发表于 2026-5-11 13:21 | 显示全部楼层
通过STM32CubeMX的“Memory Region”选项卡为不同模块显式分配内存起始地址和大小。
powerantone 发表于 2026-5-11 15:28 | 显示全部楼层
在初始化SD卡和LCD之前,先调用HAL_MPU_Enable()并配置好区域划分,防止运行时冲突。
等凌晨日出 发表于 2026-5-11 15:51 | 显示全部楼层
使用MPU配置将LCD缓冲区所在内存区域设置为非可缓存、非共享,防止DMA一致性冲突。
茉璃夏 发表于 2026-5-11 16:52 | 显示全部楼层
定义数组时通过__attribute__((section(".lcd_frame")))将LCD缓冲区固定到专用内存段。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

164

主题

4582

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部
0