#include "main.h" #include "string.h" #include "stdio.h" #include "usart.h" #include "iap.h" #include "dataHandling.h" #include "md5c.h" #include "stdbool.h" typedef void (*iapfun)(void); iapfun jump2app; __asm void MSR_MSP(uint32_t addr) { MSR MSP, r0 //set Main Stack value BX r14 } typedef void (*pFunction)(void); void jump_to_app(uint32_t app_addr) { // Step 1: 关闭中断 __disable_irq(); // Step 2: 将设备的运行代码地址设置为主堆栈指针(MSP) __set_MSP(*(volatile uint32_t*)app_addr); // Step 3: 跳转到设备的运行代码 pFunction app_entry = (pFunction)(*(volatile uint32_t*)(app_addr + 4)); app_entry(); } uint8_t YmodemID; uint8_t startFrame[40] = {0}; uint16_t version[4]; uint16_t length[3]; uint8_t binName[32] = {0}; uint8_t binLength[10] = {0}; uint8_t binMd5[16] = {0}; uint16_t iapbinMd5[8] = {0}; uint16_t iapbinMd5_1[8] = {0}; uint16_t FileBuffArray[512]; uint16_t FileBuffArray1[512]; uint16_t start_addr = 0; uint16_t packIndex = 0; uint16_t addrIndex = 0; uint16_t packTotalNum = 0; uint16_t packIndexbak = 0; uint16_t crcIAP = 0; uint16_t crcTerminal = 0; uint32_t AddrToWrite ; int FileLength_IAP; uint32_t update_flag = 0; int tag = 0; int lenindex=0; uint32_t nowcurAddr = 0; uint32_t nowcurAddr1 = 0; uint16_t nowcurpack = 0; uint16_t curaddr[2] = {0}; uint16_t curapack[1] = {0}; uint16_t curaddr_pack[3] = {0}; int sameIndex; bool Trindex; void Process_CMD_IAP_Update(void) { int lenRx1; int i; USART_IAP_FLAG = 0; packIndex = USART_IAP_RX[8] << 8 | USART_IAP_RX[9]; addrIndex = USART_IAP_RX[2] << 8 | USART_IAP_RX[3]; lenRx1 = USART_PUB_LENGTH; uint8_t ERR_Arr[8] = "error"; YmodemID = USART_IAP_RX[7]; memset(FileBuffArray, 0, sizeof(FileBuffArray)); memset(FileBuffArray1, 0, sizeof(FileBuffArray1)); switch (YmodemID) { case 0x01: //起始帧与结束帧解析 根据包序号判别该帧为起始帧还是结束帧 memcpy(startFrame, &USART_IAP_RX[10], 40); crcIAP = crc16_xmodem(&USART_IAP_RX[10], 128); crcTerminal = (USART_IAP_RX[lenRx1 - 4] << 8) | USART_IAP_RX[lenRx1 - 3]; AddrToWrite = 0; if (crcIAP == crcTerminal) { /*升级起始帧标记0*/ for (i = 0; i < 88; ++i) { if (*(unsigned char *)(StartMode_Addr + i + 4) != USART_IAP_RX[10 + i]) break; } if (i < 50) { for (i = 0; i < 25; i++) { FileBuffArray[i] = (uint16_t)(USART_IAP_RX[i * 2 + 11] << 8 | USART_IAP_RX[i * 2 + 10]); } Flash_WriteBytes(FileBuffArray, StartMode_Addr + 4, 25); //从StartMode_Addr+4 ,开始写入数据 delay_sys_us(50); /*升级起始帧标记1*/ /*IAP总长度标记0*/ #if indexfl == 4 lenindex =0;//长度为4位数 #else lenindex =1;//长度为5位数 #endif readFlashToArr(binLength, StartMode_Addr+27); if(lenindex != 0) { FileLength_IAP = ((binLength[0]&0xF)*10000) + ((binLength[1]&0xF) *1000) +((binLength[2]&0xF) *100) +\ ((binLength[3]&0xF) *10) + ((binLength[4]&0xF) ); } else { FileLength_IAP = ((binLength[0]&0xF)*1000) + ((binLength[1]&0xF) *100) +((binLength[2]&0xF) *10) +\ ((binLength[3]&0xF) *1) ; } all_len = FileLength_IAP; erase_flash(LENGTH_ADDR); HAL_FLASH_Unlock(); // 解锁Flash HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, LENGTH_ADDR, all_len); HAL_FLASH_Lock(); // 上锁Flash /*IAP总长度标记1*/ /*IAP_MD5标记0*/ if(lenindex!=0) { Flash_ReadBytes(iapbinMd5, StartMode_Addr + 33, 16); Flash_WriteBytes(iapbinMd5, MD5_ADDR, 8); for (int i = 0; i < 8; i++) { iapbinMd5[i] = ((iapbinMd5[i] >> 8) & 0xFF) | ((iapbinMd5[i] << 8) & 0xFF00); } } else { Flash_ReadBytes(iapbinMd5, StartMode_Addr + 32, 16); Flash_WriteBytes(iapbinMd5, MD5_ADDR, 8); for (int i = 0; i < 8; i++) { iapbinMd5[i] = ((iapbinMd5[i] >> 8) & 0xFF) | ((iapbinMd5[i] << 8) & 0xFF00); } } /*IAP_MD5标记1*/ AddrToWrite = Application_Buffer_Addr; } memset(USART_IAP_RX, 0, sizeof(USART_IAP_RX)); delay_sys_us(80); receive_modbus_9_1(initial_address, USART_MODBUS_RX[1], ((uint16_t)USART_MODBUS_RX[2] << 8) | USART_MODBUS_RX[3], \ ((uint16_t)USART_MODBUS_RX[4] << 8) | USART_MODBUS_RX[5], USART_MODBUS_RX[6]); } else { memset(USART_IAP_RX, 0, sizeof(USART_IAP_RX)); HAL_UART_Transmit(&huart1, ERR_Arr, strlen((char *)ERR_Arr), 100); } memset(FileBuffArray, 0, sizeof(FileBuffArray)); memset(FileBuffArray1, 0, sizeof(FileBuffArray1)); break; /*** * 存储并迁移下载区 */ case 0x02: //有效载荷帧数据处理 updatecuraddr(CURaddr_PACKAGE_ADDR); updatecurpack(CURaddr_PACKAGE_ADDR); crcIAP = crc16_xmodem(&USART_IAP_RX[10], 128); crcTerminal = (USART_IAP_RX[lenRx1 - 4] << 8) + USART_IAP_RX[lenRx1 - 3]; // nowcurAddr1 += 128; if((nowcurAddr1&0xFFFF) == addrIndex+128) { Trindex = 1; } else { Trindex = 0; } if(((nowcurAddr1&0xFFFF) != addrIndex) && Trindex) { addrIndex-=128; nowcurAddr1 = (nowcurAddr1 &0xFFFF0000) | addrIndex; AddrToWrite = nowcurAddr1; } if (crcIAP == crcTerminal) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); HAL_Delay(1); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); for (i = 0; i < 64; i++) { FileBuffArray[i] = (uint16_t)(USART_IAP_RX[i * 2 + 11] << 8 | USART_IAP_RX[i * 2 + 10]); } Flash_WriteBytes(FileBuffArray, AddrToWrite, 64);//init 08040000 AddrToWrite += 128; // +128 nowcurAddr = AddrToWrite; curaddr_pack[0] = (nowcurAddr >> 16) & 0xFFFF; curaddr_pack[1] = nowcurAddr & 0xFFFF; curaddr_pack[2] = packIndex; Flash_WriteBytes(curaddr_pack, CURaddr_PACKAGE_ADDR, 3); memset(USART_IAP_RX, 0, sizeof(USART_IAP_RX)); //CURPACKAGE_ADDR //CURADDRESS_ADDR // if((nowcurAddr-128) != addrIndex) // { // // HAL_UART_Transmit(&huart1, ERR_Arr, strlen((char *)ERR_Arr), 100); // return; // } // else // { HAL_GPIO_WritePin(kmg_GPIO_Port, kmg_Pin, GPIO_PIN_SET); HAL_Delay(1); HAL_GPIO_WritePin(kmg_GPIO_Port, kmg_Pin, GPIO_PIN_RESET); // } receive_modbus_9_1(initial_address, USART_MODBUS_RX[1], ((uint16_t)USART_MODBUS_RX[2] << 8) | USART_MODBUS_RX[3], \ ((uint16_t)USART_MODBUS_RX[4] << 8) | USART_MODBUS_RX[5], USART_MODBUS_RX[6]); } break; case 0x04: { crcIAP = crc16_xmodem(&USART_IAP_RX[10], 128); crcTerminal = (USART_IAP_RX[lenRx1 - 4] << 8) + USART_IAP_RX[lenRx1 - 3]; if (crcIAP == crcTerminal) { /*系统版本标记0*/ Flash_ReadBytes(version, StartMode_Addr + 14, 8); for (int i = 0; i < 4; i++) { version[i] = ((version[i] >> 8) & 0xFF) | ((version[i] << 8) & 0xFF00); } convertHexToAscii(version, &System_version); erase_flash(VERSION_ADDR); HAL_FLASH_Unlock(); // 解锁Flash HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, VERSION_ADDR, System_version); HAL_FLASH_Lock(); // 上锁Flash /*系统版本标记1*/ tag = App2_MD5_Check(Application_Buffer_Addr,all_len); if(tag) { Set_Update_Down(); //设定标志位 下次启动时进行程序拷贝 }else{ int txLen = sprintf((char *)USART_IAP_RX,"check=error\r\n"); delay_sys_us(80); HAL_UART_Transmit_IT(&huart1,USART_IAP_RX,txLen); while (huart1.gState == HAL_UART_STATE_BUSY_TX) { HAL_Delay(1); } } } else { delay_sys_us(80); HAL_UART_Transmit(&huart1, ERR_Arr, strlen((char *)ERR_Arr), 100); delay_sys_us(80); } } break; default: break; } } uint8_t buffer[BUFFER_SIZE_length]; uint8_t buffer_length[100]; unsigned int all_len; int i; unsigned int ModeStart; void Start_BootLoader(void) { uint16_t ModeStart1[2]; Flash_ReadBytes(ModeStart1, StartMode_Addr, 2); ModeStart = (ModeStart1[0] << 16) | ModeStart1[1]; all_len = FileLength_IAP; int tag; int txLen; memset(USART_IAP_RX, 0, sizeof(USART_IAP_RX)); update_iaplength(LENGTH_ADDR); switch (ModeStart) { case Startup_Normal: // 正常启动 在APP2中可以设定此标志位 使得下次重启之后进入APP1 { break; } case Startup_Update: /*启动最新的程序 */ all_len = FileLength_IAP; tag = App2_MD5_Check(Application_Buffer_Addr,all_len); if (tag) { iap_write_appbin(ADD_UPDATE_PROG,Application_Buffer_Addr,all_len); HAL_Delay(80); txLen = sprintf((char *)USART_IAP_RX, "Upgrade completed"); HAL_UART_Transmit_IT(&huart1,USART_IAP_RX,txLen); while (huart1.gState == HAL_UART_STATE_BUSY_TX) { HAL_Delay(1); } Set_App2_Flag(); } else { txLen = sprintf((char *)USART_IAP_RX,"checkfail"); delay_sys_us(80); HAL_UART_Transmit_IT(&huart1,USART_IAP_RX,txLen); while (huart1.gState == HAL_UART_STATE_BUSY_TX) { HAL_Delay(1); } return ; } case Startup_APP2: /*启动最新的程序 */ if (App2_MD5_Check(ADD_UPDATE_PROG,all_len)) { __set_FAULTMASK(0); //先关闭全局中断 jump_to_app(ADD_UPDATE_PROG); } break; default: // 启动失败 { if (App2_MD5_Check(ADD_UPDATE_PROG,all_len)) { __set_FAULTMASK(0); //先关闭全局中断 jump_to_app(ADD_UPDATE_PROG); } return; } } }