#include "debug.h" #include "crc16.h" #include "flexcan_init.h" #include #include #include #include #include "IAP_Task.h" #include "wdt_refresh.h" #include "pinmux_cfg.h" #include #include "sdrv_rstgen.h" #include #include #include #include "eth_cfg.h" #include "sdrv_eth.h" #include "interface_ethernet.h" u32 fileDataLen = 0; //IAP file data length u32 fileCheckSum = 0; //IAP file data checksum u32 flashProgramLen = 0; //length of data written to backup area //iapFileHeader iapPara; //IAP file parameters CBL_CMD_LIST g_cmdList = {0}; volatile uint16_t g_updateModeCnt = 0;// uint32_t g_recvLen = 0; uint16_t g_canAddr = 0; uint8_t des_ipaddr[4] = {192,168,17,3};//本机IP //uint8_t CH395GWIPAddr[4] = {192,168,17,1};//网关 //uint8_t CH395IPMask[4] = {255,255,255,0};//掩码 //uint8_t OwnMasterIpArr[4] = {192,168,17,117};//ַ目标IP uint8_t g_recvData[1028] = {0}; uint8_t g_recvDataCheck[1028] = {0}; uint8_t g_eflashRWBuffer[DATA_SIZE] = {0x00}; SystemDataRecord g_systemDataRecord = {0,0,0,0}; volatile uint8_t g_canRxMsgFlag = 0;//接收到CAN数据后的标志 volatile uint16_t Eth_Rx_Flag = 0;//接收到CAN数据后的标志 extern uint8_t SocketId; ENET_RxBuf ENET_RxBuf_1 = {0}; uint8_t g_RedData[1024] = {0}; uint8_t debugdata[4] = {0,0,0,0}; Flash_RxBuf Flash_RxBuf_1 = {0}; Flash_RxBuf Flash_RxBuf_2 = {0}; uint8_t writeflashTime = 0;//最大循环写入3次 uint32_t AppBinSize = 0;//数据总长度,用来判断数据长度 uint32_t WriteflashSize = 0;//写的flash数据长度 uint32_t OTA_CANTxID = 0x02;//默认发送ID为0x02 uint32_t OTA_CANRxID = 0x01;//默认接收ID为0x01 uint32_t WDT_CANRxID = 0x03;//默认接收ID为0x03 uint8_t flash_eth_time = 0;//接收启动超时标志 uint8_t ethCmdSTT = 0; bool WDTReFresh_flag = false;//busoff标志 /********************************************************************* * @fn IAP_EEPROM_ERASE * * @brief erase Data-Flash block, minimal block is 256B * * @param Page_Address - the address of the page being erased. * Length - Erased data length * * @return none */ void IAP_EEPROM_ERASE(uint32_t Page_Address, uint32_t Length) { u16 pageNum = Length / FLASH_PAGE_SIZE; u16 lastDataNum = Length % FLASH_PAGE_SIZE; u32 Len_PAGE = 0; //----------------------------------------------------- if(0 != (lastDataNum))//判断是否整除 { pageNum = pageNum+1; } Len_PAGE = pageNum * FLASH_PAGE_SIZE;//计算擦写长度 sdrv_spi_nor_erase(&flash, Page_Address,Len_PAGE); } /********************************************************************* * @fn IAP_EEPROM_WRITE * * @brief write Data-Flash data block * * @param StartAddr - the address of the page being written. * Buffer - data buff * Length - written data length * * @return FLASH_Status */ void IAP_EEPROM_WRITE( u32 StartAddr, u8 *Buffer, u32 Length ) { u16 pageNum = Length / FLASH_PAGE_Write; u16 lastDataNum = Length % FLASH_PAGE_Write; u32 Len_PAGE = 0; int write_sta = 0; //----------------------------------------------------- if(0 != (lastDataNum))//判断是否整除 { pageNum = pageNum+1; } Len_PAGE = pageNum * FLASH_PAGE_Write;//计算擦写长度 write_sta = sdrv_spi_nor_write(&flash, StartAddr, Buffer, Len_PAGE); if(write_sta != 0) { printf("flash fail!"); } } /********************************************************************* * @fn IAP_EEPROM_READ * * @brief read Data-Flash data block * * @param StartAddr - the address of the page being read. * Buffer - data buff * Length - read data length * * @return none */ void IAP_EEPROM_READ( u32 StartAddr, u8 *Buffer, u32 Length ) { u16 pageNum = Length / FLASH_PAGE_Write; u16 lastDataNum = Length % FLASH_PAGE_Write; u32 Len_PAGE = 0; //----------------------------------------------------- if(0 != (lastDataNum))//判断是否整除 { pageNum = pageNum+1; } Len_PAGE = pageNum * FLASH_PAGE_Write;//计算擦写长度 sdrv_spi_nor_read(&flash, StartAddr, Buffer, Len_PAGE); } /** * bootMsgTx * * @param[in] Mode: 模式 0:can下载,1:以太网下载 * @param[in] Cmd: 发送的命令 * @param[in] *Buffer: 需要发送的数据 * * @brief 发送下载时反馈给上位机的数据 */ void bootMsgTx(uint8_t Mode,uint16_t Cmd,uint8_t *Buffer,uint8_t len) { uint16_t port = 0; //------------------------------------------------------------------------------ switch(Mode) { case DOWNLOAD_CAN://can下载 CAN_Send_Msg(&g_flexcan_handle,Cmd, FLEXCAN_STANDARD_FRAME, FLEXCAN_FrameTypeData, Buffer,len, TX_MB_INDEX); break; case DOWNLOAD_ETH://以太网下载 if(0x02 == Cmd) { port = BOOT_TX_PORT; } UdpSendToData(UDPCB_1, Buffer,len, des_ipaddr, port); break; default:; } } /** * CAN_BootGetAddrData * * @param[in] none * @return : 节点地址。 * * @brief 获取节点地址信息 */ uint16_t CAN_BootGetAddrData(void) { return 0x10;//返回的地址值需要根据实际情况进行修改 } /** * DataRecord_WriteUpgrade * * @param[in] upgradeFlag NORMAL_ON(0):normal start, CAN_BOOTLOADER_UPGRADE(1):bootloader upgrade * @return 0, success.-1, fail, other:flash ctrl fail * * @brief Unlock the eflash control */ int DataRecord_WriteUpgrade(uint8_t upgradeFlag) { IAP_EEPROM_READ( DATA_START_ADDR, (uint8_t *)&g_systemDataRecord, 4 ); IAP_EEPROM_ERASE(DATA_START_ADDR, FLASH_PAGE_SIZE); g_systemDataRecord.canBootloaderUpgrade = 0; IAP_EEPROM_WRITE(DATA_START_ADDR, (uint8_t *)&g_systemDataRecord, 4); IAP_EEPROM_READ( DATA_START_ADDR, (uint8_t *)&g_systemDataRecord, 4 ); if (g_systemDataRecord.canBootloaderUpgrade == upgradeFlag) { return 0; } else { return -1; } } /** * goToApp * * @param[in] none * @return : none * * @brief APP跳转 */ void goToApp(void) { /* global reset */ /* soft reset flash */ // flash.sw_rst = true;//跳转前先非初始化 // sdrv_spi_nor_deinit(&flash); // /* soft reset xspi host */ // sdrv_spi_nor_drv_deinit(&flash); printf("goToApp\r\n"); sdrv_gpio_set_pin_output_level(GPIO_B9, 0); //测量时间 arch_invalidate_cache_range(0x01978000,0x8000);//清除 dcache sdrv_core_force_remap(SDRV_REMAP_SF, APP_Flash_adr+0x10000000); } /** * CAN_BootExecutiveCommand * * @param[in] pRxMessage CAN总线消息 * @return : none * * @brief 执行主机下发的命令 */ void CAN_BootExecutiveCommand(ENET_RxBuf *pRxMessage) { uint16_t canCmd = 0;//ID的bit0~bit3位为命令码 uint16_t crcData = 0; static uint32_t s_startAddr = 0; static uint32_t RgEasySize = 0; uint8_t ENETTxMessage[8] = {0,0,0,0,0,0,0}; static uint8_t CAN_BootExecutiveStt = 0; uint8_t WriteE2adr = 0;//写地址中间值 static uint8_t EnterRegion = 0;//区域 uint8_t psn_data[4]__attribute__((__aligned__(4))); //实际数据接收数据 注意4字节对齐 注意需要4字节对齐。 //--------------------------------------------------------------------------- canCmd = (pRxMessage->RxData[0] << 8) + pRxMessage->RxData[1]; printf("Flash_RxBufLenNow :0x%x,Flash_RxBufSta :0x%x,Flash_RxBufLen:0x%x\r\n",Flash_RxBuf_1.Flash_RxBufLenNow, Flash_RxBuf_1.Flash_RxBufSta,Flash_RxBuf_1.Flash_RxBufLen); printf("Flash2_RxBufLenNow :0x%x,Flash2_RxBufSta :0x%x,Flash2_RxBufLen:0x%x\r\n",Flash_RxBuf_2.Flash_RxBufLenNow, Flash_RxBuf_2.Flash_RxBufSta,Flash_RxBuf_2.Flash_RxBufLen); printf("CAN_BootExecutiveStt :0x%x, canCmd:0x%x\r\n", CAN_BootExecutiveStt,canCmd); switch(canCmd) { case ENTER_UPDATE_MODE: //boot重启 /* global reset */ /* soft reset flash */ flash.sw_rst = true; sdrv_spi_nor_deinit(&flash); /* soft reset xspi host */ sdrv_spi_nor_drv_deinit(&flash); //20250822 修改为点击连接就修改IP,这样不需要外部来修改参数 wrbyte_24c02(BOOT_DES_IP, (pRxMessage->RxData[2])); wrbyte_24c02(BOOT_DES_IP+1,(pRxMessage->RxData[3])); wrbyte_24c02(BOOT_DES_IP+2,(pRxMessage->RxData[4])); wrbyte_24c02(BOOT_DES_IP+3,(pRxMessage->RxData[5])); for(;;) { ssdk_printf(SSDK_INFO, "Restart!\r\n"); udelay(100000); } break; case READ_VERSION: if(BOOT0_index == (pRxMessage->RxData[2])) { ENETTxMessage[0] = (uint8_t)(READ_VERSION>>8); ENETTxMessage[1] = (uint8_t)(READ_VERSION); ENETTxMessage[2] = BOOT0_index; ENETTxMessage[3] = rdbyte_24c02(BOOT0_VERSION_E2adr); ENETTxMessage[4] = rdbyte_24c02(BOOT0_VERSION_E2adr+1); ENETTxMessage[5] = rdbyte_24c02(BOOT0_VERSION_E2adr+2); ENETTxMessage[6] = rdbyte_24c02(BOOT0_VERSION_E2adr+3); ENETTxMessage[7] = rdbyte_24c02(BOOT0_VERSION_E2adr+4); bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 8); } else if(BOOT1_index == (pRxMessage->RxData[2])) { ENETTxMessage[0] = (uint8_t)(READ_VERSION>>8); ENETTxMessage[1] = (uint8_t)(READ_VERSION); ENETTxMessage[2] = BOOT1_index; ENETTxMessage[3] = rdbyte_24c02(BOOT1_VERSION_E2adr); ENETTxMessage[4] = rdbyte_24c02(BOOT1_VERSION_E2adr+1); ENETTxMessage[5] = rdbyte_24c02(BOOT1_VERSION_E2adr+2); ENETTxMessage[6] = rdbyte_24c02(BOOT1_VERSION_E2adr+3); ENETTxMessage[7] = rdbyte_24c02(BOOT1_VERSION_E2adr+4); bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 8); } else if(APP_index == (pRxMessage->RxData[2])) { ENETTxMessage[0] = (uint8_t)(READ_VERSION>>8); ENETTxMessage[1] = (uint8_t)(READ_VERSION); ENETTxMessage[2] = APP_index; ENETTxMessage[3] = rdbyte_24c02(APP_VERSION_E2adr); ENETTxMessage[4] = rdbyte_24c02(APP_VERSION_E2adr+1); ENETTxMessage[5] = rdbyte_24c02(APP_VERSION_E2adr+2); ENETTxMessage[6] = rdbyte_24c02(APP_VERSION_E2adr+3); ENETTxMessage[7] = rdbyte_24c02(APP_VERSION_E2adr+4); bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 8); } else{} break; case CRC_UPDATE: switch(CAN_BootExecutiveStt) { case 0: if(BOOT0_index == (pRxMessage->RxData[4])) { IAP_EEPROM_ERASE(BOOT0_Flash_adr,FLASH_BLOCK_SIZE);// 擦除4K s_startAddr = BOOT0_Flash_adr; } else if(BOOT1_index == (pRxMessage->RxData[4])) { IAP_EEPROM_ERASE(BOOT1_Flash_adr,FLASH_BLOCK_SIZE);// s_startAddr = BOOT1_Flash_adr; } else if(APP_index == (pRxMessage->RxData[4])) { IAP_EEPROM_ERASE(APP_Flash_adr,FLASH_BLOCK_SIZE);// s_startAddr = APP_Flash_adr; } else{} RgEasySize = FLASH_BLOCK_SIZE;//擦除长度,擦除多长那就下载多长 CAN_BootExecutiveStt = 10; break; //循环烧写flash case 10: if(FlashBufComplete == (Flash_RxBuf_1.Flash_RxBufSta))//接收完成 缓存1 { crcData = crc16_ccitt(&Flash_RxBuf_1.RxData[0], Flash_RxBuf_1.Flash_RxBufLen); if(crcData == (Flash_RxBuf_1.Flash_RxBufCRC)) { Flash_RxBuf_1.Flash_RxBufSta = FlashBufCRCPass; ENETTxMessage[0] = (uint8_t)(CRC_UPDATE>>8); ENETTxMessage[1] = (uint8_t)(CRC_UPDATE); ENETTxMessage[2] = CRC_Pass; // ssdk_printf(SSDK_CRIT, "0x%x,ENETTxMessage[0]:0x%x,0x%x,CRC_Pass:0x%x\r\n",ENETTxMessage[0],ENETTxMessage[2]); bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 3); if(RgEasySize >= Flash_RxBuf_1.Flash_RxBufLen)//擦除长度是否大于写数据长度 { // ssdk_printf(SSDK_CRIT, "RxData1[0] :0x%x,RxData1[1]:0x%x\r\n",Flash_RxBuf_1.RxData[0],Flash_RxBuf_1.RxData[1]); External_wdt_refresh();//喂狗 4K喂狗一次 IAP_EEPROM_WRITE(s_startAddr, &Flash_RxBuf_1.RxData[0], Flash_RxBuf_1.Flash_RxBufLen);//20230209修改写flash不需要转换为32位,就是单个字节 s_startAddr = s_startAddr + (Flash_RxBuf_1.Flash_RxBufLen);//烧写地址累加 RgEasySize = RgEasySize - Flash_RxBuf_1.Flash_RxBufLen;//擦除总长度-当前写入的长度 Flash_RxBuf_1.Flash_RxBufSta = FlashBufWrite; CAN_BootExecutiveStt = 10; } else//擦除之后也得写1K,已经校验通过了 { External_wdt_refresh();//喂狗 4K喂狗一次 CAN_BootExecutiveStt = 10;//擦除长度写完,重新擦除 IAP_EEPROM_ERASE(s_startAddr,FLASH_BLOCK_SIZE);// RgEasySize = FLASH_BLOCK_SIZE;//重新为4K // ssdk_printf(SSDK_CRIT, "RxData1[0] :0x%x,RxData1[1]:0x%x\r\n",Flash_RxBuf_1.RxData[0],Flash_RxBuf_1.RxData[1]); IAP_EEPROM_WRITE(s_startAddr, &Flash_RxBuf_1.RxData[0], Flash_RxBuf_1.Flash_RxBufLen);//20230209修改写flash不需要转换为32位,就是单个字节 s_startAddr = s_startAddr + (Flash_RxBuf_1.Flash_RxBufLen);//烧写地址累加 RgEasySize = RgEasySize - Flash_RxBuf_1.Flash_RxBufLen;//擦除总长度-当前写入的长度 Flash_RxBuf_1.Flash_RxBufSta = FlashBufWrite; } } else//CRC 校验不通过 { CAN_BootExecutiveStt = 10; Flash_RxBuf_1.Flash_RxBufSta = FlashBufCRCFail; ENETTxMessage[0] = (uint8_t)(CRC_UPDATE>>8); ENETTxMessage[1] = (uint8_t)(CRC_UPDATE); ENETTxMessage[2] = CRC_Fail; ssdk_printf(SSDK_CRIT, "CCCRCfail:0x%x,RxCRCfail:0x%x\r\n",crcData,Flash_RxBuf_1.Flash_RxBufCRC); bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 3); } } else if(FlashBufComplete == (Flash_RxBuf_2.Flash_RxBufSta))//接收完成 缓存2 { crcData = crc16_ccitt(&Flash_RxBuf_2.RxData[0], Flash_RxBuf_2.Flash_RxBufLen); if(crcData == (Flash_RxBuf_2.Flash_RxBufCRC)) { CAN_BootExecutiveStt = 10; Flash_RxBuf_2.Flash_RxBufSta = FlashBufCRCPass; ENETTxMessage[0] = (uint8_t)(CRC_UPDATE>>8); ENETTxMessage[1] = (uint8_t)(CRC_UPDATE); ENETTxMessage[2] = CRC_Pass; bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 3); if(RgEasySize > 0) { // ssdk_printf(SSDK_CRIT, "RxData2[0] :0x%x,RxData2[1]:0x%x\r\n",Flash_RxBuf_2.RxData[0],Flash_RxBuf_2.RxData[1]); External_wdt_refresh();//喂狗 4K喂狗一次 IAP_EEPROM_WRITE(s_startAddr, &Flash_RxBuf_2.RxData[0], Flash_RxBuf_2.Flash_RxBufLen);//20230209修改写flash不需要转换为32位,就是单个字节 s_startAddr = s_startAddr + (Flash_RxBuf_2.Flash_RxBufLen);//烧写地址累加 RgEasySize = RgEasySize - Flash_RxBuf_2.Flash_RxBufLen;//擦除总长度-当前写入的长度 Flash_RxBuf_2.Flash_RxBufSta = FlashBufWrite; CAN_BootExecutiveStt = 10; } else//擦除之后也得写1K,已经校验通过了 { External_wdt_refresh();//喂狗 4K喂狗一次 CAN_BootExecutiveStt = 10;//擦除长度写完,重新擦除 IAP_EEPROM_ERASE(s_startAddr,FLASH_BLOCK_SIZE);// RgEasySize = FLASH_BLOCK_SIZE;//重新为4K // ssdk_printf(SSDK_CRIT, "RxData2[0] :0x%x,RxData2[1]:0x%x\r\n",Flash_RxBuf_2.RxData[0],Flash_RxBuf_2.RxData[1]); IAP_EEPROM_WRITE(s_startAddr, &Flash_RxBuf_2.RxData[0], Flash_RxBuf_2.Flash_RxBufLen);//20230209修改写flash不需要转换为32位,就是单个字节 s_startAddr = s_startAddr + (Flash_RxBuf_2.Flash_RxBufLen);//烧写地址累加 RgEasySize = RgEasySize - Flash_RxBuf_2.Flash_RxBufLen;//擦除总长度-当前写入的长度 Flash_RxBuf_2.Flash_RxBufSta = FlashBufWrite; } } else//CRC 校验不通过 { CAN_BootExecutiveStt = 10; Flash_RxBuf_2.Flash_RxBufSta = FlashBufCRCFail; ENETTxMessage[0] = (uint8_t)(CRC_UPDATE>>8); ENETTxMessage[1] = (uint8_t)(CRC_UPDATE); ENETTxMessage[2] = CRC_Fail; bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 3); ssdk_printf(SSDK_CRIT, "CCCRCfail:0x%x,RxCRCfail:0x%x\r\n",crcData,Flash_RxBuf_2.Flash_RxBufCRC); } } else//都没有接收完成 { CAN_BootExecutiveStt = 10; } break; default:break; } break; case Write_VERSION: if(BOOT0_index == (pRxMessage->RxData[2])) { WriteE2adr = BOOT0_VERSION_E2adr; } else if(BOOT1_index == (pRxMessage->RxData[2])) { WriteE2adr = BOOT1_VERSION_E2adr; } else if(APP_index == (pRxMessage->RxData[2])) { WriteE2adr = APP_VERSION_E2adr; } else{} EnterRegion = (pRxMessage->RxData[2]);//下次跳转区域 wrbyte_24c02(WriteE2adr,pRxMessage->RxData[3]); wrbyte_24c02(WriteE2adr+1,pRxMessage->RxData[4]); wrbyte_24c02(WriteE2adr+2,pRxMessage->RxData[5]); wrbyte_24c02(WriteE2adr+3,pRxMessage->RxData[6]); wrbyte_24c02(WriteE2adr+4,pRxMessage->RxData[7]); ENETTxMessage[0] = (uint8_t)(Write_VERSION>>8); //读取E2看是否正常写入 ENETTxMessage[1] = (uint8_t)(Write_VERSION); ENETTxMessage[2] = (pRxMessage->RxData[2]); ENETTxMessage[3] = rdbyte_24c02(WriteE2adr); ENETTxMessage[4] = rdbyte_24c02(WriteE2adr+1); ENETTxMessage[5] = rdbyte_24c02(WriteE2adr+2); ENETTxMessage[6] = rdbyte_24c02(WriteE2adr+3); ENETTxMessage[7] = rdbyte_24c02(WriteE2adr+4); bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 8); break; case ENTER_APP: if((BOOT0_index == EnterRegion) || (BOOT1_index == EnterRegion)) { flash.sw_rst = true; sdrv_spi_nor_deinit(&flash); /* soft reset xspi host */ sdrv_spi_nor_drv_deinit(&flash); for(;;) { ssdk_printf(SSDK_INFO, "Restart!\r\n"); udelay(100000); }//重启 } else if(APP_index == (pRxMessage->RxData[2])) { goToApp(); } else{} break; case EXCUTE_APP: wrbyte_24c02(Update_Flg_E2adr,NORMAL_ON); udelay(3000);//延时3ms goToApp(); break; case READ_PSN://读取PSN if(BOOT0_index == (pRxMessage->RxData[2])) { IAP_EEPROM_READ( BOOT0_PSN_adr,psn_data,4); } else if(BOOT1_index == (pRxMessage->RxData[2])) { IAP_EEPROM_READ( BOOT1_PSN_adr,psn_data, 4); } else { } ENETTxMessage[0] = (uint8_t)(READ_PSN>>8); //读取E2看是否正常写入 ENETTxMessage[1] = (uint8_t)(READ_PSN); ENETTxMessage[2] = (pRxMessage->RxData[2]); ENETTxMessage[3] = psn_data[3]; ENETTxMessage[4] = psn_data[2]; ENETTxMessage[5] = psn_data[1]; ENETTxMessage[6] = psn_data[0]; bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 7); break; case WRITE_IP://修改IP 重启后有效 wrbyte_24c02(BOOT_DES_IP, (pRxMessage->RxData[2])); wrbyte_24c02(BOOT_DES_IP+1,(pRxMessage->RxData[3])); wrbyte_24c02(BOOT_DES_IP+2,(pRxMessage->RxData[4])); wrbyte_24c02(BOOT_DES_IP+3,(pRxMessage->RxData[5])); ENETTxMessage[0] = (uint8_t)(WRITE_IP>>8); //读取E2看是否正常写入 ENETTxMessage[1] = (uint8_t)(WRITE_IP); ENETTxMessage[2] = rdbyte_24c02(BOOT_DES_IP ); ENETTxMessage[3] = rdbyte_24c02(BOOT_DES_IP+1); ENETTxMessage[4] = rdbyte_24c02(BOOT_DES_IP+2); ENETTxMessage[5] = rdbyte_24c02(BOOT_DES_IP+3); bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 6); break; case LOST_FRAME://丢帧 ENETTxMessage[0] = (uint8_t)(CRC_UPDATE>>8); ENETTxMessage[1] = (uint8_t)(CRC_UPDATE); ENETTxMessage[2] = CRC_Fail; printf("Lost Frame"); bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, ENETTxMessage, 3); break; default:break; } } /** * ReadUpgradeFlag * * @param[in] * @return none * * @brief read upgrade flag from flash */ void ReadUpgradeFlag(void) { static uint16_t lost_cnt = 0; uint8_t flash_buf[8] = {0,0,0,0,0,0,0,0}; //-------------------------------------------------------------------- if ( (g_canRxMsgFlag) || (Eth_Rx_Flag != 0) ) { g_canRxMsgFlag = 0; Eth_Rx_Flag --; CAN_BootExecutiveCommand(&ENET_RxBuf_1); } if(1 == flash_eth_time)//超过2s,标志未清楚认为是丢帧 { lost_cnt ++; if(lost_cnt >= 2000)//2s 定时 { lost_cnt = 0; flash_eth_time = 0; ethCmdSTT = 0;//清空接收状态,重新开始接收 flash_buf[0] = (uint8_t)(CRC_UPDATE>>8); flash_buf[1] = (uint8_t)(CRC_UPDATE); flash_buf[2] = CRC_Fail; printf("Lost Frame"); bootMsgTx(Flash_RxBuf_1.Download_Mode, OTA_CANTxID, flash_buf, 3); } } else { lost_cnt = 0; } }