3

我有一个 mplabx 项目,其中包含 PIC32MX795F512L 的自定义引导加载程序和应用程序。在整个开发过程中,我一直从引导加载程序跳转到应用程序,使用以下行没有问题:

((void (*)(void))(APPLICATION_RESET_ADDRESS))();

whereAPPLICATION_RESET_ADDRESS是一个宏,其中包含我的应用程序的重置处理程序的地址。在最近对引导加载程序进行了一些修改之后,我突然在执行该行之后和进入应用程序功能之前的某个时间开始进入通用异常处理main程序。奇怪的是,如果我在该行上设置一个断点,然后在中断后继续它工作正常。此外,如果我将跳转到应用程序的方式更改为:

asm volatile
(
    "JALR %0"
    :
    :"r"(APPLICATION_RESET_ADDRESS)
    :
);

它毫无问题地跳转到应用程序,这真的很令人困惑,因为生成的程序集是((void (*)(void))(APPLICATION_RESET_ADDRESS))();

LUI v0,-25341
ADDIU V0, V0, -28672
JALR V0
NOP

和生成的程序集:

asm volatile
(
    "JALR %0"
    :
    :"r"(APPLICATION_RESET_ADDRESS)
    :
);

LUI V0, -25342
ORI V0, V0, -28672
JALR V0
NOP

所以这两种方法都使用相同数量的指令,并且都使用 JALR 跳转,两者之间的唯一区别是它们如何将指针加载到寄存器中。有人有什么想法吗?

4

2 回答 2

2

我不知道你是否已经报道过这个案例。但是,您可能遇到的一个可能问题是您在跳转到应用程序时可能会运行中断。虽然 Microchip 在其关于 PIC 32 引导加载程序 - AN1388的应用笔记中没有明确涵盖这种情况,但如果发生中断并且您正在设置启动代码应用程序 - 这很大程度上取决于您的启动代码是如何设置的。

在跳转到您的应用程序之前禁用中断总是一个好主意。

如果您查看微芯片的AN1388 源代码,您会看到它们在跳转到应用程序之前禁用中断。下面是他们的代码和我自己的评论:

//Enter firmware upgrade mode if there is a trigger or if the
//application is not valid.
if(CheckTrigger() || !ValidAppPresent())
{
    TRANS_LAYER_Init(pbClk);  //  Init the transport layer...
                              //Interrupts are enabled during
                              //this function.
    while(!FRAMEWORK_ExitFirmwareUpgradeMode())
    {
        /* Keep receiving commands from the PC */
        ...
    }

    TRANS_LAYER_Close();  //   This is just a wrapper that
                          //makes a call to a function which
                          //disables all interrupts.
}

JumpToApp();  //Similar to your function.

希望这会给你一个地方看。我看不出你如何调用跳转有任何问题。

于 2014-07-29T20:40:07.160 回答
1

我知道这不是为什么的答案,但是,我使用与微芯片中的 AN1388 相同的方法跳转到我的引导加载程序:

void jump_to_app(void)
{
    void (*fptr)(void);
    fptr = (void (*)(void))USER_APP_RESET_ADDRESS;
    fptr();
}

它可以工作,我们的产品中有一个非常复杂的引导加载程序/应用程序组合。

于 2014-07-28T19:50:00.560 回答