Thread 中讨论的其他器件:MSPM0G3507、MSPM0-SDK
工具/软件:
您好:
我正在使用 MSPM0G3507的自定义引导加载程序。 该引导加载程序使用 UART 实现、并在将新的十六进制文件写入闪存之前执行 CRC 和版本检查。
在我的引导加载程序中、重置引导加载程序后首先运行、然后在所需位置检查应用程序是否存在(如果不存在)、则跳转到该应用程序、如果不存在、则运行正常的引导加载程序代码。
如果接收到的代码的完整 CRC 和计算出的本地 CRC 匹配、则它最后会跳转到已刷写的新应用程序、但问题是当我通过跳转函数跳转、跳转应用程序的中断不起作用时、它将重置 UC 并从引导加载程序应用程序从0开始。 我之前说过、它将再次检查并跳转到该应用程序。
所以主要的错误是我的中断处理程序从不被执行,从不写入 bootcmd(1 at flash loc 0x0001F058 )。 每次中断我给出 GPIO 中断时、它都会重复。
因为我找不到这个问题、这是我的第一个引导加载程序代码、所以有人能帮我解决这个问题吗? 我附加了跳转函数和 IRQ 处理程序以及链接器文件。
链接器命令文件
#include "ti_msp_dl_config.h" #include "string.h" #include "stdio.h" #include "core_cm0plus.h" #define BOOTLOADER_VECTOR_TABLE_ADDRESS 0x00000000 #define BOOTLOADER_INT_LOCATION 0x0001F058 /* At this location flag set by applicant who wish to turn on boot mode to flesh nex hex */ #define VTOR_OFFSET (uint32_t *)0x00003E80 #define NO_ERROR 0 #define ERROR_WRITE_32_BIT 6 void jump_to_app(uint32_t); uint8_t BootCmdWrite(uint32_t); volatile uint8_t gErrorType = NO_ERROR; volatile DL_FLASHCTL_COMMAND_STATUS gCmdStatus; uint32_t gCmd32 = 0x00000001; uint32_t gCmdTemp; int main(void) { //early_irq_enable(); SYSCFG_DL_init(); SCB->VTOR = (uint32_t)VTOR_OFFSET; __enable_irq(); NVIC_ClearPendingIRQ(USR_BOOT_INT_IRQN); NVIC_EnableIRQ(USR_BOOT_INT_IRQN); while (1) { DL_GPIO_togglePins(USER_LED_PORT, USER_LED_RED_LED_PIN); delay_cycles(16000000); } } void GROUP1_IRQHandler(void) { switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) { case USR_BOOT_INT_IIDX: /* If SW is high, turn the LED off */ if (DL_GPIO_readPins(USR_BOOT_PORT, USR_BOOT_BT_PIN_PIN)) { BootCmdWrite(gCmd32); DL_GPIO_togglePins(RGB_PORT, RGB_GREEN_LED_PIN); delay_cycles(64000000); jump_to_app(BOOTLOADER_VECTOR_TABLE_ADDRESS); // NVIC_SystemReset(); } break; default : break; } } uint8_t BootCmdWrite(uint32_t cmd) { if (gErrorType == NO_ERROR) { DL_FlashCTL_unprotectSector(FLASHCTL, BOOTLOADER_INT_LOCATION, DL_FLASHCTL_REGION_SELECT_MAIN); // gCmdStatus = DL_FlashCTL_programMemoryFromRAM64WithECCGenerated( // FLASHCTL, BOOTLOADER_INT_LOCATION, &cmd32[0]); DL_FlashCTL_programMemoryFromRAM32WithECCGenerated( FLASHCTL, BOOTLOADER_INT_LOCATION, &cmd); // Ensure write is fully committed __DSB(); // Data Synchronization Barrier __ISB(); // Instruction Synchronization Barrier if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED) { /* If command was not successful, set error flag */ gErrorType = ERROR_WRITE_32_BIT; } DL_FlashCTL_protectSector(FLASHCTL, BOOTLOADER_INT_LOCATION, DL_FLASHCTL_REGION_SELECT_MAIN); gCmdTemp = *(uint32_t *)BOOTLOADER_INT_LOCATION; } return gErrorType; } void HardFault_Handler(void) { // Debug indicator - blink LED or breakpoint while (1) { DL_GPIO_togglePins(RGB_PORT, RGB_GREEN_LED_PIN); for (volatile int i = 0; i < 100000; i++); // Simple delay } } void jump_to_app(uint32_t app_addr) { __disable_irq(); // Disable and clear all interrupts for (uint32_t i = 0; i < 8; i++) { NVIC->ICER[i] = 0xFFFFFFFF; // Disable IRQs NVIC->ICPR[i] = 0xFFFFFFFF; // Clear pending IRQs } __DSB(); __ISB(); // Reset SysTick just in case SysTick->CTRL = 0; SysTick->LOAD = 0; SysTick->VAL = 0; uint32_t sp = *((uint32_t *)app_addr); // Stack pointer uint32_t reset = *((uint32_t *)(app_addr + 4)); // Reset handler __set_MSP(sp); SCB->VTOR = app_addr; // If needed ((void (*)(void))reset)(); // Jump to reset handler }