pic32跳出引导加载程序会导致一般异常

时间:2014-07-28 18:38:22

标签: c assembly mips pic pic32

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

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

其中APPLICATION_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跳转,2之间的唯一区别是它们如何将指针加载到寄存器中。有没有人有任何想法?

2 个答案:

答案 0 :(得分:2)

我不知道你是否已经报道此案。但是,您可能遇到的一个问题是,您可能在跳转到应用程序时运行中断。虽然Microchip没有在Application Note on the PIC 32 Bootloader - AN1388中明确涵盖这种情况,但如果发生中断并且您正在应用程序中设置启动代码,则可能会导致错误的地址 - 很多这取决于您的启动代码的设置方式。

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

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

//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.

希望这会给你一个看的地方。我没有看到你如何调用跳跃的任何问题。

答案 1 :(得分:1)

我知道这不是原因的答案,但我使用与微芯片AN1388相同的方法跳转到我的引导程序:

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

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