【问题标题】:Stm32f4 Memory Jumpingstm32f4 内存跳转
【发布时间】:2013-05-05 14:43:34
【问题描述】:

我正在使用 stm32f4 探索板,我试图跳转到闪存的一部分,在那里我将开始执行另一个程序。变量ApplicationAddress 是 0x08008000。当我的代码到达此部分时,PC 会转到 0x0000000 并且系统会死机。我不确定到底发生了什么。感谢您的时间。我的跳转代码如下所示。

    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000);  
    JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
    Jump_To_Application = (pFunction) JumpAddress;
    /* Initialize user application's Stack Pointer */
    __set_MSP(*(__IO uint32_t*) ApplicationAddress);
    Jump_To_Application();

【问题讨论】:

  • 一堆问题:0x08008000这两个字的内容是什么?你是说一旦Jump_To_Application() 被执行,PC 就会以0 结束?您是否有可以在汇编级别单步执行的调试器设置?您是否有可以将文本转储到以进行调试写入的串行端口?
  • 有一个适用于任何 ARM Cortex-M 设备的通用解决方案,详细信息如下:stackoverflow.com/questions/14393715/…。因此这是重复的。
  • 对不起,Clifford,我搜索了一个类似的帖子,但我没有看到这个。
  • 所以汇编方法适用于返回主程序起始地址@0x08000000,而不是另一个程序的地址@0x08008000。你知道为什么会这样吗?
  • 我遇到的另一件事;当您编译要跳转到的程序时,请确保将该项目的设置更改为从您要跳转到的地址 0x 开始。

标签: memory embedded stm32


【解决方案1】:

大概你在他的问题中发布的那段代码实际上是在使用 MSP 堆栈,所以当你执行时:

__set_MSP(*(__IO uint32_t*) ApplicationAddress);

该堆栈被丢弃,如果 Jump_To_Application 变量是一个局部变量(如果它是一个局部变量,它可能已经在堆栈上 - 特别是如果您正在运行非优化/调试构建)可能会突然垃圾。

为了解决这个问题,我使用了:

void LoadStackAndGo( void* sp, void* entry)
{
    __asm (
        "mov sp, r0 \n"
        "mov pc, r1 \n"
    );
}

应该很容易适应您正在使用的任何工具链。

【讨论】:

  • 一个 Cortex-M 可执行文件通常在起始地址有向量表,并且该表包含一个初始堆栈指针和 PC。因此只需传递向量表的地址,并从前两个 32 位字加载 SP 和 PC。在此之前,还需要重置 SCB:VTOR 寄存器以指向起始地址,甚至在此之前禁用中断。
【解决方案2】:

我遇到了完全相同的问题,但是我的解决方案是:

__set_MSP (*(__IO uint32_t*)ApplicationAddress);

__set_PSP (*(__IO uint32_t*)ApplicationAddress);

并将函数指针声明为静态...

static Function jumpToApplication = (Function) * (__IO uint32_t*)(ApplicationAddress + 4);

【讨论】:

    猜你喜欢
    • 2019-01-28
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 2013-07-26
    相关资源
    最近更新 更多