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

标签 c assembly mips pic pic32

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

((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 跳转,两者之间的唯一区别在于它们如何将指针加载到寄存器中。有人有什么想法吗?

最佳答案

不知道您是否已经报道过这个案例。但是,您可能遇到的一个可能的问题是,您可能在跳转到应用程序时运行中断。尽管 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.

希望这能为您提供一些可看的地方。我没有发现您调用跳转的方式有任何问题。

关于c - pic32 跳出引导加载程序导致一般异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25002003/

相关文章:

c - 在 C 中初始化 3 维字符数组

c++ - GCC 发出用于 boost::shared_ptr 取消引用的额外代码

MIPS 汇编语言

assembly - MIPS 中的 "Long call"函数是什么意思

c - socket connect() 返回 errno EINVAL

java - 我应该如何编写 .i 文件以用 Java 或 C# 包装回调

c - 在多线程程序中执行另一个程序

function - Delphi - 编写带有函数的 .pas 库

c++ - C++ 函数如何返回大对象或结构?

assembly - mips 类型 R、I 和 J、RS、RT 和 RD 字段长度