工具/软件:
大家好、我正在使用 mspm0g3519 控制器。 我根据客户安全代码的引用设计了自定义引导加载程序。 我有一个疑问。 为什么建议在运行客户安全代码时使用优化级别 2 或更高版本? 为什么此代码不适用于优化级别 0? 即使我尝试使用其示例应用程序代码运行客户安全代码(来自 SDK 启动映像管理器)示例代码时也是如此。 它只能用于-O2、不能用于-O0。
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具/软件:
大家好、我正在使用 mspm0g3519 控制器。 我根据客户安全代码的引用设计了自定义引导加载程序。 我有一个疑问。 为什么建议在运行客户安全代码时使用优化级别 2 或更高版本? 为什么此代码不适用于优化级别 0? 即使我尝试使用其示例应用程序代码运行客户安全代码(来自 SDK 启动映像管理器)示例代码时也是如此。 它只能用于-O2、不能用于-O0。
您好、
我从 SDK 中获取了客户安全代码和示例。 优化级别 2 的代码即可正常工作。 表示客户安全代码完全跳转到示例代码。 但当我将优化级别更改为 0 (-O0) 时、客户安全代码不会跳转到应用代码。 优化级别是否会影响客户安全代码中的跳转逻辑代码? 这是来自客户安全代码的代码片段。
static void start_app(uint32_t *vector_table)
{
/* The following code resets the SP to the value specified in the
* provided vector table, and then the Reset Handler is invoked.
*
* Per ARM Cortex specification:
*
* ARM Cortex VTOR
*
*
* Offset Vector
*
* 0x00000000 ++++++++++++++++++++++++++
* | Initial SP value |
* 0x00000004 ++++++++++++++++++++++++++
* | Reset |
* 0x00000008 ++++++++++++++++++++++++++
* | NMI |
* ++++++++++++++++++++++++++
* | . |
* | . |
* | . |
*
* */
/* Reset the SP with the value stored at vector_table[0] */
__asm volatile(
"LDR R3,[%[vectab],#0x0] \n"
"MOV SP, R3 \n" ::[vectab] "r"(vector_table));
/* Set the Reset Vector to the new vector table (Will be reset to 0x000) */
SCB->VTOR = (uint32_t) vector_table;
/* Jump to the Reset Handler address at vector_table[1] */
((void (*)(void))(*(vector_table + 1)))();
}代码进入硬故障。 我已检查了两种优化的汇编文件。
Optimization level 2. (code work fine)
0x00001810 4818 ldr r0, [pc, #0x60] ; Load immediate address (string/format) into r0
0x00001812 211F movs r1, #0x1f ; r1 = 0x1F
0x00001814 02CD lsls r5, r1, #0xb ; r5 = 0x1F << 11 (vector table address base)
0x00001816 4629 mov r1, r5 ; Move r5 → r1 (bit_printf arg)
0x0000181C 682B ldr r3, [r5] ; r3 = *(r5) (new stack pointer)
0x0000181E 469D mov r13, r3 ; Set SP = *(r5)
0x00001820 4815 ldr r0, [pc, #0x54] ; Load address (VTOR reg addr) into r0
0x00001822 6005 str r5, [r0] ; Write new vector table base to VTOR
0x00001824 CD06 ldm r5!, {r1, r2} ; Load r1=*(r5), r2=*(r5+4), then r5+=8
0x00001826 4815 ldr r0, [pc, #0x54] ; Reload VTOR addr into r0
0x00001828 3D08 subs r5, #8 ; Restore r5 back (undo ldm increment)
0x0000182E 4811 ldr r0, [pc, #0x44] ; Load another format string address
0x00001830 4629 mov r1, r5 ; r1 = r5
0x00001836 6868 ldr r0, [r5, #4] ; r0 = *(r5+4) (reset handler address)
0x00001838 4780 blx r0 ; Jump to application reset handler
0x0000183A 4620 mov r0, r4 ; r0 = r4 (not used, dead code)
0x0000183C F000FC8E bl DL_Common_delayCycles; Delay (dead code after jump)
Optimization level 0 (not jump to aaplication code)
0x00001AD8 B580 push {r7, r14} ; Save frame pointer and LR
0x00001ADA B082 sub r13, #8 ; Allocate 8 bytes stack
0x00001ADC 9001 str r0, [r13, #4] ; Save argument (app base addr) to stack
0x00001ADE E7FF b #0x1ae0 ; Jump to next instruction (compiler artifact)
0x00001AE0 9901 ldr r1, [r13, #4] ; r1 = saved arg
0x00001AE2 480E ldr r0, [pc, #0x38] ; Load format string addr
0x00001AE8 E7FF b #0x1aea ; Compiler artifact
0x00001AEA 9801 ldr r0, [r13, #4] ; r0 = app base addr
0x00001AEC 6803 ldr r3, [r0] ; r3 = *(app base) (stack pointer value)
0x00001AEE 469D mov r13, r3 ; Set SP = *(app base)
0x00001AF0 9801 ldr r0, [r13, #4] ; r0 = *(app base+4) (reset handler)
0x00001AF2 490B ldr r1, [pc, #0x2c] ; r1 = VTOR address
0x00001AF4 6008 str r0, [r1] ; Write new vector table base
0x00001AF6 E7FF b #0x1af8 ; Compiler artifact
0x00001AF8 9801 ldr r0, [r13, #4] ; r0 = app base
0x00001AFA 6801 ldr r1, [r0] ; r1 = *(app base) (stack pointer value)
0x00001AFC 6842 ldr r2, [r0, #4] ; r2 = *(app base+4) (reset handler addr)
0x00001AFE 4809 ldr r0, [pc, #0x24] ; Load format string addr
0x00001B04 E7FF b #0x1b06 ; Compiler artifact
0x00001B06 E7FF b #0x1b08 ; Compiler artifact
0x00001B08 9901 ldr r1, [r13, #4] ; r1 = app base addr
0x00001B0A 4804 ldr r0, [pc, #0x10] ; Load format string addr
0x00001B10 E7FF b #0x1b12 ; Compiler artifact
0x00001B12 9801 ldr r0, [r13, #4] ; r0 = app base addr
0x00001B14 6840 ldr r0, [r0, #4] ; r0 = *(app base+4) (reset handler addr)
0x00001B16 4780 blx r0 ; Jump to application reset handler
0x00001B18 B002 add r13, #8 ; restore stack after jump
0x00001B1A BD80 pop {r7, pc} ; Restore registers and return它看起来好像 C 代码加载 SP 太早了;使用-O0 时、它随后引用一个(悬空)栈变量、但使用-O2 时则不引用。 (即使有-O2 我会说它“意外工作“。
我不确定这本身是一个编译器错误,因为它无法了解 SP(在__asm () 中是否有一个“clobber"选项“选项?)。
我在 boot_manager/customer_secure_code 中未找到此代码。 您能给我们提示一下它在哪里吗?
[编辑:啊、我在 customer_secure_code.c 中找到了它。]
谢谢、它位于 customer_secure_code.c 中
我想您已经确定了问题、但我不知道 TI 的计划是什么。
“-O2"变通“变通办法是否适合您的用途?
或者:一个相当简单的更改可能是将 vector_table 变量复制到局部“static"(“(.bss 而不是栈)变量、并将其用在函数的其余部分。 .bss 不会移动太多。
[编辑:为了更好地衡量,请将新变量声明为“volatile “,这样优化器就不会得到任何“不正确“的想法。]
嗨 Bruce ,我已经尝试加载 sp,然后调用,但板重新启动再次和 againe 到引导加载程序代码,我放入闪存开始 (0x00000000),这似乎是代码跳到引导加载程序再次.
您是否删除了另一个_asm、即设置 SP 的_asm? 这就是事情开始出错的地方。
具体来说:在-O0 情况下、汇编列表的第 37 行将 SP 设置到应用程序的栈、但随后第 38 行(然后是第 42 行)返回、从(旧)栈中获取 vector_table 的值、该值已消失。
对于-O2 情况、第 8 行设置 SP、但到那时所有局部变量【好的,只有一个】都已在寄存器中、因此不需要返回到栈副本【好的是,因为没有任何】。 优化器不能保证执行此操作、但通常会执行此操作。
理论上、您可以移动将 SP 设置为调用之前最后一个内容的_asm、但调用仍可以引用栈(第 42 行)。 我建议的技巧是让生成的代码查看其他地方、以防止引用栈。 这有点笨拙、但它是正常的 C。[我预计这个代码大约每年执行一次、因此 4 个字节和几个额外的时钟无关紧要。]
也就是说、我在您的_asm 中没有看到任何明显的内容、除非是这样
(a) 您使用的是 R3 、但没有将其声明为(伪)输出参数 — 编译器可能为[vectab]和分配了 R3
(B) 我本来会使用“MOV SP、R3“而不是 MSR、但这主要是因为我不必仔细研究 Cortex-M0 文档、才能记住我是想要 MSP 还是 PSP。
【编辑:轻微澄清。】
具体来说、类似于【未测试】:
static void start_app(uint32_t *vector_table)
{
static uint32_t * volatile bss_vector_ptr; // So it doesn't move
bss_vector_ptr = vector_table;
/* Set the Reset Vector to the new vector table (Will be reset to 0x000) */
SCB->VTOR = (uint32_t) bss_vector_ptr;
/* Reset the SP with the value stored at vector_table[0] */
__asm volatile(
"LDR R3,[%[vectab],#0x0] \n"
"MOV SP, R3 \n" ::[vectab] "r"(bss_vector_ptr));
/* Jump to the Reset Handler address at vector_table[1] */
((void (*)(void))(*(bss_vector_ptr + 1)))();
}
[编辑:固定的 goof]
【编辑:已测试】
或者:
void
start_app(uint32_t *vector_table)
{
SCB->VTOR = (uint32_t) vector_table;
__asm volatile(
"MOV SP,%[newSP] \n"
"BLX %[newPC] \n"
:
:[newSP] "r" (vector_table[0]), [newPC] "r" (vector_table[1])
:
);
return;
}