This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP432E401Y:自定义引导加载程序无法跳转到 APP

Guru**** 2502205 points
Other Parts Discussed in Thread: MSP432E401Y

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1543326/msp432e401y-custom-bootloader-cannot-jump-to-app

器件型号:MSP432E401Y


工具/软件:

我们需要通过 UART6 实现固件升级、而无需使用 BSL Rocket。 为了实现这一点、我们从空 CCS 工程开始构建了一个自定义 BSL。

为了支持双映像存储、我们修改了链接器脚本中的闪存原点、以便:

  • BSL 的起始位置 0x00000000
  • 应用程序从开始 0x00004000

为了从 BSL 跳转到应用程序、我们使用以下调用函数:

    NVIC->0xffffffff[0]= ICER
    NVIC->0xffffffff[1]= ICER
    NVIC->0xffffffff[2]= ICER
    NVIC->0xffffffff[3]= ICER

    SCB->VTOR = APP_START_ADDRESS
    uint32_t sp =*((uint32_t *) app_start_address);
    __ set_msp;
    ((void (*)(void)) app_start_address)();

但是、我们目前无法跳转 从 BSL 传输到应用程序 从应用程序返回到 BSL。

两个映像在放置于0x00000000时均可正确执行、但一旦我们使用链接器脚本调整原点、映像就无法运行。 我们想了解解决问题的原因并确定需要采取哪些步骤。 谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid=“663553" url="“ url="~“~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1543326/msp432e401y-custom-bootloader-cannot-jump-to-app

    为了支持双映像存储、我们修改了链接器脚本中的闪存原点、以便:

    • BSL 的起始位置 0x00000000
    • 应用程序从开始 0x00004000
    [/报价]

    您好、

     是否表示应用程序已编程为 0x4000? 您能否仔细检查应用程序是否确实在那里编程? 您可以使用 CCS 存储器浏览器查看 0x4000 处的闪存。

     另一个需要检查的问题是您是如何构建应用的? 您是否构建了从 0x4000 开始的应用程序? 您说该应用程序在 0x0 下工作。 我假设您更改应用程序的链接器、以便将其分配给 0x4000。  

    [引用 userid=“663553" url="“ url="~“~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1543326/msp432e401y-custom-bootloader-cannot-jump-to-app

    为了从 BSL 跳转到应用程序、我们使用以下调用函数:

        NVIC->0xffffffff[0]= ICER
        NVIC->0xffffffff[1]= ICER
        NVIC->0xffffffff[2]= ICER
        NVIC->0xffffffff[3]= ICER

        SCB->VTOR = APP_START_ADDRESS
        uint32_t sp =*((uint32_t *) app_start_address);
        __ set_msp;
        ((void (*)(void)) app_start_address)();
    [/报价]

    您似乎没有使用 C:\ti\simplelink_msp432e4_SDK_4_20_00_12\source\ti\devices\msp432e4\boot_loader\bl_startup_ccs.s 从 BSL 跳转到应用程序。 看起来您的引导加载程序是用 C 语言编写的、而不是用汇编语言编写的、就像在 BL_startup_ccs.s 中一样

    以下示例从引导加载程序(基于 C 代码)跳转到从 0x8100 开始的应用程序。  

    #include <stdint.h>
    #include <stdbool.h>
    #include <string.h>
    #include <stdio.h>
    
    /* driverlib header files */
    #include <inc/hw_memmap.h>
    #include <driverlib/uart.h>
    #include <inc/hw_types.h>
    #include <driverlib/sysctl.h>
    #include <driverlib/gpio.h>
    #include <driverlib/pin_map.h>
    #include <inc/hw_nvic.h>
    
    static char message_buffer[128];
    
    /* Address of the reset vector of the application control is transferred to */
    #define APP_RESET_VECTOR_ADDR 0x8100
    const uint32_t *const app_reset_vector = (const uint32_t *) APP_RESET_VECTOR_ADDR;
    
    /*
     * Transfer control to application in flash, given a pointer to the reset vector which gives the initial stack pointer
     * and the program counter to transfer to.
     *
     * Defined as a naked function as doesn't return and uses inline assembler assuming the reset_vector argument is passed in r0
     */
    __attribute__((naked)) static void transfer_to_app (const uint32_t *const reset_vector)
    {
        asm (" ldr r1,[r0]");      /* Initial stack pointer */
        asm (" mov sp,r1");
        asm (" ldr r0, [r0, #4]"); /* Initial program counter */
        asm (" bx r0");
    }
    
    
    int main(void)
    {
        uint32_t SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |SYSCTL_CFG_VCO_480), 120000000);
    
        /* Enable UART to allow an indication that the boot loader is running */
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        while (!SysCtlPeripheralReady (SYSCTL_PERIPH_GPIOA))
        {
        }
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        while (!SysCtlPeripheralReady (SYSCTL_PERIPH_UART0))
        {
        }
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        UARTConfigSetExpClk(UART0_BASE, SysClock, 115200,
                            UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
    
        /* Report that the bootloader is running */
        snprintf (message_buffer, sizeof (message_buffer),
                  "\n\rBootloader running\n\rTransfering to application with SP=0x%08x PC=0x%08x\n\r",
                  app_reset_vector[0], app_reset_vector[1]);
        const size_t message_len = strlen (message_buffer);
        size_t message_index;
        for (message_index = 0; message_index < message_len; message_index++)
        {
            UARTCharPut (UART0_BASE, message_buffer[message_index]);
        }
    
        /* Wait until all the message has completed transmission before resetting the UART */
        while (UARTBusy (UART0_BASE))
        {
        }
    
        /* Reset the peripherals used to output the above message */
        SysCtlPeripheralReset (SYSCTL_PERIPH_UART0);
        SysCtlPeripheralDisable (SYSCTL_PERIPH_UART0);
        SysCtlPeripheralReset (SYSCTL_PERIPH_GPIOA);
        SysCtlPeripheralDisable (SYSCTL_PERIPH_GPIOA);
    
        /* Set the vector table to the beginning of the application in flash.
         * For the TI-RTOS based application this doesn't seem necessary for the application to run, since TI-RTOS
         * defaults to a minimum set of exception vectors in flash before moving the vector table to RAM and installing
         * device specific interrupt handlers. */
        HWREG(NVIC_VTABLE) = (int32_t) app_reset_vector;
    
        /* Transfer control to the application - doesn't return */
        transfer_to_app (app_reset_vector);
    
    	return 0;
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    感谢您的答复。

    是的、我们已经使用 CCS Memory Browser 验证了应用程序是否在指定位置正确编程。
    为了更改应用程序的位置、我们更新了链接器脚本以将闪存原点设置为 0x4000。 我们还应该修改什么内容吗?

    我们测试了该示例并将 APP_RESET_VECTOR_ADDR 设置为 0x4000、但遗憾的是、应用程序仍然无法按预期运行。 这一次、运行 transfer_to_app (app_reset_vector) 时、它会卡在 startup_msp432e401y_ccs.c 中的默认处理程序。

    顺便说一下、我们没有找到 inc/hw_memmap.h 和 inc/hw_types.h

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    运行 transfer_to_app (app_reset_vector) 时、它会卡在 startup_msp432e401y_ccs.c 中的默认处理程序处。

    它在哪里卡住了?  您能否检查地址 0xE000ED08 处的 NVIC_vtable 是否更新为 0x4000?

    HWREG (NVIC_vtable)=(int32_t) APP_RESET_VECTOR;

    /*将控制权转移到应用程序 — 不返回*/
    transfer_to_app (app_reset_vector);

    顺便说一下、我们没有找到 inc/hw_memmap.h 和 inc/hw_types.h

    示例代码适用于与 MSP432E 相同的 TM4C129 芯片、但使用 TivaWare 而不是 MSP432E SDK。 两个实例。  对于 MSP432E、可将#include 部分替换为以下内容。

    #include
    #include
    #include
    #include
    #include “ti/devices/msp432e4/driverlib/driverlib.h"</s>“

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    您提供的示例现在正在成功运行;但是、我们自己的代码仍然无法按预期运行。
    我们怀疑该问题可能与闪存编程过程有关。
    我们将继续调查—非常感谢您的支持!