#include "main.h" uint8_t send_start_buf[6] = {0xA5, 0x5A, 0x06, 0x00, 0x10, 0x01}; uint8_t get_package_buf[14] = {0xA5, 0x5A, 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 2022change // uint8_t send_over_buf[9] = {0xA5, 0x5A, 0x09, 0x00, 0x12, 0x00, 0x00, 0x00,0x00};//2022change uint32_t FlashPtr; typedef void (*pFunction)(void); pFunction Jump_To_Application; uint32_t packagesSize; uint8_t rx1_frame_OK; uint8_t rx1_buff[rx2_buffsize]; uint32_t rx1count; uint8_t wifi_connect_flg = 0; uint32_t time_flg = 0; uint8_t version[4] = {0}; // 2022change uint32_t current_package; //当前升级包 uint8_t upgrade_hand_flg = 0; uint32_t lastFrameCnt = 0; //最后一帧字节数 uint8_t flash_array[BinPerFrameSize]; uint32_t OPENBL_CRC32_MPEG_2(uint8_t *data, uint32_t length) { uint32_t i; uint32_t crc = 0xffffffff, j = 0; while ((length--) != 0) { crc ^= (uint32_t)data[j] << 24; j++; for (i = 0; i < 8; ++i) { if ((crc & 0x80000000) != 0) { crc = (crc << 1) ^ 0x04C11DB7; } else { crc <<= 1; } } } return crc; } void CRC_usart1send(uint8_t *data, uint32_t length) { uint32_t crc_temp, i; uint8_t crc[4]; crc_temp = OPENBL_CRC32_MPEG_2(data, length); crc[0] = (uint8_t)crc_temp; crc[1] = (uint8_t)(crc_temp >> 8); crc[2] = (uint8_t)(crc_temp >> 16); crc[3] = (uint8_t)(crc_temp >> 24); for (i = 0; i < length; i++) { UART_SendByte(USART1, (uint8_t)data[i]); } for (i = 0; i < 4; i++) { UART_SendByte(USART1, (uint8_t)crc[i]); } while (RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC)) ; } uint8_t flashWrite(uint8_t *data, uint_fast8_t length) { static uint8_t buffer; uint16_t temp, i; uint_fast8_t index; uint32_t flashPtr1; if (length == 0) return 0; flashPtr1 = FlashPtr; FLASH_Unlock(); index = 0; do { if (flashPtr1 & 1) { flashPtr1--; temp = buffer; } else { temp = data[index++]; }; temp |= data[index++] << 8; FLASH_ProgramHalfWord(flashPtr1, temp); flashPtr1 += sizeof(uint16_t); } while ((length - index) >= 2); for (i = 0; i < length; i++) //读出flash校验是否写错 { if (data[i] != *(uint8_t *)(FlashPtr + i)) return 1; //有错 } FLASH_Lock(); FlashPtr += length; return 0; } void page_flashErase(void) //形参为包数量 { FLASH_Unlock(); FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3); FLASH_EraseSector(FLASH_Sector_9, VoltageRange_3); FLASH_Lock(); } int check_stack_head(unsigned long execAdr) { // MBL_APP_EXEC_ADR为新程序的起始地址,检查栈顶地址是否合法,即栈顶地址是否为0x2000xxxx(内置SRAM) if (((*(__IO uint32_t *)execAdr) & 0x2FFE0000UL) == 0x20000000UL) return 0; else return -1; } void flash_write_version(uint8_t *version) // version为4个字节 { //需要flash已解锁 uint32_t value; value = *(__IO uint32_t *)version; FLASH_ProgramWord(FLASH_VERSION_ADDR, value); } void execute_app() { uint32_t JumpAddress = 0; uint32_t Jumpadd = FLASH_OLDAPP_ADDR; USART_DeInit(USART1); if (upgrade_flag == 1) // 1111--升级完成 { Jumpadd = FLASH_APP_ADDR; } JumpAddress = *(__IO uint32_t *)(Jumpadd + 4); //用户代码区第二个字存储为新程序起始地址(新程序复位向量指针) printf("Jumpadd is %x,JumpAddress is %x,upgrade_flag is %d\r\n", Jumpadd, JumpAddress, upgrade_flag); Jump_To_Application = (pFunction)JumpAddress; __set_MSP(*(__IO uint32_t *)Jumpadd); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) Jump_To_Application(); // 设置PC指针为新程序复位中断函数的地址 } void upgrade_menu(void) { uint8_t error; switch (upgrade_hand_flg) { case 0x01: //获取数据包 upgrade_hand_flg = 0x00; //获取数据包标志位置0 get_package_buf[6] = (uint8_t)current_package; get_package_buf[7] = (uint8_t)(current_package >> 8); // 2022change get_package_buf[8] = (uint8_t)(current_package >> 16); get_package_buf[9] = (uint8_t)(current_package >> 24); // time_flg = resent_time;//重新计时 CRC_usart1send(get_package_buf, 9); // 2022change break; case 0x02: //写入数据包 error = flashWrite(flash_array, BinPerFrameSize); //写入flash,固定一包写256个字节 if (1 == error) //写入错误重启,重新升级 { page_flashErase(); NVIC_SystemReset(); } if (0 == lastFrameCnt) { current_package += BinPerFrameSize; upgrade_hand_flg = 0x01; //获取数据包标志位置0 get_package_buf[5] = 0x01; //回复OK } else //最后一帧发完 { current_package += lastFrameCnt; upgrade_hand_flg = 0x44; // flash完成标志位 get_package_buf[5] = 0x03; //回复完成 } break; case 0x44: // Execute The New Program Enter 'D' // MBL_APP_EXEC_ADR为新程序的起始地址,检查栈顶地址是否合法,即栈顶地址是否为0x2000xxxx(内置SRAM) if (check_stack_head(FLASH_APP_ADDR) == 0) { FLASH_Unlock(); FLASH_EraseSector(FLASH_Sector_2, VoltageRange_3); FLASH_ProgramWord(FLASH_DATA_FLAG_ADDR, FLASH_START_FLAG); //升级完成 // flash_write_version(version); FLASH_Lock(); // send_over_buf[5] = version[0]; // send_over_buf[6] = version[1]; // send_over_buf[7] = version[2]; // send_over_buf[8] = version[3];//2022change get_package_buf[6] = (uint8_t)current_package; get_package_buf[7] = (uint8_t)(current_package >> 8); get_package_buf[8] = (uint8_t)(current_package >> 16); get_package_buf[9] = (uint8_t)(current_package >> 24); CRC_usart1send(get_package_buf, 9); //发送完成升级 delay_ms(2); upgrade_flag = 1; execute_app(); /*执行用户程序*/ } break; case 0x1E: // wifi发的东西 break; default: break; } } void boot_ReceiveHdl() { uint32_t crcCal, i; uint8_t crcGet[4]; uint32_t packageNO; if (rx1_frame_OK) { switch (rx1_buff[4]) { case 0x10: //已进入升级模式 get_package_buf[5] = 0x01; //回复OK CRC_usart1send(send_start_buf, 6); break; case 0x11: //包头数据 //获取版本号 version[0] = rx1_buff[5]; version[1] = rx1_buff[6]; version[2] = rx1_buff[7]; version[3] = rx1_buff[8]; // 2022change //更新请求帧的版本号 // get_package_buf[5] = version[0]; // get_package_buf[6] = version[1]; // get_package_buf[7] = version[2]; // get_package_buf[8] = version[3];//2022change //获取bin字节数 packagesSize = (uint32_t)(rx1_buff[12]) << 24 | (uint32_t)(rx1_buff[11]) << 16 | (uint32_t)(rx1_buff[10]) << 8 | rx1_buff[9]; page_flashErase(); //擦除需要占用的flash空间 FlashPtr = FLASH_APP_ADDR; //从新地址开始启动 current_package = 0; //当前数据包从0开始 lastFrameCnt = 0; upgrade_hand_flg = 0x01; //开始获取包标志位 wifi_connect_flg = 1; //通讯连接上 break; case 0x12: //升级包数据 //获取当前包序号 packageNO = (uint32_t)(rx1_buff[8]) << 24 | (uint32_t)(rx1_buff[7]) << 16 | (uint32_t)(rx1_buff[6]) << 8 | rx1_buff[5]; //获取CRC crcGet[0] = rx1_buff[rx1count - 4]; crcGet[1] = rx1_buff[rx1count - 3]; crcGet[2] = rx1_buff[rx1count - 2]; crcGet[3] = rx1_buff[rx1count - 1]; crcCal = OPENBL_CRC32_MPEG_2(rx1_buff, rx1count - 4); if ((*(__IO uint32_t *)crcGet == crcCal) && (packageNO == current_package)) // CRC校验合格、包序号正确 { for (i = 0; i < BinPerFrameSize; i++) { flash_array[i] = rx1_buff[9 + i]; } upgrade_hand_flg = 0x02; //开始写入flash if ((rx1count - 13 + current_package) >= packagesSize) //判断最后一帧多少字节 { lastFrameCnt = rx1count - 13; if (lastFrameCnt < BinPerFrameSize) { memset(&flash_array[lastFrameCnt], 0xff, BinPerFrameSize - lastFrameCnt); } } } else { upgrade_hand_flg = 0x01; //开始获取包标志位--重新开始获取 get_package_buf[5] = 0x02; //回复重新获取 } LED_B = 0; delay_ms(10); LED_B = 1; break; case 0xff: // NVIC_SystemReset(); break; default: break; } rx1count = 0; rx1_frame_OK = 0; } } void USART1_IRQHandler(void) //串口1中断服务程序--WIFI { static uint8_t rece_step = 0; static uint16_t templen = 0; uint8_t receive; if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { receive = USART_ReceiveData(USART1); //(USART1->DR); //读取接收到的数据 rx1_buff[rx1count++] = receive; if (rx1_frame_OK == 1) //没处理完再发就丢弃 { USART_ReceiveData(USART1); return; } switch (rece_step) { case 0: if (receive == 0xa5) { rece_step = 1; rx1count = 1; } else rx1count = 0; break; case 1: if (receive == 0x5a) { rx1_buff[0] = 0xa5; rx1_buff[1] = 0x5a; rx1count = 2; rece_step = 2; } else { if (receive == 0xA5) { rece_step = 1; rx1count = 1; } else rece_step = 0; } break; case 2: if (rx1count >= 4) { templen = (uint16_t)(rx1_buff[3]) << 8 | rx1_buff[2]; rece_step = 3; } break; case 3: if ((templen >= rx2_buffsize) || rx1count >= rx2_buffsize) { rece_step = 0; rx1count = 0; } else if (rx1count >= (4 + templen)) { rx1_frame_OK = 1; rece_step = 0; } break; } } }