裸机上未定义的指令MRS

问题描述 投票:0回答:1

我想在 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,但需要手动创建标头,其中包含所有必需的宏。

感谢大家的头脑风暴!

c arm embedded clock bare-metal
1个回答
0
投票

内部时钟分频器需要设置为

CGC_SYS_CLOCK_DIV_2
(制造商 XML 配置的默认值)而不是
CGC_SYS_CLOCK_DIV_1
。我在创建 SDK 时犯了一些错误。

© www.soinside.com 2019 - 2024. All rights reserved.