From 19bcaaf18cef573386ebebeaca2264ff58ee9c18 Mon Sep 17 00:00:00 2001 From: Oliver Walter Date: Thu, 8 Feb 2024 02:44:26 +0100 Subject: [PATCH] existing FW file check to avoid redundant transmit + refactro dupliacte code --- Application/Tasks/FirmwareHandler.c | 61 +++++++++++++++++--------- Application/Tasks/FirmwareUpdate.c | 66 ++++++++++++++++++++--------- Application/Tasks/UsbDataHandler.c | 24 +++++++---- Application/Tasks/UsbDataHandler.h | 5 ++- proto/firmware.proto | 16 +++++++ 5 files changed, 121 insertions(+), 51 deletions(-) diff --git a/Application/Tasks/FirmwareHandler.c b/Application/Tasks/FirmwareHandler.c index 8bba0d7..bcb0e98 100644 --- a/Application/Tasks/FirmwareHandler.c +++ b/Application/Tasks/FirmwareHandler.c @@ -13,8 +13,8 @@ static FirmwareStart msg_FirmwareStart; static FirmwarePackage msg_FirmwarePackage; static FirmwarePackageAck msg_FirmwarePackageAck; static FirmwareDone msg_FirmwareDone; - -static UsbDataPacket pack_FirmwarePackageAck; +static FirmwareFileCheck msg_FirmwareFileCheck; +static UsbDataPacket pack_FirmwarePackage; static FIL FwFile = {0}; @@ -50,37 +50,56 @@ void DataSend_FirmwarePackgeAck(bool ack, uint32_t crc, uint32_t counter, uint32 msg_FirmwarePackageAck.crc_pac = crc; msg_FirmwarePackageAck.device_id =device; - - pb_ostream_t ostream = pb_ostream_from_buffer(pack_FirmwarePackageAck.data,sizeof(pack_FirmwarePackageAck.data)); - bool status = pb_encode(&ostream, FirmwarePackageAck_fields, &msg_FirmwarePackageAck); - - pack_FirmwarePackageAck.head.length= ostream.bytes_written; - pack_FirmwarePackageAck.head.type = 0xF04; - pack_FirmwarePackageAck.head.check = UsbDataPacket_head_sum(&pack_FirmwarePackageAck); - - if(status) { - while (CDC_Transmit_HS((uint8_t*)&pack_FirmwarePackageAck, pack_FirmwarePackageAck.head.length + sizeof(UsbDataPacketHead) ) == USBD_BUSY) - { - osDelay(3); - } - } else { - Error_Handler(); - } - + UsbDataPacketSendMessage(UsbPackageType_FIRMWAREPACKAGEACK, &pack_FirmwarePackage, FirmwarePackageAck_fields, &msg_FirmwarePackageAck); } + +void DataSend_FirmwareFileCheck(uint32_t crc, uint32_t device_id, bool ready_for_data, UINT size, char* name) { + msg_FirmwareFileCheck.crc_fw = crc; + msg_FirmwareFileCheck.device_id = device_id; + msg_FirmwareFileCheck.ready_for_data = ready_for_data; + msg_FirmwareFileCheck.size = size; + memcpy(msg_FirmwareFileCheck.name, name, sizeof(msg_FirmwareFileCheck.name)); + + UsbDataPacketSendMessage(UsbPackageType_FIRMWAREFILECHECK, &pack_FirmwarePackage, FirmwareFileCheck_fields, &msg_FirmwareFileCheck); +} + + +#define CHUNK_SIZE 256 // Change this to the size of chunks you want to read +static uint8_t crc_buffer[CHUNK_SIZE]; + void DataClbk_FirmwareStart(void *msg, uint32_t length) { DATA_CLBK_SETUP(FirmwareStart); fwStartTime = osKernelGetSysTimerCount(); fwPackageCounter = 0; - + uint32_t crc = 0; + UINT totalRead = 0; + UINT bytesRead = 0; + if(FileOpen) { f_close(&FwFile); } + // Check if file already exists + if(f_open(&FwFile, msg_FirmwareStart.name, FA_READ) == FR_OK) { + + __HAL_CRC_DR_RESET(&hcrc); + do { + f_read(&FwFile, crc_buffer, CHUNK_SIZE, &bytesRead); + crc = HAL_CRC_Accumulate(&hcrc, (uint32_t *)crc_buffer, bytesRead); + totalRead+=bytesRead; + } while(bytesRead == CHUNK_SIZE); + f_close(&FwFile); + + if(crc == msg_FirmwareStart.crc_fw) { + // CRC matches, no need for transfer + DataSend_FirmwareFileCheck(crc, msg_FirmwareStart.device_id, false, totalRead, msg_FirmwareStart.name); + return; + } + } fresult_open = f_open(&FwFile, msg_FirmwareStart.name, FA_CREATE_ALWAYS | FA_WRITE); FileOpen=true; - + DataSend_FirmwareFileCheck(crc, msg_FirmwareStart.device_id, fresult_open==FR_OK, totalRead, msg_FirmwareStart.name); } diff --git a/Application/Tasks/FirmwareUpdate.c b/Application/Tasks/FirmwareUpdate.c index becef4b..d0cae49 100644 --- a/Application/Tasks/FirmwareUpdate.c +++ b/Application/Tasks/FirmwareUpdate.c @@ -4,6 +4,7 @@ #include "CLSAddress.h" #include "fatfs.h" #include "FirmwareUpdate.h" +#include "UsbDataHandler.h" // Memory for the task StaticTask_t CLS_FW_Task_cb; @@ -22,7 +23,6 @@ const osThreadAttr_t CLS_FW_Task_attr = { }; osMutexId_t CLS_FW_Task_FileLock = NULL; -static FirmwareUpdateArgs configuration = {0}; static FIL fw_file; static FwFrame frame = {0}; @@ -33,15 +33,15 @@ void wait_for_start_callback(uint16_t canid, uint8_t * data, uint8_t size) { osThreadFlagsSet(CLS_FW_Task_id, TASK_FLAG_WAIT); } -void wait_for_start() { +void wait_for_start(FirmwareUpdateArgs * configuration) { // setup wait_for_start_callback to get notified when the slave is ready - uint16_t ready_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration.device, CLS_CH_FW_MISO); + uint16_t ready_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration->device, CLS_CH_FW_MISO); // wait_for_start_callback // MessageCode::Firmware(FirmwareChannel::SlaveOutMasterIn); CanData_regEventMsg(ready_canid, wait_for_start_callback); // setup the command to send the slave into booloader mode - uint16_t target_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration.device, CLS_CH_FW_BOOTCALL); + uint16_t target_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration->device, CLS_CH_FW_BOOTCALL); uint8_t bootloader_call[8] = {0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab}; @@ -87,10 +87,10 @@ void running_callback_ack(uint16_t canid, uint8_t * data, uint8_t size) { } -void running() { - uint16_t error_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration.device, CLS_CH_FW_MISO); - uint16_t ack_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration.device, CLS_CH_FW_SLAVE_FEEDBACK); - uint16_t target_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration.device, CLS_CH_FW_MOSI); +void running(FirmwareUpdateArgs * configuration) { + uint16_t error_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration->device, CLS_CH_FW_MISO); + uint16_t ack_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration->device, CLS_CH_FW_SLAVE_FEEDBACK); + uint16_t target_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration->device, CLS_CH_FW_MOSI); CLS_BSP_TxHeaderType header = CREATE_BSP_CAN_HEADER(target_canid,CLS_BSP_DLC_BYTES_8); CanData_regEventMsg(error_canid,running_callback_error); @@ -129,7 +129,8 @@ void running() { } - +#define MAX_FW_UPDATES 16 +osMessageQueueId_t fwUpdateQueue; void CLSFirmwareUpdateTask_func(void *argument); @@ -139,31 +140,54 @@ void FirmwareUpdateTask_start(FirmwareUpdateArgs args) { CLS_FW_Task_FileLock = osMutexNew(NULL); } + // Initialize the queue if it hasn't been initialized yet + if(fwUpdateQueue == NULL) { + fwUpdateQueue = osMessageQueueNew(MAX_FW_UPDATES, sizeof(FirmwareUpdateArgs), NULL); + } + if(CLS_FW_Task_FileLock == NULL) { // error cant create mutex return; - } + } + + osMessageQueuePut(fwUpdateQueue, &args, 0, 0); + // check CLS_FW_Task_id is null or stopped // only one Task can runn at once if(CLS_FW_Task_id == NULL || osThreadGetState(CLS_FW_Task_id) == osThreadTerminated) { - configuration = args; CLS_FW_Task_id = osThreadNew(CLSFirmwareUpdateTask_func, NULL, &CLS_FW_Task_attr); } } - +UsbDataPacket buffer; void CLSFirmwareUpdateTask_func(void *argument) { - char * filename = configuration.name; - if( f_open(&fw_file, filename, FA_READ) != FR_OK) { - // TODO: Logging - osThreadExit(); - } + FirmwareUpdateArgs args; + osStatus_t status; + + while(1) { + // Wait for a firmware update request + status = osMessageQueueGet(fwUpdateQueue, &args, NULL, 100); + + // If the queue is empty, terminate the task + if (status != osOK) { + osThreadExit(); + } + + char * filename = args.name; + if(f_open(&fw_file, filename, FA_READ) != FR_OK) { + // TODO: Logging + continue; + } - wait_for_start(); + wait_for_start(&args); - running(); + running(&args); + FirmwareUpdateDone done = { + .device_id = args.device, + }; - f_close(&fw_file); - osThreadExit(); + //UsbDataPacketSendMessage(UsbPackageType_FIRMWAREUPDATEDONE, &buffer,FirmwareUpdateDone_fields,&done); + f_close(&fw_file); + } } \ No newline at end of file diff --git a/Application/Tasks/UsbDataHandler.c b/Application/Tasks/UsbDataHandler.c index 8205951..f049656 100644 --- a/Application/Tasks/UsbDataHandler.c +++ b/Application/Tasks/UsbDataHandler.c @@ -195,22 +195,30 @@ bool UsbDataPacket_head_check(const UsbDataPacket *p) { #include "usbd_cdc_if.h" #include -static UsbDataPacket packet; -void USBDataResonse(void * msg, const pb_msgdesc_t* fields, UsbPackageType typeid) { - pb_ostream_t ostream = pb_ostream_from_buffer(packet.data,sizeof(packet.data)); + + +bool UsbDataPacketSendMessage(uint32_t type , UsbDataPacket * buffer ,const pb_msgdesc_t * fields ,const void* msg) { + pb_ostream_t ostream = pb_ostream_from_buffer(buffer->data,sizeof(buffer->data)); bool status = pb_encode(&ostream, fields ,msg); - packet.head.length = ostream.bytes_written; - packet.head.type = typeid; - packet.head.check = UsbDataPacket_head_sum(&packet); + buffer->head.length = ostream.bytes_written; + buffer->head.type = type; + buffer->head.check = UsbDataPacket_head_sum(buffer); if(status) { - while (CDC_Transmit_HS((uint8_t*)&packet, packet.head.length + sizeof(UsbDataPacketHead) ) == USBD_BUSY) + while (CDC_Transmit_HS((uint8_t*)buffer, buffer->head.length + sizeof(UsbDataPacketHead) ) == USBD_BUSY) { osDelay(3); } } else { - Error_Handler(); + return false; } + return true; +} + + +static UsbDataPacket packet; +void USBDataResonse(void * msg, const pb_msgdesc_t* fields, UsbPackageType typeid) { + UsbDataPacketSendMessage(typeid, &packet, fields, msg); } //__attribute__((weak)) void DataClbk_FirmwareStart(void *msg, uint32_t length) {} diff --git a/Application/Tasks/UsbDataHandler.h b/Application/Tasks/UsbDataHandler.h index e58e5e4..95d3a5d 100644 --- a/Application/Tasks/UsbDataHandler.h +++ b/Application/Tasks/UsbDataHandler.h @@ -3,7 +3,7 @@ #include "stdbool.h" #include "stdint.h" - +#include "pb_common.h" #ifdef __cplusplus extern "C" { #endif @@ -60,6 +60,9 @@ uint8_t UsbDataPacket_head_sum(const UsbDataPacket* p); */ bool UsbDataPacket_head_check(const UsbDataPacket* p); + +bool UsbDataPacketSendMessage(uint32_t type , UsbDataPacket * buffer ,const pb_msgdesc_t * fields ,const void* msg); + /** * @brief This function starts the USB data handler. * diff --git a/proto/firmware.proto b/proto/firmware.proto index 2926a96..6bba2e3 100644 --- a/proto/firmware.proto +++ b/proto/firmware.proto @@ -8,6 +8,8 @@ enum UsbPackageType { FIRMWAREPACKAGE = 3842; // 0xF02 FIRMWAREDONE = 3843; // 0xF03 FIRMWAREPACKAGEACK = 3844; // 0xF04 + FIRMWAREFILECHECK = 3845; // 0xF05 + FIRMWAREUPDATEDONE = 3846; // 0xF06 REQUEST_DEVICE_LIST = 1000; RESPONSE_DEVICE_LIST = 1001; } @@ -20,6 +22,14 @@ message FirmwareStart { required uint32 crc_fw = 5; } +message FirmwareFileCheck { + required string name = 1 [(nanopb).max_size = 32]; + required uint32 size = 2; + required uint32 device_id = 3; + required bool ready_for_data =4; + required uint32 crc_fw = 5; +} + message FirmwarePackage { required uint32 counter = 1; required uint32 crc_pac = 2; @@ -41,6 +51,12 @@ message FirmwareDone { } +message FirmwareUpdateDone { + required uint32 device_id = 3; +} + + + message RequestDeviceList { required uint32 msg =1; }