lpc 1768 辅助引导加载程序错误

lpc 1768 Secondary Boot Loader error

我正在研究 lpc 1768 SBL,它包含以下代码以跳转到用户应用程序。

#define NVIC_VectTab_FLASH           (0x00000000)
#define USER_FLASH_START             (0x00002000)
void NVIC_SetVectorTable(DWORD NVIC_VectTab, DWORD Offset)
{ 
   NVIC_VECT_TABLE = NVIC_VectTab | (Offset & 0x1FFFFF80);
}
void execute_user_code(void)
{


    void (*user_code_entry)(void);
    /* Change the Vector Table to the USER_FLASH_START 
    in case the user application uses interrupts */
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, USER_FLASH_START);


    user_code_entry = (void (*)(void))((USER_FLASH_START)+1);
    user_code_entry();

}

它运行正常,没有任何错误。在代码中加入一些堆内存后,机器就卡住了。我为堆尝试了不同的值。他们中的一些人正在工作。经过一些深入的调试,我发现当应用程序 bin 文件的第一个位置有一个可以被 64 整除的值时,机器没有卡住。

当我select 堆内存为 0x00002E90 时,它生成堆栈基为 0x10005240 。然后堆栈基址 + 堆栈大小 (0x2900) 给出一个值 = 0x10007B40。 我发现这是在应用程序 bin 文件的第一个位置加载的。这个值可以被64整除,代码是运行没有卡死

但是,当我 select 堆内存为 0x00002E88 时,它生成的堆栈基数为 0x10005238。然后堆栈基址 + 堆栈大小 (0x2900) 给出一个值 = 0x10007B38。 这个值不能被64整除,代码卡死

本例反汇编如下

从地址 0x0000 2000 步进时,它会转到硬故障处理程序。但在较早的情况下,它不会成为硬错。它继续并且也有效。

我无法理解指令 DCW 以及它为什么会出现硬故障。 谁能告诉我这背后的原因?

执行向量 table 是你在较旧的 ARM7/ARM9 部件(或更大的 Cortex-A 部件)上执行的操作,其中向量是指令,第一个条目将跳转到重置处理程序,但在 Cortex-M 上,向量 table 是纯数据 - 第一个条目是您的初始堆栈指针,第二个条目是重置处理程序的 地址 -所以尝试执行它很容易出错..

碰巧,在这种情况下,您 可以 实际上完全偶然地执行了该向量的大部分 table,因为内存布局导致每个半字的闪存地址变成相当无害的指令:

2: 1000    asrs  r0, r0, #32
4: 20d9    movs  r0, #217    ; 0xd9
6: 0000    movs  r0, r0
8: 20f5    movs  r0, #245    ; 0xf5
a: 0000    movs  r0, r0
...

直到你最终把所有剩余的 NOP 都弄乱到 0x20d8 ,你在那里找到了真正的入口点。然而,杀手是初始堆栈指针,因为由于 RAM 更高,你得到这个:

0: 7b38    ldrb  r0, [r7, #12]

0x7bxx 的低字节是基址寄存器的编码位置,因此通过改变地址,您可以确定是哪个寄存器,此外,其中留下的任何垃圾值是否也恰好是有效的要加载的地址。你觉得幸运吗?

总之,总结一下:与其直接调用向量 table 的地址,不如从中加载第二个字,然后调用任何地址 that包含。