#include "main.h" #include "string.h" #include "stdio.h" #include "usart.h" #include "iap.h" #include "stmflash.h" #include "md5c.h" extern void __set_FAULTMASK(uint32_t faultMask); iapfun jump2app; uint16_t iapbuf[1024]; __asm void MSR_MSP(uint32_t addr) { MSR MSP, r0 //set Main Stack value BX r14 } void Flash_ReadBytes(uint16_t* sorBuf,uint32_t FlashAddr,uint16_t len) { uint16_t* p = sorBuf; uint8_t i = 0,j = 0; uint32_t addr = FlashAddr; while(len--) { i = *(uint32_t*)addr++; j = *(uint32_t*)addr++; *p++ = j<<8|i; } } uint16_t Flashbuf[2048]__attribute__ ((at(0X20001000))); void Flash_WriteBytes(uint16_t* sorBuf,uint32_t FlashAddr,uint16_t len) { uint32_t Offset_ADDR = 0,Page_StartAddr = 0,i = 0; Offset_ADDR = FlashAddr%0x800; Page_StartAddr = FlashAddr - Offset_ADDR; //设置PageError uint32_t PageError = 0; FLASH_EraseInitTypeDef f; f.TypeErase = FLASH_TYPEERASE_PAGES; __nop(); f.PageAddress =Page_StartAddr; f.NbPages = 1; Flash_ReadBytes(Flashbuf,Page_StartAddr,0x400); for(i = 0;i(i+512)) update_len = 512; else update_len = all_len-i; memcpy(iapbuf,(const void *)(addr+i),update_len); MD5Update (&md5c, (unsigned char *)iapbuf, update_len); i += update_len; HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); } MD5Final(digest,&md5c); for(i=0;i<16;++i) { if(digest[i]!=*(unsigned char *)(addr+all_len+i)) break; } if(i>=16) return 1; else return 0; } // appxaddr:应用程序的起始地址 // appbuf:应用程序CODE. // appsize:应用程序大小(字节). void iap_write_appbin(uint32_t appxaddr, uint8_t *appbuf, uint32_t appsize) { uint32_t t; uint16_t i = 0; uint16_t temp; uint32_t fwaddr = appxaddr; //当前写入的地址 uint8_t *dfu = appbuf; for (t = 0; t < appsize; t += 2) { temp = (uint16_t)dfu[1] << 8; temp += (uint16_t)dfu[0]; dfu += 2; //偏移2个字节 iapbuf[i++] = temp; if (i == 1024) { i = 0; HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); STMFLASH_Write(fwaddr, iapbuf, 1024); fwaddr += 2048; //偏移2048 16=2*8.所以要乘以2. } } if (i) STMFLASH_Write(fwaddr, iapbuf, i); //将最后的一些内容字节写进去. } //跳转到应用程序段 // appxaddr:用户代码起始地址. void iap_load_app(uint32_t appxaddr) { if (((*(uint32_t *)appxaddr) & 0x2FFE0000) == 0x20000000) //检查栈顶地址是否合法. { jump2app = (iapfun) * (uint32_t *)(appxaddr + 4); //用户代码区第二个字为程序开始地址(复位地址) MSR_MSP(*(uint32_t *)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) jump2app(); //跳转到APP. } } unsigned int update_flag = 0xAAAAAAAA; ///< 对应bootloader的启动步骤 unsigned int ModeStart; unsigned int i,all_len; /** * @bieaf 进行BootLoader的启动 * * @param none * @return none */ void Start_BootLoader(void) { uint16_t ModeStart1[2]; HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); Flash_ReadBytes(ModeStart1, StartMode_Addr, 2); ModeStart = ModeStart1[0]; ModeStart <<= 16; ModeStart |= ModeStart1[1]; switch (ModeStart) ///< 读取是否启动应用程序 */ { case Startup_Normal: ///< 正常启动 */ //在APP2中可以设定此标志位 使得下次重启之后进入APP1 { ; break; } case Startup_Update: /*启动最新的程序 */ HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); for (i = 0, all_len = 0; i < 4; ++i) { all_len = all_len << 8; all_len |= *(unsigned char *)(StartMode_Addr + 68 + i); } if (App2_MD5_Check(Application_Buffer_Addr,all_len)) { iap_write_appbin(ADD_UPDATE_PROG,(uint8_t *)Application_Buffer_Addr,all_len); HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); Flash_WriteBytes((uint16_t*)(StartMode_Addr + 68), StartMode_Addr+132, 2); } Set_App2_Flag(); case Startup_APP2: /*启动最新的程序 */ for (i = 0, all_len = 0; i < 4; ++i) { all_len = all_len << 8; all_len |= *(unsigned char *)(StartMode_Addr + 132 + i); } if ((all_len<0x20000) && App2_MD5_Check(ADD_UPDATE_PROG,all_len)) { __set_FAULTMASK(0); //先关闭全局中断 iap_load_app(ADD_UPDATE_PROG); //执行FLASH APP2代码 } break; default: ///< 启动失败 { return; } } } uint8_t YmodemID; uint16_t packIndex, packTotalNum, packIndexbak; //当前包号,总包数 uint16_t crcIAP, crcTerminal, crcIAP1; uint32_t FileLength_IAP = 0; //文件长度 uint16_t FileBuffArray[512]; // MD5校验 uint16_t FileBuffArray1[512]; // MD5校验 uint32_t AddrToWrite = Application_Buffer_Addr; uint32_t DataReadFlash, DataReadFlash1, update_flag; void Set_Update_Down(void) { uint16_t update_flag1[2]; update_flag = Startup_Update; ///< 对应bootloader的启动步骤 update_flag1[0] = (uint16_t)update_flag; update_flag1[1] = (uint16_t)(update_flag >> 16); Flash_WriteBytes(update_flag1, StartMode_Addr, 2); __set_FAULTMASK(1); NVIC_SystemReset(); } void Res_Update_Down(void) { uint16_t update_flag1[2]; update_flag = Startup_Normal; ///< 对应bootloader的启动步骤 update_flag1[0] = (uint16_t)update_flag; update_flag1[1] = (uint16_t)(update_flag >> 16); Flash_WriteBytes(update_flag1, StartMode_Addr, 2); __set_FAULTMASK(1); NVIC_SystemReset(); } void Set_App2_Flag(void) { uint16_t update_flag1[2]; update_flag = Startup_APP2; ///< 对应bootloader的启动步骤 update_flag1[1] = (uint16_t)update_flag; update_flag1[0] = (uint16_t)(update_flag >> 16); Flash_WriteBytes(update_flag1, StartMode_Addr, 2); } void Process_CMD_IAP_Update(void) { int lenRx1, lenRx2; int i; for (i = 0; i < 512; i++) { FileBuffArray[i] = 0; FileBuffArray1[i] = 0; } packIndex = (USART2_RX_BUF002[5] << 8) + USART2_RX_BUF002[6]; packTotalNum = (USART2_RX_BUF002[7] << 8) + USART2_RX_BUF002[8]; lenRx1 = data_lengthU2; YmodemID = USART2_RX_BUF002[4]; //只能是01,02 data_lengthU2 = 0; uint8_t ERR_Arr[8] = "error\r\n"; uint8_t ACK_Arr[16] = "acknowlege"; HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); switch (YmodemID) { case 0x01: //起始帧与结束帧解析 根据包序号判别该帧为起始帧还是结束帧 if (packIndex == 1) { //起始帧处理 FileLength_IAP = (USART2_RX_BUF002[73] << 24) + (USART2_RX_BUF002[74] << 16) + (USART2_RX_BUF002[75] << 8) + (USART2_RX_BUF002[76]); crcIAP = LIB_CRC_MODBUS(&USART2_RX_BUF002[4], 133); // crcTerminal = (USART2_RX_BUF002[lenRx1 - 5] << 8) + USART2_RX_BUF002[lenRx1 - 6]; if (crcIAP == crcTerminal) { for (i = 0; i < 88; ++i) { if (*(unsigned char *)(StartMode_Addr + i + 4) != USART2_RX_BUF002[9 + i]) break; } if (i < 88) { for (i = 0; i < 44; i++) { FileBuffArray[i] = (uint16_t)(USART2_RX_BUF002[i * 2 + 10] << 8 | USART2_RX_BUF002[i * 2 + 9]); } HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); Flash_WriteBytes(FileBuffArray, StartMode_Addr + 4, 44); HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); delay_sys_us(80); packIndexbak = 0; AddrToWrite = Application_Buffer_Addr; HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); } else { if(packIndexbak>1) packIndexbak-=1; } { static uint16_t txLen; for (i = 0; i < 1024; i++) { USART2_RX_BUF002[i] = 0; } txLen = sprintf((char *)FileBuffArray, "file=%d\r\n", packIndexbak); // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); // delay_sys_us(80); HAL_UART_Transmit_IT(&huart1,(unsigned char *)FileBuffArray,txLen); while (huart1.gState == HAL_UART_STATE_BUSY_TX) { HAL_Delay(1); } delay_sys_us(80); delay_sys_us(80); // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); // } } else { for (i = 0; i < 1024; i++) { USART2_RX_BUF002[i] = 0; } // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); // delay_sys_us(80); HAL_UART_Transmit(&huart1, ERR_Arr, strlen((char *)ERR_Arr), 100); delay_sys_us(80); // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); // __NOP(); } __NOP(); } else { __NOP(); } break; case 0x02: //有效载荷帧数据处理 crcIAP = LIB_CRC_MODBUS(&USART2_RX_BUF002[4], lenRx1 - 10); // crcTerminal = (USART2_RX_BUF002[lenRx1 - 5] << 8) + USART2_RX_BUF002[lenRx1 - 6]; if ((crcIAP == crcTerminal) && (((packIndexbak + 1) == packIndex) || ((packIndexbak) == packIndex))) { if ((packIndexbak + 1) == packIndex) { lenRx2 = (lenRx1 - 15) % 2; if (!lenRx2) { for (i = 0; i < ((lenRx1 - 15) / 2); i++) { FileBuffArray[i] = (uint16_t)(USART2_RX_BUF002[i * 2 + 10] << 8 | USART2_RX_BUF002[i * 2 + 9]); FileBuffArray1[i] = (uint16_t)(USART2_RX_BUF002[i * 2 + 10] << 8 | USART2_RX_BUF002[i * 2 + 9]); } Flash_WriteBytes(FileBuffArray, AddrToWrite, ((lenRx1 - 15) / 2)); HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); Flash_ReadBytes(FileBuffArray1, AddrToWrite, ((lenRx1 - 15) / 2)); HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); } else { for (i = 0; i < ((lenRx1 - 16) / 2); i++) { FileBuffArray[i] = (uint16_t)(USART2_RX_BUF002[i * 2 + 10] << 8 | USART2_RX_BUF002[i * 2 + 9]); FileBuffArray1[i] = (uint16_t)(USART2_RX_BUF002[i * 2 + 10] << 8 | USART2_RX_BUF002[i * 2 + 9]); } FileBuffArray[(lenRx1 - 16) / 2] = USART2_RX_BUF002[(lenRx1 - 16 + 10)] << 8; FileBuffArray1[(lenRx1 - 16) / 2] = USART2_RX_BUF002[(lenRx1 - 16 + 10)] << 8; HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); Flash_WriteBytes(FileBuffArray, AddrToWrite, ((lenRx1 - 15 + 1) / 2)); HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); Flash_ReadBytes(FileBuffArray1, AddrToWrite, ((lenRx1 - 15 + 1) / 2)); HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); } AddrToWrite += lenRx1 - 15; DataReadFlash = *((uint32_t *)(AddrToWrite)); DataReadFlash1 = (*(__IO uint32_t *)AddrToWrite); HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); } if (DataReadFlash == DataReadFlash1) { __NOP(); HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); packIndexbak = packIndex; } { int txLen; for (i = 0; i < 1024; i++) { USART2_RX_BUF002[i] = 0; } txLen = sprintf((char *)USART2_RX_BUF002, "%s=%d\r\n", ACK_Arr, packIndex); // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); // delay_sys_us(80); HAL_UART_Transmit_IT(&huart1,USART2_RX_BUF002,txLen); while (huart1.gState == HAL_UART_STATE_BUSY_TX) { delay_sys_us(1); } // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); // } __NOP(); } else { // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); // delay_sys_us(80); HAL_UART_Transmit(&huart1, ERR_Arr, strlen((char *)ERR_Arr), 100); delay_sys_us(80); // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); // __NOP(); } break; case 3: // if(packIndex>2) { //结束帧处理 int i,all_len; crcIAP1 = LIB_CRC_MODBUS(&USART2_RX_BUF002[4], 133); // crcTerminal = (USART2_RX_BUF002[lenRx1 - 5] << 8) + USART2_RX_BUF002[lenRx1 - 6]; if (crcIAP1 == crcTerminal) { int txLen; // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); // delay_sys_us(80); txLen = sprintf((char *)USART2_RX_BUF002, "%s\r\n", ACK_Arr); HAL_UART_Transmit_IT(&huart1,USART2_RX_BUF002,txLen); while (huart1.gState == HAL_UART_STATE_BUSY_TX) { delay_sys_us(1); } // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); // for (i = 0, all_len = 0; i < 4; ++i) { all_len = all_len << 8; all_len |= *(unsigned char *)(StartMode_Addr + 68 + i); } if (1)//App2_MD5_Check(Application_Buffer_Addr,all_len)) { txLen = sprintf((char *)USART2_RX_BUF002, "md5 check=ok\r\n"); // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); // delay_sys_us(80); HAL_UART_Transmit_IT(&huart1,USART2_RX_BUF002,txLen); while (huart1.gState == HAL_UART_STATE_BUSY_TX) { delay_sys_us(1); } // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); // Set_Update_Down(); //设定标志位 下次启动时进行程序拷贝 } else { txLen = sprintf((char *)USART2_RX_BUF002,"md5 check=error\r\n"); } // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); // delay_sys_us(80); HAL_UART_Transmit_IT(&huart1,USART2_RX_BUF002,txLen); while (huart1.gState == HAL_UART_STATE_BUSY_TX) { delay_sys_us(1); } // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); // } else { // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_RESET); // delay_sys_us(80); HAL_UART_Transmit(&huart1, ERR_Arr, strlen((char *)ERR_Arr), 100); delay_sys_us(80); // HAL_GPIO_WritePin(GPIOA, con03_uart2_kongzhiqi_Pin, GPIO_PIN_SET); // __NOP(); } __NOP(); } break; default: break; } }