Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
pic32跳出引导加载程序导致一般异常_C_Assembly_Mips_Pic_Pic32 - Fatal编程技术网

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

pic32跳出引导加载程序导致一般异常,c,assembly,mips,pic,pic32,C,Assembly,Mips,Pic,Pic32,我有一个mplabx项目,其中有一个定制的引导加载程序和用于PIC32MX795F512L的应用程序。在整个开发过程中,我一直在从引导加载程序跳到应用程序,使用这行代码没有问题: ((void (*)(void))(APPLICATION_RESET_ADDRESS))(); 其中APPLICATION\u RESET\u ADDRESS是一个宏,其中包含我的应用程序的重置处理程序的地址。在最近对引导加载程序进行了一些修改之后,在执行该行之后的某个时候,在进入应用程序的main函数之前,我突然

我有一个mplabx项目,其中有一个定制的引导加载程序和用于PIC32MX795F512L的应用程序。在整个开发过程中,我一直在从引导加载程序跳到应用程序,使用这行代码没有问题:

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