pic32跳出引导加载程序导致一般异常
我有一个mplabx项目,其中有一个定制的引导加载程序和用于PIC32MX795F512L的应用程序。在整个开发过程中,我一直在从引导加载程序跳到应用程序,使用这行代码没有问题:pic32跳出引导加载程序导致一般异常,c,assembly,mips,pic,pic32,C,Assembly,Mips,Pic,Pic32,我有一个mplabx项目,其中有一个定制的引导加载程序和用于PIC32MX795F512L的应用程序。在整个开发过程中,我一直在从引导加载程序跳到应用程序,使用这行代码没有问题: ((void (*)(void))(APPLICATION_RESET_ADDRESS))(); 其中APPLICATION\u RESET\u ADDRESS是一个宏,其中包含我的应用程序的重置处理程序的地址。在最近对引导加载程序进行了一些修改之后,在执行该行之后的某个时候,在进入应用程序的main函数之前,我突然
((void (*)(void))(APPLICATION_RESET_ADDRESS))();
其中APPLICATION\u RESET\u ADDRESS
是一个宏,其中包含我的应用程序的重置处理程序的地址。在最近对引导加载程序进行了一些修改之后,在执行该行之后的某个时候,在进入应用程序的main
函数之前,我突然开始进入通用异常处理程序。奇怪的是,如果我在那一行上设置一个断点,然后在中断后继续,它就可以正常工作了。此外,如果我将跳转到应用程序的方式更改为:
asm volatile
(
"JALR %0"
:
:"r"(APPLICATION_RESET_ADDRESS)
:
);
它毫无问题地跳转到应用程序,这确实令人困惑,因为生成程序集的是:((void(*)(void))(application\u RESET\u ADDRESS))代码>是
LUI v0,-25341
ADDIU V0, V0, -28672
JALR V0
NOP
以及由以下程序生成的程序集:
asm volatile
(
"JALR %0"
:
:"r"(APPLICATION_RESET_ADDRESS)
:
);
是
因此,两种方法使用相同数量的指令,并且都使用JALR跳转。2之间的唯一区别是它们如何将指针加载到寄存器中。有人有什么想法吗?我知道这不是原因的答案,但我使用了与microchip的AN1388相同的方法跳转到我的引导加载程序:
void jump_to_app(void)
{
void (*fptr)(void);
fptr = (void (*)(void))USER_APP_RESET_ADDRESS;
fptr();
}
它可以工作,我们的产品中有一个相当复杂的引导加载程序/应用程序组合。我不知道您是否已经介绍过这个案例。但是,您可能遇到的一个问题是,您可能在跳转到应用程序时正在运行中断。虽然Microchip没有明确地覆盖它们的这种情况,但如果出现中断,并且在应用程序中设置启动代码的过程中,您可能会向一个不正确的地址传递向量,这很大程度上取决于启动代码的设置方式。
最好在跳转到应用程序之前禁用中断。
如果您查看for microchip,您可以看到它们在跳转到应用程序之前禁用中断。下面是他们的代码和我自己的评论:
//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.
希望这能给你找个地方看看。我看不出您如何调用跳转有任何问题。((void(*)(void))(应用程序重置地址))代码>应该与此函数执行相同的操作。问题是,即使我的内联汇编也可以工作,但是如果我不知道为什么一个方法可以工作,而另一个方法不行,我不知道将来什么时候/是否会再次发生。哦,我同意你的看法,你是否碰巧调查了异常代码以了解问题所在?查看覆盖弱处理程序并在那里中断以检查错误代码。您的应用程序\u RESET\u地址的值是多少?@embedded\u guy 0x9D029000可能是您在启动代码中更改的其他内容?我看不出有什么理由不能基于上面的内容跳转到应用程序。你有没有在引导中运行的中断?@embedded_guy我有几个在引导加载程序中运行的中断,包括两个定时器和一个以太网中断。但这会影响到什么吗?我以为中断会在返回时恢复所有被破坏的寄存器。如果您还没有这样做,我会在跳转到应用程序之前尝试禁用所有中断。它现在似乎正在工作,所以我希望中断是罪魁祸首。我还关闭了DMA以确保这不是问题的一部分。不过,只有时间能证明这一点。我很高兴这对你有帮助。禁用DMA也是一个好主意。
//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.