我想在 Renesas Synergy R7FS5D97E 评估板 (Cortex M4) 上运行简单的 C 测试代码。我使用官方材料制作了一个示例项目+ SDK和工具链项目,使用Ozone调试器成功构建并刷新了它。
但是,当我运行它时,启动时会引发异常:在函数
MRS R1, PRIMASK
中执行R_BSP_RegisterProtectEnable
时出现HardFault,带有未定义的指令标志。
如果第一次执行该指令时发生这种情况,这是可以理解的,但事实并非如此——事实上,大约是在程序运行期间执行该指令(在这个确切的函数中,甚至与 PRIMASK 寄存器的值相同)大约第 15 次,所以这个硬件不能简单地不支持它。
我设法追踪错误发生的位置:在
R_BSP_RegisterProtectEnable
(HW_CGC_HardwareLock
) -> SystemInit
(system_S5D9.c:171
) -> bsp_clock_init
(bsp_clocks.c:150
) 之后调用 R_CGC_SystemClockSet
/r_cgc.c:707
-> r_cgc_system_dividers_set
(r_cgc.c:2637
),所以我想知道这是否可能是某种时钟配置问题?在 Ozone 中,我只是使用为此板提供的默认设置。
或者,我在准备这个 SDK 和工具链时可能犯了一个错误 - 我必须从 Renesas 配置文件中手动拼凑出一个纯 Conan+CMake 项目,也许我错过了一些东西。尽管如此,这条特定指令失败是没有意义的。它只是将特殊寄存器值复制到通用寄存器。
几年前,我在不同的 Renesas Synergy 板上运行过同样的事情(不同的 SDK 和工具链文件),并且在那里遇到了相当多的麻烦,但从来没有这个 - 它最终成功了。
附上错误发生前的系统状态和来自Ozone的HardFault详细信息,因为我无法将其复制为文本。
SDK项目、工具链项目;我认为示例项目并不重要,因为错误发生在启动过程中,但如果需要,我可以上传它。
UPD:在此分支中设置ICLK分频器和时钟源时会发生错误。时钟源首先在函数
r_cgc_clock_source_set
中设置,该函数调用R_BSP_RegisterProtectDisable
,执行存储并调用R_BSP_RegisterProtectEnable
。 R_BSP_RegisterProtectEnable
中的第一条指令是MRS R1, PRIMASK
,这里执行成功。汇编(内联函数):
LDR.W R8, [R7, #28]
BL R_BSP_RegisterProtectDisable
LDRB.W R3, [R8, #38]
BFI R3, R6, #0, #3
MOV R0, R5
STRB.W R3, [R8, #38]
BL R_BSP_RegisterProtectEnable
然后调用函数
r_cgc_system_dividers_set
(源链接)。组装(这次是非内联):
LDR R0, [R7, #28]
MOV R1, R4
BL r_cgc_system_dividers_set
~~~
PUSH {R4-R6, LR}
LDRB R2, [R1]
LDRB R3, [R1, #1]
LDRB R6, [R1, #2]
LDRB R5, [R1, #3]
MOVS R4, #0
AND R3, R3, #7
BFI R4, R2, #12, #3
LDR R2, =gp_cgc_feature ; [PC, #64] [0x00001CC0] =0x1FFE0214
BFI R4, R3, #8, #3
LDR R2, [R2]
BFI R4, R6, #4, #3
LDRB R6, [R1, #4]
LDRB.W R2, [R2, #42]
BFI R4, R5, #0, #3
LDRB R5, [R1, #5]
LDRB R1, [R1, #6]
BFI R4, R6, #16, #3
BFI R4, R5, #28, #3
BFI R4, R1, #24, #3
MOV R5, R0
LSLS R2, R2, #29
IT MI
BFIMI R4, R3, #16, #3
MOVS R0, #0
BL R_BSP_RegisterProtectDisable
STR R4, [R5, #32]
MOVS R0, #0
POP.W {R4-R6, LR}
B.W R_BSP_RegisterProtectEnable
这次,
MRS R1, PRIMASK
中的第一条指令R_BSP_RegisterProtectEnable
改为抛出未定义的指令错误。
它真的开始散发出糟糕的时钟配置的臭味,但是这个代码是从瑞萨网站下载的,适用于这个确切的设备,所以我不敢修改它,除非我确切地知道该怎么做。这就是我的问题。
UPD2:
bsp_clock_cfg.h
中的内部时钟分频器与制造商的文件不匹配!我要么犯了一个拼写错误,要么重用了另一个项目中的文件,并且没有注意到问题,因为 /1 似乎是一个不错的内部时钟分频器,但将其更改为 /2 修复了此错误。也许它导致从闪存获取指令/预取仅在尝试解码后完成...
请注意,此文件通常由瑞萨软件根据 XML 配置(包括默认值)自动生成。我找到了这些 XML,但需要手动创建标头,其中包含所有必需的宏。
感谢大家的头脑风暴!
内部时钟分频器需要设置为
CGC_SYS_CLOCK_DIV_2
(制造商 XML 配置的默认值)而不是 CGC_SYS_CLOCK_DIV_1
。我在创建 SDK 时犯了一些错误。