我有一个带有自定义引导程序和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之间的唯一区别是它们如何将指针加载到寄存器中。有没有人有任何想法?
答案 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();
}
它有效,我们的产品中有一个非常复杂的引导加载程序/应用程序组合。