STM32H7使用MDK或IAR将D2域SRAM1做主RAM空间会在分散加载启动阶段硬件异常(已经解决,8楼附C方案,14楼附汇编方案)
做主RAM空间跳转到这里卡死:
尝试过在SystemInit里面就使能SRAM时钟和MPU配置,依然不行。
待后面有时间再查查。
错误类型说明:
这个问题我也很早就发现了,猜想一下原因:看H743的芯片框图,SRAM1-3没有挂在cpu的总线上,而AXIRAM,IRAM,DRAM都是挂在cpu总线上的,所以它们都可以启动并运行程序,而SRAM1-3都不可以,感觉SRAM硬件逻辑上像是一个外设。
需要配置使能 heluo1985 发表于 2022-4-28 08:00
需要配置使能
没用,这个问题2019年时就把坑踩出来了,那个时候还没有DATA_IN_D2_SRAM。楼主位特地加上下面这句话就是这个意思。
尝试过在SystemInit里面就使能SRAM时钟和MPU配置,依然不行
STM32H7的D2域SRAM使用注意事项
https://www.armbbs.cn/forum.php? ... id=94833&fromuid=58
(出处: 硬汉嵌入式论坛)
这个问题也好解释,上电在调用 LDR R0, =SystemInit 这条语句的时候就已经开始使用堆栈了,这个时候 SRAM并没有使能,需要先用汇编指令先把这个SRAM使能,才能调用SystemInit 函数
进入debug状态,可以看一下 MSP 指针位置,已经分配到 未使能的区域去了,只要有PUSH指令就会挂
可以参见汇编代码 理解 heluo1985 发表于 2022-4-28 09:37
可以参见汇编代码 理解
厉害了,兄弟,就是这个问题,push的时候不会挂,pop lr的时候会挂{:8:}
我简单改了下,继续使用HAL的API,无需定义DATA_IN_D2_SRAM。
; Reset handler
Reset_Handler PROC
EXPORTReset_Handler
IMPORTSystemInit
IMPORT__main
IMPORT__HAL_RCC_D2SRAM1_CLK_ENABLE1
LDR R0, = __HAL_RCC_D2SRAM1_CLK_ENABLE1
BLX R0
LDR R0, = SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
宏定义没法IMPORT,我直接定义了个函数,跟HAL库的是一样的,仅仅换了个名字。
void __HAL_RCC_D2SRAM1_CLK_ENABLE1(void)
{
SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_D2SRAM1EN);
READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_D2SRAM1EN);
}
heluo1985 发表于 2022-4-28 09:37
可以参见汇编代码 理解
彻底解决了,修改汇编不方便用户操作,不使用官方的DATA_IN_D2_SRAM定义,也不直接在里面调用下面几个函数,这几个函数里面有局部变量(虽然没啥用,但是pop lr出错了)。
__HAL_RCC_D2SRAM1_CLK_ENABLE();
__HAL_RCC_D2SRAM2_CLK_ENABLE();
__HAL_RCC_D2SRAM3_CLK_ENABLE();
手动添加这三组函数到SystemInit末尾即可,简单省事。
SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_D2SRAM1EN);
READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_D2SRAM1EN);
SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_D2SRAM2EN);
READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_D2SRAM2EN);
SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_D2SRAM3EN);
READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_D2SRAM3EN);
高手,膜拜大佬{:34:} eric2013 发表于 2022-4-28 10:25
彻底解决了,修改汇编不方便用户操作,不使用官方的DATA_IN_D2_SRAM定义,也不直接在里面调用下面几个函 ...
这种方法还是由风险的,编译选项 优化等级 可能都有影响,依照效率分配的方案,这三块就不适合用来做堆栈,ITCM DTCM AXI 都可以,我也是最近研究 RAM-ECC 检测才发现这里面的配置,ST的安全库STL 以及 RAM-ECC,以及 操作系统的非特权等级,基本上把底层研究个差不多了,耗费了大概一周的时间 ;P heluo1985 发表于 2022-4-28 11:39
这种方法还是由风险的,编译选项 优化等级 可能都有影响,依照效率分配的方案,这三块就不适合用来做堆栈 ...
已经全部测试了,IAR和MDK AC6 AC5所有优化等级下,只要函数SystemInit里面没有局部变量,他们是不会做push lr操作的,类似内联方式直接调用的。
没有局部变量,函数跳转还做push lr属于多余操作,如果编译器不能识别出这个,是编译器有点low了。
eric2013 发表于 2022-4-28 11:53
已经全部测试了,IAR和MDK AC6 AC5所有优化等级下,只要函数SystemInit里面没有局部变量,他们是不会做pu ...
{:8:} 这个我倒是没有测试优化等级,很多底层也是参考了你的教程 {:34:} 厉害啊!两位都是真正的高手,大赞!! 做了个汇编方式的,加在如下位置即可
;使能D2SRAM1,D2SRAM2,D2SRAM3
LDR r0, =0x580244DC
LDR r1,
ORR r1, r1, #0xE0000000
STR r1,
eric2013 发表于 2022-4-28 14:59
做了个汇编方式的,加在如下位置即可
;使能D2SRAM1,D2SRAM2,D2SRAM3
{:3:}嗯嗯这个方案可以彻底解决问题 太精彩了! heluo1985 发表于 2022-4-28 11:39
这种方法还是由风险的,编译选项 优化等级 可能都有影响,依照效率分配的方案,这三块就不适合用来做堆栈 ...
大佬,RAM-ECC这部分,有没有资料可以共享下呢? guohongguang 发表于 2022-5-3 22:13
大佬,RAM-ECC这部分,有没有资料可以共享下呢?
主要 参阅AN5342这个文档 eric2013 发表于 2022-4-28 14:59
做了个汇编方式的,加在如下位置即可
;使能D2SRAM1,D2SRAM2,D2SRAM3
在cubeide上如何修改呢 jinlei_wang 发表于 2023-11-9 19:54
在cubeide上如何修改呢
仅做了个MDK方式的,注意在systeminit里面初始化不行,前面还有一段C库初始化,系统初始化之类的函数,要在复位中断复位程序里面就搞才可以,CubeIDE方式的你试试,实现不行,先加个前缀const,存到内部Flash,待D2时钟初始化后,再复制到D2 RAM mark一下,一直对这个D2域的SRAM有困惑 Mark,方便回来找
页:
[1]