Cortex M4 的引导加载程序 - 跳转到加载的应用程序

Posted

技术标签:

【中文标题】Cortex M4 的引导加载程序 - 跳转到加载的应用程序【英文标题】:Bootloader for Cortex M4 - Jump to loaded Application 【发布时间】:2016-05-02 13:18:46 【问题描述】:

我在 Atmel SAM4E-EK 板上使用 Atmel SAM4E-16e。我已经为此配置编写了一个引导加载程序。 引导加载程序通过 UART 接收 .bin 文件并将其写入 Flash。这没有问题,我做了一个十六进制转储,这正是我所期望的:

引导加载程序位于 0x400000(AT SAM4E 的闪存起始地址) 我的申请位于 0x420000 0x800000 是 Fl​​ash 结束地址

这是 C 代码:

int main(void)
     // Init and downloading the .bin to Flash
     binary_exc((void*) 0x420000);




int binary_exec(void * vStart)
    int i;
    // -- Check parameters
    // Should be at least 32 words aligned
    if ((uint32_t)vStart & 0x7F)
    return 1;

    Disable_global_interrupt();
    // Disable IRQs
    for (i = 0; i < 8; i ++) NVIC->ICER[i] = 0xFFFFFFFF;
    // Clear pending IRQs
    for (i = 0; i < 8; i ++) NVIC->ICPR[i] = 0xFFFFFFFF;

    // -- Modify vector table location
    // Barriars
    __DSB();
    __ISB();
    // Change the vector table
    SCB->VTOR = ((uint32_t)vStart & SCB_VTOR_TBLOFF_Msk);
    // Barriars
    __DSB();
    __ISB();

    Enable_global_interrupt();

    // -- Load Stack & PC
    _binExec(vStart);
    return 0;


void _binExec (void * l_code_addr)
    __asm__ ("mov   r1, r0        \n"
    "ldr   r0, [r1, #4]  \n" //I also tryed #5 but that doesn't work, too
    "ldr   sp, [r1]      \n"
    "blx   r0"
    );

但是当我尝试跳转到我的应用程序时,应用程序没有启动。 跳转到程序的代码来自 SAM8X (Cortex M3) 的 Atmel 示例。调试器有时会说 PC 会跳转到另一个地址 (0x004003E2),但不会继续。

我找到了旧主题Bootloader for Cortex M3,解决方案是添加一个,但这对我不起作用,即使我使用了他们的代码。然后调试器不再响应。

我正在使用带有 GCC 的 Atmel Studio 7。处理器以拇指模式运行。

我希望你能帮助我解决这个问题,或者给我一些提示,这里出了什么问题。

【问题讨论】:

您当然需要设置blx 的寄存器的lsb,否则您将尝试交互到不存在的ARM 状态和硬故障。您尝试向哪个地址添加一个(即在此代码中的确切位置)使事情变得更糟? 如果你的代码在 0x420000 那么你想 blx 到 0x420001,那你为什么要读取地址 0x420000 的指令然后尝试跳转到指令定义的地址呢?为什么不 orr r0,#1; blx r0?你的反汇编显示什么地址进入 binary_exec?为什么 binary_exec 中的所有开销?您是否正在尝试处理任何情况,在此之前是否有代码运行使系统处于未知状态? 您可以在对 _binExec 的 C 调用中执行 1 的或,然后 bin exec 只不过是 blx r0。当然,如果该代码返回它会返回到 blx 之后,这可能不是您想要的。 我的新应用程序位于 0x420000,但我需要跳转到 0x420004,因为重置向量位于此地址。这是在汇编代码中。在那里,我还尝试跳转到 0x420005,因为那是 ***.com/questions/12715556/bootloader-for-cortex-m3 的解决方案 【参考方案1】:

此代码假定加载在地址 0x420000 的程序以向量表开头:

SP 偏移量 0 (0x420000) 在偏移量 4 (0x420004) 处重置地址。

为此,代码似乎完全正确。

但是你确定这个向量表是正确的吗? 0x420004 处的数据位 0 是否设置为 Thumb 代码?当您编译此代码时,它是否知道它将从此地址运行(对于它可能使用的任何绝对地址)。您是否有可能使用调试器来了解第一个故障发生的时间?

我认为您应该提供对您尝试在此地址加载的程序的第一条指令的 disass。

【讨论】:

【参考方案2】:

我现在已经解决了这个问题。 我仍然使用我在问题中发布的代码。问题是我在处理器闪存上写入的 .bin 文件 0x420000 的编译方式认为它位于闪存起始地址 (0x400000)。 当它加载复位向量的地址时,它位于 0x400xyz 而不是 0x420xyz,因此应用程序跳转到了错误的地址。

解决办法是在我想通过bootloader上传的项目中将Flash起始地址改为0x420000。

【讨论】:

以上是关于Cortex M4 的引导加载程序 - 跳转到加载的应用程序的主要内容,如果未能解决你的问题,请参考以下文章

通过应用程序跳转到 STM32 中的引导加载程序,即在引导模式下从用户闪存使用引导 0 和引导 1 引脚

在引导加载程序中跳转到0x7C00不会引起无限循环

STM32L073RZ (rev Z) IAP 跳转到引导加载程序(系统内存)

使用 avrdude 对闪存的引导加载程序部分进行编程很慢

Qt/QML:在加载程序加载后访问 ListView 以跳转到特定项目/页面

在 STM32F765 上使用引导加载程序时 J-Link 调试器出现问题