//#include #include "BootloaderInterface.h" #include "BootloaderProtocol.h" #include "ProtocolDefs.h" #include "BoardCfg.h" #include "timer.h" #include "WiFiCtrl.h" #include "SPI_Flash.h" #include "FlashMapping.h" #include "NetworkProtocol.h" #include "Syslog.h" #include "checksum.h" #include "FlashMapping.h" #define BOOTLOADER_FLASH_ERASE_POLL_TIMEOUT 25//100 //ms #define BOOTLOADER_FLASH_ERASE_MAX_POLL_COUNT 40//10 //One sector should not take more than 1s to erase... #define BOOTLOADER_FLASH_WRITE_POLL_TIMEOUT 25//100 //ms #define BOOTLOADER_FLASH_WRITE_MAX_POLL_COUNT 40//10 //One sector should not take more than 1s to erase... unsigned char BootloaderBuffer[300]; int BootloaderInterfaceState; int DataChunkWritten; int CurDataChunkIndex; int FirmwareUploaded; int CurDataChunkSize; int BooloaderFlashEraseState; int BootloaderFlashErased; unsigned int BootloaderCurFlashEraseAddress; int BooloaderFlashErasePollCount; int BootloaderFlashWriteState; unsigned int BootloaderCurFlashWriteAddress; int BootloaderFlashWritePollCount; int BootloaderFirmwareChunkWriteCount; char* BootloaderFlashWriteDataPtr; int BootloaderInterfaceInit() { BootloaderProtocolInit(); BootloaderResetStateMachine(); BootloaderCheckFlashBootloaderData(); update_crc_32(0,0); //Force to populate the CRC32 table... return 1; } void BootloaderInterfaceTick() { BootloaderInterfaceStateMachine(BOOTLOADER_TICK_EVENT,0); } void BootloaderExecuteCmd(char Cmd,bool CRCValid) { unsigned char *DataBufPtr = BootloaderProtocolGetDataBufferPtr(); if(CRCValid == 0) { printf("Bootloader received a frame with invalid CRC\n"); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_INVALID_CRC_CMD); return; } switch(Cmd) { case BOOTLOADER_HEARTBEAT_REQUEST: { printf("Bootloader Heartbeat Request\n"); *DataBufPtr = 1; BootloaderProtocolSendFrame(BOOTLOADER_HEARTBEAT_RESPONSE,1); break; } case BOOTLOADER_ERASE_BOOTLOADER_FLASH_REQUEST: { printf("BOOTLOADER_ERASE_BOOTLOADER_FLASH_REQUEST\n"); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_ERASE_FLASH_CMD); break; } case BOOTLOADER_INIT_UPLOAD_REQUEST: { printf("BOOTLOADER_INIT_UPLOAD_REQUEST\n"); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_INIT_UPLOAD_CMD); break; } case BOOTLOADER_GET_STATE_REQUEST: { printf("BOOTLOADER_GET_STATE_REQUEST\n"); BootloaderProtocolSendBootloaderState((char)BootloaderInterfaceState); break; } case BOOTLOADER_SEND_DATA_CHUNK_REQUEST: { // printf("BOOTLOADER_SEND_DATA_CHUNK_REQUEST\n"); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_NEW_DATA_CHUNK_CMD); break; } case BOOTLOADER_UPLOAD_FINISHED_REQUEST: { printf("BOOTLOADER_UPLOAD_FINISHED_REQUEST\n"); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_UPLOAD_FINISHED_CMD); break; } case BOOTLOADER_EXECUTE_UPGRAGE_REQUEST: { printf("BOOTLOADER_EXECUTE_UPGRAGE_REQUEST\n"); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_EXECUTE_UPGRAGE_CMD); break; } case BOOTLOADER_ABORT_OPERATION_REQUEST: { printf("BOOTLOADER_ABORT_OPERATION_REQUEST\n"); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_ABORT_CMD); } case BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_REQUEST: { printf("BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_REQUEST\n"); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_CHECK_FLASH_CMD); break; } case BOOTLOADER_GET_STORED_FIRMWARE_INFO_REQUEST: { printf("BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_REQUEST\n"); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_GET_FIRMWARE_DATA_CMD); break; } default: { break; } } } void BootloaderCRCError(char Cmd, int RxCRC, int ExpectedCRC) { printf("BootloaderProtocol detected a CRC error. Cmd: %d, RxCRC:0x%x, Expected:[0x%x]\n",Cmd,RxCRC,ExpectedCRC); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_INVALID_CRC_CMD); } void BootloaderInterfaceStateMachine(int Event, int Param) { switch(BootloaderInterfaceState) { case BOOTLOADER_STANDBY_STATE: { switch(Event) { case BOOTLOADER_TICK_EVENT: { break; } case BOOTLOADER_NEW_CMD_EVENT: { if(Param == BOOTLOADER_SM_ACTIVATE_CMD) { BootloaderInterfaceState = BOOTLOADER_ACTIVE_STATE; printf("Bootloader Interface going into active state\n"); } break; } case BOOTLOADER_TIMEOUT_EVENT: { break; } } break; } case BOOTLOADER_ACTIVE_STATE: { switch(Event) { case BOOTLOADER_TICK_EVENT: { break; } case BOOTLOADER_NEW_CMD_EVENT: { switch(Param) { case BOOTLOADER_SM_ERASE_FLASH_CMD: { ResetBootloaderFlashEraseStateMachine(); //Setup the state machine BootloaderProtocolSendACK(BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESPONSE); BootloaderInterfaceState = BOOTLOADER_ERASE_FLASH_STATE; printf("Bootloader Interface going into Erase Flash state\n"); break; } case BOOTLOADER_SM_INIT_UPLOAD_CMD: { if(BootloaderFlashErased == 0) { BootloaderProtocolSendInitUploadResponse(BOOTLOADEDR_INIT_TRANSFER_ERROR_FLASH_NOT_ERASED); } else { BootloaderProtocolSendInitUploadResponse(BOOTLOADEDR_INIT_TRANSFER_OK); //TODO: Shall we prepare something before?? BootloaderProtocolSendACK(BOOTLOADER_READY_FOR_DATA_RESPONSE); BootloaderInterfaceState = BOOTLOADER_RECEIVING_FIRMWARE_STATE; printf("Bootloader Interface going into Firmware RX state\n"); } break; } case BOOTLOADER_SM_ABORT_CMD: { //TODO invalidate data in Flash printf("Aborting upload, going into STANDBY mode\n"); BootloaderResetStateMachine(); break; } case BOOTLOADER_SM_EXECUTE_UPGRAGE_CMD: { if(BootloaderCheckFlashBootloaderData() == RET_OK) { BootloaderProtocolSendACK(BOOTLOADER_EXECUTE_UPGRADE_RESPONSE); printf("Bootloader will now upgrade and reboot!!\n"); char Flags[2]; Flags[BOOTLOADER_FLAGS_ACTION_FLAG_INDEX] = BOOTLOADER_ACTION_FLASH_FIRMWARE_VALUE; Flags[BOOTLOADER_FLAGS_ACTION_VALIDATOR_INDEX] = BOOTLOADER_FLASH_FIRMWARE_VALIDATOR; SPIFlashWriteBuffer(Flags,2,FLASH_BTLDR_FLAGS_ADDRESS); Sleep(100); TurnOFFWiFi(); Sleep(100); SoftReset(); } else { BootloaderProtocolSendNACK(BOOTLOADER_EXECUTE_UPGRADE_RESPONSE); printf("Bootloader upgrade request denied: Firmware not uploaded\n"); } break; } case BOOTLOADER_SM_CHECK_FLASH_CMD: { if(BootloaderCheckFlashBootloaderData() == RET_OK) { BootloaderProtocolSendFlashCheckResult(FLASH_CHECK_SUCCESS); } else { BootloaderProtocolSendFlashCheckResult(FLASH_CHECK_FAILED); } break; } case BOOTLOADER_SM_GET_FIRMWARE_DATA_CMD: { char Response[21]; memset(Response,0xFF,sizeof(Response)); if(BootloaderCheckFlashBootloaderData() != RET_OK) { Response[0] = 0; } else { Response[0] = 1; BootloaderIntToBytes(&Response[1],mStoredBootloaderInfo.Firmwareflags); BootloaderIntToBytes(&Response[5],mStoredBootloaderInfo.NbRecords); BootloaderIntToBytes(&Response[9],mStoredBootloaderInfo.FirmwareSize); BootloaderIntToBytes(&Response[13],mStoredBootloaderInfo.Versioncode); BootloaderIntToBytes(&Response[17],mStoredBootloaderInfo.DataCRC32); } BootloaderProtocolSendStoredFirmwareInfoResponse(Response,sizeof(Response)); break; } default: { //SEND NACK BootloaderProtocolSendNACK(Param); break; } } break; } case BOOTLOADER_TIMEOUT_EVENT: { break; } } break; } case BOOTLOADER_ERASE_FLASH_STATE: { switch(Event) { case BOOTLOADER_TICK_EVENT: { int res = BootloaderFlashEraseStateMachine(BOOTLOADER_FLASH_ERASE_SM_TICK_EVENT); switch(res) { case BOOTLOADER_FLASH_ERASE_RUNNING_RES: { break; } case BOOTLOADER_FLASH_ERASE_FINISHED_RES: { printf("Flash erase finished. Bootloader Interface going into Active state\n"); BootloaderProtocolSendACK(BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESULT_RESPONSE); //TODO: send result instead BootloaderInterfaceState = BOOTLOADER_ACTIVE_STATE; BootloaderFlashErased = 1; break; } case BOOTLOADER_FLASH_ERASE_ERROR_RES: { printf("Flash erase error. Bootloader Interface going into Active state\n"); BootloaderProtocolSendNACK(BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESULT_RESPONSE); //TODO: send result instead BootloaderInterfaceState = BOOTLOADER_ACTIVE_STATE; break; } case BOOTLOADER_FLASH_ERASE_ABORT_RES: { printf("Flash erase abort. Bootloader Interface going into Active state\n"); BootloaderProtocolSendNACK(BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESULT_RESPONSE); //TODO: send result instead BootloaderInterfaceState = BOOTLOADER_ACTIVE_STATE; break; } } break; } case BOOTLOADER_NEW_CMD_EVENT: { switch(Param) { case BOOTLOADER_SM_ABORT_CMD: { //TODO: stop erasing and reset SM. //TODO invalidate data in Flash BootloaderFlashEraseStateMachine(BOOTLOADER_FLASH_ERASE_SM_ABORT_EVENT); printf("Aborting Flash erase, going into STANDBY mode\n"); BootloaderResetStateMachine(); break; } default: { //SEND NACK BootloaderProtocolSendNACK(Param); break; } } break; } case BOOTLOADER_TIMEOUT_EVENT: { break; } } break; } case BOOTLOADER_RECEIVING_FIRMWARE_STATE: { switch(Event) { case BOOTLOADER_TICK_EVENT: { int res = BootloaderFlashWriteStateMachine(BOOTLOADER_FLASH_WRITE_SM_TICK_EVENT); switch(res) { case BOOTLOADER_FLASH_WRITING_RES: { break; } case BOOTLOADER_FLASH_WRITE_FINISHED_RES: { BootloaderProtocolSendDataChunkResult(BOOTLOADER_CHUNK_TRANSFER_SUCCESS,CurDataChunkIndex); printf("Bootloader Chunk %d successfuly written to flash\n",CurDataChunkIndex); CurDataChunkIndex++; break; } case BOOTLOADER_FLASH_WRITE_ERROR_RES: { BootloaderProtocolSendDataChunkResult(BOOTLOADER_CHUNK_TRANSFER_ERROR_FLASH_ERROR,CurDataChunkIndex); BootloaderResetStateMachine(); printf("Bootloader Flash write error. Aborting and going into STANDBY state\n"); break; } case BOOTLOADER_FLASH_WRITE_ABORT_RES: { break; } } break; } case BOOTLOADER_NEW_CMD_EVENT: { switch(Param) { case BOOTLOADER_SM_NEW_DATA_CHUNK_CMD: { //TODO:Check data validity //TODO: Write data to flash //Extract index from buffer unsigned int DataChunkIndex = 0; unsigned int DataChunkSize = 0; DataChunkSize = 0; // DataChunkIndex = BootloaderBuffer[0]; // DataChunkIndex <<= 8; // DataChunkIndex += BootloaderBuffer[1]; // DataChunkIndex <<= 8; // DataChunkIndex += BootloaderBuffer[2]; // DataChunkIndex <<= 8; // DataChunkIndex += BootloaderBuffer[3]; DataChunkIndex = BootloaderBytesToInt(&BootloaderBuffer[0]); // DataChunkSize = BootloaderBuffer[4]; // DataChunkSize <<= 8; // DataChunkSize += BootloaderBuffer[5]; // DataChunkSize <<= 8; // DataChunkSize += BootloaderBuffer[6]; // DataChunkSize <<= 8; // DataChunkSize += BootloaderBuffer[7]; DataChunkSize = BootloaderBytesToInt(&BootloaderBuffer[4]); BootloaderFlashWriteDataPtr = &BootloaderBuffer[8]; //Check CRC if(CurDataChunkIndex != DataChunkIndex) { //Error... abort. BootloaderProtocolSendDataChunkResult(BOOTLOADER_CHUNK_TRANSFER_ERROR_INVALID_CHUNK_INDEX,CurDataChunkIndex); printf("Bootloader Interface ABORTING UPLOAD. Received invalid chunk index. Rx: [%d] - Expected: [%d]\n", DataChunkIndex,CurDataChunkIndex); ResetBootloaderFlashWriteStateMachine(); } else { CurDataChunkSize = DataChunkSize; BootloaderFlashWriteStateMachine(BOOTLOADER_FLASH_WRITE_SM_NEW_BUFFER_EVENT); printf("Bootloader Interface. Rx new data chunk. Writing to flash. Index: %d\n", DataChunkIndex); } break; } case BOOTLOADER_SM_INVALID_CRC_CMD: { //BootloaderProtocol determined the CRC of the chunk was invalid. BootloaderProtocolSendDataChunkResult(BOOTLOADER_CHUNK_TRANSFER_ERROR_RESEND,CurDataChunkIndex); printf("Bootloader Interface invalid chunk CRC. Requesting resend chunk index [%d]\n", CurDataChunkIndex); break; } case BOOTLOADER_SM_UPLOAD_FINISHED_CMD: { printf("Bootloader Interface firmware upload finished. Check flash integrity.\n"); if(BootloaderCheckFlashBootloaderData() == RET_OK) { BootloaderInterfaceState = BOOTLOADER_ACTIVE_STATE; //BootloaderProtocolSendACK(BOOTLOADER_UPLOAD_FINISHED_RESPONSE); BootloaderProtocolSendFirmwareUploadResult(BOOTLOADER_UPLOAD_SUCCESS); FirmwareUploaded = 1; } else { printf("Firmware integrity check failed. Going back to STANDBY state.\n"); // BootloaderProtocolSendNACK(BOOTLOADER_UPLOAD_FINISHED_RESPONSE); BootloaderProtocolSendFirmwareUploadResult(BOOTLOADER_UPLOAD_FAILED_FLASH_VERIFICATION_ERROR); BootloaderResetStateMachine(); FirmwareUploaded = 0; } break; } case BOOTLOADER_SM_ABORT_CMD: { //TODO invalidate data in Flash printf("Bootloader aborting firmware download. Going back to STANDBY state\n"); BootloaderFlashWriteStateMachine(BOOTLOADER_FLASH_WRITE_SM_ABORT_EVENT); BootloaderResetStateMachine(); break; } default: { //WHAT TO DO??? break; } } break; } case BOOTLOADER_TIMEOUT_EVENT: { break; } } break; } case BOOTLOADER_SENDING_FIRMWARE_COPY_STATE: { switch(Event) { case BOOTLOADER_TICK_EVENT: { break; } case BOOTLOADER_NEW_CMD_EVENT: { switch(Param) { case BOOTLOADER_SM_ABORT_CMD: { //TODO invalidate data in Flash printf("Aborting upload, going into STANDBY mode\n"); BootloaderResetStateMachine(); break; } default: { //SEND NACK BootloaderProtocolSendNACK(Param); break; } } break; } case BOOTLOADER_TIMEOUT_EVENT: { break; } } break; } case BOOTLOADER_PRINTING_FIRMWARE_STATE: { switch(Event) { case BOOTLOADER_TICK_EVENT: { break; } case BOOTLOADER_NEW_CMD_EVENT: { switch(Param) { case BOOTLOADER_SM_ABORT_CMD: { //TODO invalidate data in Flash printf("Aborting upload, going into STANDBY mode\n"); BootloaderResetStateMachine(); break; } default: { //SEND NACK BootloaderProtocolSendNACK(Param); break; } } break; } case BOOTLOADER_TIMEOUT_EVENT: { break; } } break; } } } void BootloaderResetStateMachine() { BootloaderInterfaceState = BOOTLOADER_STANDBY_STATE; DataChunkWritten = 0; CurDataChunkIndex = 0; FirmwareUploaded = 0; CurDataChunkIndex = 0; FirmwareUploaded = 0; CurDataChunkSize = 0; ResetBootloaderFlashEraseStateMachine(); ResetBootloaderFlashWriteStateMachine(); CloseBootloaderServer(); } void BootloaderActivateBootloader() { OpenBootloaderServer(); BootloaderInterfaceStateMachine(BOOTLOADER_NEW_CMD_EVENT,BOOTLOADER_SM_ACTIVATE_CMD); } void BootloaderDeactivateBootloader() { BootloaderResetStateMachine(); // CloseBootloaderServer(); // BootloaderIterfaceStateMachine(BOOTLOADER_SM_ABORT_CMD,0); } int BootloaderFlashEraseStateMachine(int event) { if(event == BOOTLOADER_FLASH_ERASE_SM_ABORT_EVENT) { ResetBootloaderFlashEraseStateMachine(); return BOOTLOADER_FLASH_ERASE_ABORT_RES; } switch(BooloaderFlashEraseState) { case BOOTLOADER_FLASH_ERASE_SECTOR_STATE: { if(SPIFlashErase64KSector(BootloaderCurFlashEraseAddress,0) == RET_ERROR) { printf("Bootloader Interface Erasing sector %0x%x\n", BootloaderCurFlashEraseAddress); BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_ERROR_STATE; return BOOTLOADER_FLASH_ERASE_ERROR_RES; } BooloaderFlashErasePollCount = 0; TimerStart(BOOTLOADER_FLASH_POLL_TIMER,BOOTLOADER_FLASH_ERASE_POLL_TIMEOUT); BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_WAIT_FOR_SECTOR_DONE; break; } case BOOTLOADER_FLASH_ERASE_WAIT_FOR_SECTOR_DONE: { if(IsTimerExpired(BOOTLOADER_FLASH_POLL_TIMER) == 1) { if(SPIFlashCheckBusy() == 0) //sector erased { if(BootloaderCurFlashEraseAddress == FLASH_BTLDR_FIRMWARE_LAST_64K_SECTOR_ADD) { //Whole bootloader partition is erased. printf("Bootloader Interface: Last sector 0x%x erased after %d polls\n",BootloaderCurFlashEraseAddress,BooloaderFlashErasePollCount); BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_FINISHED_STATE; return BOOTLOADER_FLASH_ERASE_FINISHED_RES; break; } else { printf("Bootloader Interface sector 0x%x erased after %d polls\n",BootloaderCurFlashEraseAddress,BooloaderFlashErasePollCount); BootloaderCurFlashEraseAddress += SPI_FLASH_64K_SECTOR_SIZE; BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_SECTOR_STATE; } } else { if(BooloaderFlashErasePollCount >= BOOTLOADER_FLASH_ERASE_MAX_POLL_COUNT) { printf("Bootloader Interface Flash erase error. Max poll count reached : %d!!!\n",BooloaderFlashErasePollCount); BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_ERROR_STATE; return BOOTLOADER_FLASH_ERASE_ERROR_RES; } else { TimerStart(BOOTLOADER_FLASH_POLL_TIMER,BOOTLOADER_FLASH_ERASE_POLL_TIMEOUT); BooloaderFlashErasePollCount++; } } } break; } case BOOTLOADER_FLASH_ERASE_CHECKBACK_STATE: { break; } case BOOTLOADER_FLASH_ERASE_FINISHED_STATE: { return BOOTLOADER_FLASH_ERASE_FINISHED_RES; break; } case BOOTLOADER_FLASH_ERASE_ERROR_STATE: { return BOOTLOADER_FLASH_ERASE_ERROR_RES; break; } } return BOOTLOADER_FLASH_ERASE_RUNNING_RES; } int ResetBootloaderFlashEraseStateMachine() { BooloaderFlashEraseState = BOOTLOADER_FLASH_ERASE_SECTOR_STATE; BootloaderCurFlashEraseAddress = FLASH_BTLDR_FIRMWARE_START_ADDRESS; BooloaderFlashErasePollCount = 0; BootloaderFlashErased = 0; } int BootloaderFlashWriteStateMachine(int event) { switch(BootloaderFlashWriteState) { case BOOTLOADER_FLASH_WRITE_STANDBY_STATE: { if(event == BOOTLOADER_FLASH_WRITE_SM_TICK_EVENT) { //TODO: timeout // return BOOTLOADER_FLASH_WRITE_ERROR_RES; } else if(event == BOOTLOADER_FLASH_WRITE_SM_NEW_BUFFER_EVENT) { // printf("Starting writing data to Flash\nFlash Address : Data\n"); BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_BUFFER_STATE; BootloaderFirmwareChunkWriteCount = 0; return BOOTLOADER_FLASH_WRITING_RES; } break; } case BOOTLOADER_FLASH_WRITE_BUFFER_STATE: { if(BootloaderFlashWriteDataPtr == 0) { ResetBootloaderFlashWriteStateMachine(); return BOOTLOADER_FLASH_WRITE_ERROR_RES; } while(BootloaderFirmwareChunkWriteCount < CurDataChunkSize) { //printf("%d : 0x%x\n",(BootloaderCurFlashWriteAddress-FLASH_BTLDR_FIRMWARE_START_ADDRESS),(unsigned int)*BootloaderFlashWriteDataPtr); if(SPIFlashWriteByte(BootloaderCurFlashWriteAddress++,*BootloaderFlashWriteDataPtr++,1) == RET_ERROR) { printf("Bootloader flash error. Aborting and going back to STANDBY\n"); BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_ERROR_STATE; return BOOTLOADER_FLASH_WRITE_ERROR_RES; } int cnt = 0; while(1) { if(SPIFlashCheckBusy() == 0) { break; } if(cnt++ > 200) { printf("Bootloader flash write timeout error. Aborting and going back to STANDBY\n"); BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_ERROR_STATE; return BOOTLOADER_FLASH_WRITE_ERROR_RES; } } BootloaderFirmwareChunkWriteCount++; } BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_WAIT_FOR_BYTE_DONE; return BOOTLOADER_FLASH_WRITING_RES; // BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_STANDBY_STATE; // return BOOTLOADER_FLASH_WRITE_FINISHED_RES; break; } case BOOTLOADER_FLASH_WRITE_WAIT_FOR_BYTE_DONE: { if(event == BOOTLOADER_FLASH_WRITE_SM_TICK_EVENT) { BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_STANDBY_STATE; return BOOTLOADER_FLASH_WRITE_FINISHED_RES; // if(SyslogIsBufferEmpty() == RET_OK) // { // BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_STANDBY_STATE; // return BOOTLOADER_FLASH_WRITE_FINISHED_RES; // } // else // { // return BOOTLOADER_FLASH_WRITING_RES; // } } break; } case BOOTLOADER_FLASH_WRITE_CHECKBACK_STATE: { break; } case BOOTLOADER_FLASH_WRITE_FINISHED_STATE: { return BOOTLOADER_FLASH_WRITE_FINISHED_RES; break; } case BOOTLOADER_FLASH_WRITE_ERROR_STATE: { return BOOTLOADER_FLASH_WRITE_ERROR_RES; break; } } } int BootloaderPrintFlashData() { } int BootloaderCheckFlashBootloaderData() { unsigned char FlashData[700]; unsigned int FlashAddress = FLASH_BTLDR_FIRMWARE_START_ADDRESS; unsigned int FileHeaderCode, FirmwareFlags, NbRecords, FirmwareSize, VersionCode, CRC32; unsigned int ComputedCRC32 = CRC_START_32; //SPIFlashReadBuffer(FlashData,700,FlashAddress); printf("Checking Flash bootloader data integrity... \n"); SPIFlashReadBuffer(FlashData,FLASH_BTLDR_HEADER_SIZE,FlashAddress); FileHeaderCode = BootloaderBytesToInt(FlashData); FirmwareFlags = BootloaderBytesToInt(&FlashData[4]); NbRecords = BootloaderBytesToInt(&FlashData[8]); FirmwareSize = BootloaderBytesToInt(&FlashData[12]); VersionCode = BootloaderBytesToInt(&FlashData[16]); CRC32 = BootloaderBytesToInt(&FlashData[20]); mStoredBootloaderInfo.Firmwareflags = FirmwareFlags; mStoredBootloaderInfo.NbRecords = NbRecords; mStoredBootloaderInfo.FirmwareSize = FirmwareSize; mStoredBootloaderInfo.Versioncode = VersionCode; mStoredBootloaderInfo.DataCRC32 = CRC32; //printf("File Header: Code:[0x%x] - Flags:[0x%x] - Nb Records:[%d] - Firmware Size:[%d] - Version:[0x%x] - CRC32:[0x%x]\n",FileHeaderCode,FirmwareFlags,NbRecords,FirmwareSize,VersionCode,CRC32); if(FileHeaderCode != BOOTLOADER_FILE_HEADER_CODE) { // printf("Invalid file header code, aborting\n"); return RET_ERROR; } if(NbRecords == 0) { // printf("No records in file (NbRecords = 0), aborting\n"); return RET_ERROR; } FlashAddress += FLASH_BTLDR_HEADER_SIZE; //point to the start of bootloader data int CurRecord = 0; bool Done = false; int RecHeader, RecSize, RecStartAddress; //Check the header of each sector. while(Done == false) { SPIFlashReadBuffer(FlashData,12,FlashAddress); RecHeader = BootloaderBytesToInt(FlashData); RecSize = BootloaderBytesToInt(&FlashData[4]); RecStartAddress = BootloaderBytesToInt(&FlashData[8]); FlashAddress += 12; if(RecHeader != BOOTLOADER_RECORD_HEADER_CODE) { // printf("Error in record #%d. Invalid header code : [0x%x]\n",CurRecord,RecHeader); return RET_ERROR; } if(RecSize == 0) { // printf("Error in record #%d. Invalid record size (RecordSize = 0) \n"); return RET_ERROR; } // printf("Record #%d OK! Header:[0x%x] - Size:[%d] - Start Address:[0x%x]\n",CurRecord,RecHeader,RecSize,RecStartAddress); // while(SyslogIsBufferEmpty() == RET_ERROR) // { // SyslogTick(); // TickWiFi(); // } CurRecord++; if(CurRecord == NbRecords) { // Done = true; // printf("All records checked OK! Computing CRC...\n"); Done = true; break; //return RET_OK; } else { FlashAddress += RecSize; } } //Now, compute whole data CRC FlashAddress = FLASH_BTLDR_FIRMWARE_START_ADDRESS + FLASH_BTLDR_HEADER_SIZE; char Byte; int i; for(i = 0; i < FirmwareSize; i++) { SPIFlashReadBuffer(&Byte,1,FlashAddress++); ComputedCRC32 = update_crc_32(ComputedCRC32,Byte); } ComputedCRC32 ^= 0xffffffffL; if(ComputedCRC32 == CRC32) { // printf("CRC32 matches. Computed:[0x%x] - Expected:[0x%x]\n",ComputedCRC32,CRC32); // printf("Flash check success. Firmware is valid\n"); return RET_OK; } else { // printf("CRC32 mismatch. Computed:[0x%x] - Expected:[0x%x]\n",ComputedCRC32,CRC32); // printf("Flash check failed.\n"); return RET_ERROR; } return RET_OK; } int ResetBootloaderFlashWriteStateMachine() { BootloaderFlashWriteState = BOOTLOADER_FLASH_WRITE_STANDBY_STATE; BootloaderCurFlashWriteAddress = FLASH_BTLDR_FIRMWARE_START_ADDRESS; BootloaderFlashWritePollCount = 0; BootloaderFirmwareChunkWriteCount = 0; BootloaderFlashWriteDataPtr = 0; BootloaderFirmwareChunkWriteCount = 0; return RET_OK; } int BootloaderBytesToInt(unsigned char *Bytes) { if(Bytes == 0) { return 0; } int Output = Bytes[0]; Output <<= 8; Output += Bytes[1]; Output <<= 8; Output += Bytes[2]; Output <<= 8; Output += Bytes[3]; return Output; } int BootloaderIntToBytes(unsigned char *Buf, unsigned int Input) { if(Buf == 0) { return 0; } Buf[3] = (unsigned char)(Input & 0xFF); Input >>= 8; Buf[2] = (unsigned char)(Input & 0xFF); Input >>= 8; Buf[1] = (unsigned char)(Input & 0xFF); Input >>= 8; Buf[0] = (unsigned char)(Input & 0xFF); Input >>= 8; return 1; }