#include "McuBspSys.h" #include "McuW25Q64JvssiqDrv.h" #include "McuBspSpi.h" #include "McuBspGpio.h" #include "McuBspFlash.h" #include #include /* 关于升级的部分定义 */ #define MCU_TASK_FLASH_UPDATTE_FLAG_ADDRESS 0x222000 // 升级标志位存储空间 #define MCU_TASK_FLASH_UPDATTE_SIZE_ADDRESS 0x222004 // 升级文件大小存储空间 /* 程序1的保存地址 */ #define MCU_TASK_PROGRAM1_START_ADDR 0x000000 #define MCU_TASK_PROGRAM1_END_ADDR 0x07ffff #define MCU_TASK_PROGRAM1_MAX 0x080000 #define DISABLE_INT() __set_PRIMASK(1) /* 禁止全局终端 */ #define ENABLE_INT() __set_PRIMASK(0) /* 使能全局变量 */ #define APP_ADDR 0x8010000 // 应用程序的APP地址 static uint32_t gMcuTaskFlashUpdateProgramFlag = 1; // 升级标志位 static uint64_t gMcuTaskFlashUpdateProgramSize = 0; // 升级文件大小 static W25Q64JVSSIQ_OBJ gFlashObj = {0}; static void MainDelayUs(uint32_t period); static void MainFlashSpiCs(uint8_t flag); static unsigned char MainFlashReadWrite(uint8_t Data); static void McuTaskXfzBootLoaderPrep(void); static void McuTaskXfzBootLoader(void); static void McuTaskXfzJumpToApp(void); int main(void) { /* 初始化系统 */ McuBspSysInit(); McuTaskXfzBootLoaderPrep(); McuTaskXfzBootLoader(); McuTaskXfzJumpToApp(); } static void McuTaskXfzBootLoaderPrep(void) { /* 打开LED灯 */ McuBspGpioInit(GPIOE, GPIO_PIN_3, GPIO_MODE_OUTPUT_PP, GPIO_SPEED_FREQ_LOW, GPIO_PULLDOWN, 0, NULL); McuBspGpioSetLevel(GPIOE, GPIO_PIN_3, MCU_BSP_GPIO_OUT_HIGH); /* 初始化FLASH */ McuBspSpiInit(MCU_BSP_SPI3_ID); gFlashObj.SpiCs = MainFlashSpiCs; gFlashObj.SpiWriteReadByte = MainFlashReadWrite; gFlashObj.DelayUs = MainDelayUs; W25Q64_Init(&gFlashObj); /* 获取升级标志位 */ W25Q64_ReadBytes(&gFlashObj, MCU_TASK_FLASH_UPDATTE_FLAG_ADDRESS, (uint8_t *)(&gMcuTaskFlashUpdateProgramFlag), sizeof(gMcuTaskFlashUpdateProgramFlag)); if (1 != gMcuTaskFlashUpdateProgramFlag) { gMcuTaskFlashUpdateProgramFlag = 0; gMcuTaskFlashUpdateProgramSize = 0; } else { /* 获取升级文件大小 */ W25Q64_ReadBytes(&gFlashObj, MCU_TASK_FLASH_UPDATTE_SIZE_ADDRESS, (uint8_t *)(&gMcuTaskFlashUpdateProgramSize), sizeof(gMcuTaskFlashUpdateProgramSize)); if (gMcuTaskFlashUpdateProgramSize == 0 || gMcuTaskFlashUpdateProgramSize >= 458752) { // 448KB gMcuTaskFlashUpdateProgramSize = 0; gMcuTaskFlashUpdateProgramFlag = 0; } } } static void McuTaskXfzBootLoader(void) { uint32_t i = 0; uint64_t data = 0; if (gMcuTaskFlashUpdateProgramFlag == 1) { /* 插除应用程序的flash */ while (-1 == McuBspFlashErase(ADDR_FLASH_PAGE_32, ((ADDR_FLASH_PAGE_255 - ADDR_FLASH_PAGE_32) / FLASH_PAGE_SIZE) + 1)) { } /* 读取FLASH */ for (i = 0; i < (gMcuTaskFlashUpdateProgramSize / 8); i++) { data = 0; if (0 > W25Q64_ReadBytes(&gFlashObj, MCU_TASK_PROGRAM1_START_ADDR + 8 * i, (unsigned char *)&data, 8)) { // /* 重启 */ // __set_FAULTMASK(1);//关闭所有中断 // NVIC_SystemReset();//复位函数 } if (0 > McuBspFlashWrite64(ADDR_FLASH_PAGE_32 + i * 8, data)) { // /* 重启 */ // __set_FAULTMASK(1);//关闭所有中断 // NVIC_SystemReset();//复位函数 } } data = 0; if (i * 8 < gMcuTaskFlashUpdateProgramSize) { if (0 > W25Q64_ReadBytes(&gFlashObj, MCU_TASK_PROGRAM1_START_ADDR + 8 * i, (unsigned char *)&data, gMcuTaskFlashUpdateProgramSize - (i * 8))) { // /* 重启 */ // __set_FAULTMASK(1);//关闭所有中断 // NVIC_SystemReset();//复位函数 } if (0 > McuBspFlashWrite64(ADDR_FLASH_PAGE_32 + i * 8, data)) { // /* 重启 */ // __set_FAULTMASK(1);//关闭所有中断 // NVIC_SystemReset();//复位函数 } } /* 把Flash的标志位清空 */ gMcuTaskFlashUpdateProgramFlag = 0; W25Q64_WriteBytes(&gFlashObj, MCU_TASK_FLASH_UPDATTE_FLAG_ADDRESS, (uint8_t *)(&gMcuTaskFlashUpdateProgramFlag), sizeof(gMcuTaskFlashUpdateProgramFlag)); } } /* 跳转到应用程序 */ static void McuTaskXfzJumpToApp(void) { uint32_t i = 0; void (*SysJumpToApp)(void); // 声明一个函数指针 __IO uint32_t AppAddr = APP_ADDR; // APP地址 /* 反向初始化使用的外设 */ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_3); // 回复led灯的初始状态 McuBspSpiDeInit(MCU_BSP_SPI3_ID); /* 设置所有时钟到默认状态 */ HAL_RCC_DeInit(); /* 关闭滴答定时器,回复到默认值 */ SysTick->CTRL = 0; SysTick->LOAD = 0; SysTick->VAL = 0; /* 关闭全局中断 */ DISABLE_INT(); /* 关闭所有中断,清除所有中断挂起标志 */ for(i = 0; i < 8; i++) { NVIC->ICER[i] = 0xFFFFFFFF; NVIC->ICPR[i] = 0xFFFFFFFF; } /* 使能全局中断 */ ENABLE_INT(); /* 设置SysJumpToApp为终端服务函数入口地址,首地址是MSP,地址+4是复位中断服务程序地址 */ SysJumpToApp = (void (*)(void))(*((uint32_t *)(AppAddr + 4))); /* 设置主堆栈指针 */ __set_MSP(*((uint32_t *)AppAddr)); /* 设置为特权级模式,SP使用MSP指针 */ __set_CONTROL(0); /* 进行跳转 */ SysJumpToApp(); while (1) { } } static void MainDelayUs(uint32_t period) { uint32_t i = 35; // 35 = 72 / 2 -1; while (period) { while (i) { i--; } period--; i = 35; } } static void MainFlashSpiCs(uint8_t flag) { McuBspSpiCs(MCU_BSP_SPI3_ID, flag); } /* Flash发送 */ static unsigned char MainFlashReadWrite(uint8_t Data) { return McuBspSpiReadWriteByte(MCU_BSP_SPI3_ID, Data); }