#include #include #include "main.h" //设备唯一编码,固定在0x00002800位置 const uint8_t DevMac[6] __attribute__((section(".ARM.__at_0x00002800"))) = {DEVICE_TYPE & 0xFF, (DEVICE_TYPE >> 8) & 0xFF, COMM_WAY, (ADD_NUMBER >> 16) & 0xFF, (ADD_NUMBER >> 8) & 0xFF, ADD_NUMBER & 0xFF}; //const uint8_t DevMac[6] __attribute__((at(DEV_MAC_ADDRESS)))= {0x19, 0x00, 0x02, 0x00, 0x00, 0x01}; uint32_t pdwCrc32Tbl[256]; void InitCrc32Table(uint32_t* Crc32Tbl) { for (int wCnt = 0; wCnt!= 256; wCnt++){ uint32_t dwCrc = wCnt; for (int ucCnt = 0; ucCnt != 8; ucCnt++){ if (dwCrc & 1){ dwCrc = (dwCrc >> 1) ^ 0xEDB88320; } else{ dwCrc >>= 1; } } Crc32Tbl[wCnt] = dwCrc; } } uint32_t GetCrc32(int dwLen) { uint32_t Data; uint32_t dwCrc32Data = 0xFFFFFFFF; for (int dwCnt = 0; dwCnt!= dwLen; ++dwCnt){ Data = *((volatile uint8_t*)(APP_ADDRESS + dwCnt)); uint32_t dwTbl = (dwCrc32Data ^ Data) & 0xFF; dwCrc32Data = ((dwCrc32Data >> 8) & 0xFFFFFF) ^ pdwCrc32Tbl[dwTbl]; } return ~dwCrc32Data; } uint16_t CRC_Modbus(uint16_t wBase, __IO uint8_t *para, uint16_t length) { uint16_t crc = 0xffff; uint16_t index,i; for(index = 0 ; index < length;index++) { crc ^= para[index]; for(i = 0; i < 8; i++) { if(crc & 1) { crc >>= 1; crc ^= wBase; } else crc >>= 1; } } return crc; } uint32_t JumpAddress; func_ptr_t JumpToApplication; BootLoader_t BL; static void BootLoader1mSRoutine(void) { if(BL.BootLoader1mSDlyCnt) BL.BootLoader1mSDlyCnt--; if(BL.UartRevTimeOutCnt > 0) BL.UartRevTimeOutCnt--; BL.FeedDogDlyCnt++; } void FeedDogHandler(void) { if(BL.FeedDogDlyCnt >= 200) { FeedDog(); BL.FeedDogDlyCnt = 0; } } void AppWriteFlash(uint32_t AddrOffset, uint8_t *wData, int wLen) { FlashWrite(APP_ADDRESS + AddrOffset, (uint32_t *)wData, wLen / 4); } //static bool JumpToApp(uint32_t AppAddr) //{ // uint32_t u32StackTop = *((__IO uint32_t *)AppAddr); // if ((u32StackTop > SRAM_BASE) && (u32StackTop <= (SRAM_BASE + RAM_SIZE))) { // JumpAddress = *(__IO uint32_t *)(AppAddr + 4); // JumpToApplication = (func_ptr_t)JumpAddress; // __set_MSP(*(__IO uint32_t *)AppAddr); // JumpToApplication(); // } // return Error; //} static bool JumpToApp(uint32_t AppAddr) { uint32_t u32StackTop = *((__IO uint32_t *)AppAddr); if ((u32StackTop > SRAM_BASE) && (u32StackTop <= (SRAM_BASE + SRAM_SIZE))) { JumpAddress = *(__IO uint32_t *)(AppAddr + 4); JumpToApplication = (func_ptr_t)JumpAddress; __set_MSP(*(__IO uint32_t *)AppAddr); JumpToApplication(); } return Error; } void SendGetCmd(uint8_t Cmd, uint16_t PayLoad) { uint8_t sData[20], sLen; uint16_t crc16; FrameH Frame = (FrameH)sData; Frame->Header = 0x7a; Frame->SlvAddr = 0x01; Frame->Cmd = Cmd; if(Cmd == 0x01) { Frame->PayloadLen = 1; sData[sizeof(FrameHeader_t)] = PayLoad; } else if(Cmd == 0x02) { Frame->PayloadLen = 4; GDReq GDData = (GDReq)&sData[sizeof(FrameHeader_t)]; GDData->PackageIndex = PayLoad; GDData->PackageNum = BL.AppPackageCnt; } sLen = sizeof(FrameHeader_t) + Frame->PayloadLen; crc16 = CRC_Modbus(CRC16_BASE, sData, sLen); sData[sLen++] = crc16; sData[sLen++] = (crc16 >> 8) & 0x00ff; DebugUartSend(sData, sLen); } bool AnalyzeData(uint8_t *rData, uint16_t rLen) { uint16_t crc16, check; check = CRC_Modbus(CRC16_BASE, rData, rLen - 2); crc16 = (rData[rLen - 1] << 8) | rData[rLen - 2]; if(check != crc16) { return false; } FrameH Frame = (FrameH)rData; if(Frame->Cmd == 0x81) { UDReq UpData = (UDReq)&rData[sizeof(FrameHeader_t)]; BL.Para.AppFlag = 0; BL.Para.UpdateFlag = APP_UPDATE_FLAG; BL.Para.Crc32Check = UpData->AppCrc32; BL.Para.PackageCnt = UpData->PackageNum; BL.Para.AppSize = UpData->AppSize; WriteBootPara(&BL.Para); BL.BootLoader1mSDlyCnt = 20; BL.Status = BL_RESET; SendGetCmd(0x01, 1); } else if(Frame->Cmd == 0x82) { if(BL.UpDateFlag == false) return false; DownRes DownData = (DownRes)&rData[sizeof(FrameHeader_t)]; if(BL.AppPackageIdx != DownData->PackageIndex) { return false; } AppWriteFlash(BL.AppPackageIdx * 200, &BL.RxBuff[sizeof(FrameHeader_t) + sizeof(DownResponse_t)], DownData->DataLen); BL.AppPackageIdx++; BL.RevErrCnt = 0; if(BL.AppPackageIdx < BL.AppPackageCnt) { BL.Status = BL_GET_DATA; BL.BootLoader1mSDlyCnt = 5; //BuzzCtrl(10, 0, 1); } else { uint32_t crc32 = GetCrc32(BL.Para.AppSize); if(crc32 == BL.Para.Crc32Check) { BL.Status = BL_START_APP; BL.Para.AppFlag = 0; //升级成功首次启动时,把APP启动标志清除,由APP置位,下次启动便按标志启动 BL.Para.UpdateFlag = 0; BL.Para.DevType = DEV_TYPE; WriteBootPara(&BL.Para); } } } else return false; return true; } void BootLoaderLoopHandler(void) { if(BL.RxFlag) { BL.RxFlag = false; AnalyzeData(BL.RxBuff, BL.RxLen); TURN_OFF_STATE_LED(); } switch(BL.Status){ case BL_IDLE: break; case BL_RESET: if(BL.BootLoader1mSDlyCnt > 0) { break; } NVIC_SystemReset(); break; case BL_START_APP: enIrqResign(DBGUART_IRQn); enIrqResign(DBGUART_EI_IRQn); JumpToApp(APP_ADDRESS); break; case BL_ERASE_FLASH: FeedDog(); EraseFlash(); FeedDog(); BL.Status = BL_GET_DATA; BL.BootLoader1mSDlyCnt = 200; BL.AppPackageCnt = BL.Para.PackageCnt; BL.RevErrCnt = 0; BL.UpDateFlag = true; break; case BL_GET_DATA: if(BL.BootLoader1mSDlyCnt > 0) break; SendGetCmd(0x02, BL.AppPackageIdx); BL.Status = BL_WAIT_REV; BL.BootLoader1mSDlyCnt = 500; break; case BL_WAIT_REV: if(BL.BootLoader1mSDlyCnt == 0) { BL.Status = BL_GET_DATA_TIMEOUT; } break; case BL_GET_DATA_TIMEOUT: BL.RevErrCnt++; if(BL.RevErrCnt < 3) { BL.Status = BL_GET_DATA; } else { BL.Status = BL_IDLE; BL.Para.AppFlag = 0; BL.RevErrCnt = 0; BL.Para.UpdateFlag = 0; WriteBootPara(&BL.Para); BL.UpDateFlag = false; } break; } } int32_t main(void) { BSP_Init(); InitCrc32Table(pdwCrc32Tbl); ReadBootPara(&BL.Para); if(BL.Para.DevType != DEV_TYPE) { //设备类型错误,清除升级参数 BL.Status = BL_IDLE; BL.Para.AppFlag = 0; BL.Para.UpdateFlag = 0; BL.Para.DevAddr = 0x01; BL.Para.DevType = DEV_TYPE; WriteBootPara(&BL.Para); } else if(BL.Para.AppFlag == APP_START_FLAG) { BL.Status = BL_START_APP; } else if(BL.Para.UpdateFlag == APP_UPDATE_FLAG) { BL.Status = BL_ERASE_FLASH; } while (1) { FeedDogHandler(); BootLoaderLoopHandler(); } } /******************************************************************************* * 中断服务函数 ******************************************************************************/ void SysTick_IrqHandler(void) { BootLoader1mSRoutine(); } static uint16_t rLen; static uint8_t rBuff[300]; static bool Header; static uint16_t PayLen; void DbgRxIrqCallback(uint8_t RxData) { if(BL.UartRevTimeOutCnt == 0) { Header = false; rLen = 0; PayLen = 0; } BL.UartRevTimeOutCnt = 3; if(Header == false && RxData == 0x7a) { Header = true; rLen = 0; PayLen = 0; rBuff[rLen++] = RxData; } else { rBuff[rLen++] = RxData; if(rLen == 4) { PayLen = rBuff[3]; if(PayLen > 256) { Header = false; return; } } else if(rLen == sizeof(FrameHeader_t) + PayLen + 2) { BL.RxLen = rLen; memcpy(BL.RxBuff, rBuff, BL.RxLen); BL.RxFlag = true; Header = false; TURN_ON_STATE_LED_GREEN(); } } }