From 67a0ffcdbd0d63d059c0e5c7a8ce5fd03f62e04a Mon Sep 17 00:00:00 2001 From: Oliver Walter Date: Sat, 3 Feb 2024 02:58:58 +0100 Subject: [PATCH] first draft FirmwareHandler FirmwareHandler has no own Task. Only uses callbacks from messges. so it run in the UsbDataHandler Task. --- Application/Tasks/CMakeLists.txt | 1 + Application/Tasks/FirmwareHandler.c | 132 ++++++++++++++++++++++++++++ Application/Tasks/UsbDataHandler.c | 73 ++++++++------- Application/Tasks/UsbDataHandler.h | 11 +-- 4 files changed, 178 insertions(+), 39 deletions(-) create mode 100644 Application/Tasks/FirmwareHandler.c diff --git a/Application/Tasks/CMakeLists.txt b/Application/Tasks/CMakeLists.txt index 19665f2..d1d2947 100644 --- a/Application/Tasks/CMakeLists.txt +++ b/Application/Tasks/CMakeLists.txt @@ -7,6 +7,7 @@ add_library(${PROJECT_NAME} STATIC "") target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/UsbDataHandler.c + ${CMAKE_CURRENT_LIST_DIR}/FirmwareHandler.c INTERFACE ${CMAKE_CURRENT_LIST_DIR}/UsbDataHandler.h ) diff --git a/Application/Tasks/FirmwareHandler.c b/Application/Tasks/FirmwareHandler.c new file mode 100644 index 0000000..4b9697d --- /dev/null +++ b/Application/Tasks/FirmwareHandler.c @@ -0,0 +1,132 @@ + +#include "fatfs.h" +#include "usbd_cdc_if.h" +#include "firmware.pb.h" +#include "cmsis_os2.h" +#include +#include "UsbDataHandler.h" +#include "crc.h" + +// static memory only for decoding messages +static FirmwareStart msg_FirmwareStart; +static FirmwarePackage msg_FirmwarePackage; +static FirmwarePackageAck msg_FirmwarePackageAck; +static FirmwareDone msg_FirmwareDone; + +static UsbDataPacket pack_FirmwarePackageAck; + + +static FIL FwFile = {0}; +static bool FileOpen = false; +static FRESULT fresult_open =0; +static uint32_t fwStartTime = 0; +static uint32_t fwPackageCounter =0; + +#define ASSERT_SIZE(x) \ + { \ + if (!(x)) \ + Error_Handler(); \ + } + +#define DATA_CLBK_SETUP(name) \ + { \ + ASSERT_SIZE(length == sizeof(name)); \ + memcpy(&msg_##name, msg, sizeof(name)); \ + } + + +/** + * @brief This function builds and sends a FirmwarePackageAck message over USB. + * + * @param ack A boolean flag indicating the acknowledgment status. + * @param crc A 32-bit cyclic redundancy check (CRC) for the firmware package. + * @param counter A 32-bit counter for the firmware packages. + * @param device A 32-bit identifier for the device. + */ +void DataSend_FirmwarePackgeAck(bool ack, uint32_t crc, uint32_t counter, uint32_t device) { + msg_FirmwarePackageAck.ack = ack; + msg_FirmwarePackageAck.counter= counter; + 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(); + } + +} + +void DataClbk_FirmwareStart(void *msg, uint32_t length) { + DATA_CLBK_SETUP(FirmwareStart); + fwStartTime = osKernelGetSysTimerCount(); + fwPackageCounter = 0; + + if(FileOpen) { + f_close(&FwFile); + } + + fresult_open = f_open(&FwFile, msg_FirmwareStart.name, FA_CREATE_ALWAYS | FA_WRITE); + FileOpen=true; + +} + +// 0x58900205 python +// 0x2ACB825B stm32 + + +void DataClbk_FirmwarePackage(void *msg, uint32_t length) { + DATA_CLBK_SETUP(FirmwarePackage); + + // check CRC and Package counter + uint32_t crc_check = HAL_CRC_Calculate(&hcrc,msg_FirmwarePackage.data.bytes, msg_FirmwarePackage.data.size); + if(msg_FirmwarePackage.crc_pac != crc_check ) { + DataSend_FirmwarePackgeAck(false, msg_FirmwarePackage.crc_pac, msg_FirmwarePackage.counter, msg_FirmwarePackage.device_id); + return; + } + + if(msg_FirmwarePackage.counter != fwPackageCounter) { + DataSend_FirmwarePackgeAck(false, msg_FirmwarePackage.crc_pac, msg_FirmwarePackage.counter, msg_FirmwarePackage.device_id); + return; + } + + if(fresult_open != 0) { + DataSend_FirmwarePackgeAck(false, 0, 0, msg_FirmwarePackage.device_id); + return; + } + + unsigned int bytes_written =0; + f_write(&FwFile,msg_FirmwarePackage.data.bytes, msg_FirmwarePackage.data.size, &bytes_written); + fwPackageCounter++; + DataSend_FirmwarePackgeAck(true, msg_FirmwarePackage.crc_pac, msg_FirmwarePackage.counter, msg_FirmwarePackage.device_id); +} + +void DataClbk_FirmwarePackageAck(void *msg, uint32_t length) { + DATA_CLBK_SETUP(FirmwarePackageAck); + // Does notthing for the Master +} + +void DataClbk_FirmwareDone(void *msg, uint32_t length) { + DATA_CLBK_SETUP(FirmwareDone); + + // check CRC and Package counter + + f_close(&FwFile); + fresult_open = 0xFF; + FileOpen=false; + + + // Spawn Task to Send this File over CAN + +} \ No newline at end of file diff --git a/Application/Tasks/UsbDataHandler.c b/Application/Tasks/UsbDataHandler.c index 571b775..cb6bf93 100644 --- a/Application/Tasks/UsbDataHandler.c +++ b/Application/Tasks/UsbDataHandler.c @@ -1,20 +1,24 @@ #include "UsbDataHandler.h" #include "cmsis_os2.h" +#include "FreeRTOS.h" #include "firmware.pb.h" #include "usb_device.h" #include - /* Declare the thread function */ #define NUM_BUFFERS 4 // Define the number of buffers you want to use /* Define the task attributes */ -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 2048 #define TASK_PRIORITY osPriorityNormal /* Declare static memory for the task */ static uint32_t UsbDataHandler_TaskStack[TASK_STACK_SIZE]; +static uint8_t UsbDataHandler_TaskCB[sizeof(StaticTask_t)]; static const osThreadAttr_t UsbDataHandler_TaskAttr = { + .attr_bits =0, + .cb_mem= UsbDataHandler_TaskCB, + .cb_size= sizeof(UsbDataHandler_TaskCB), .name = "UsbDataHandler", .stack_mem = UsbDataHandler_TaskStack, .stack_size = sizeof(UsbDataHandler_TaskStack), @@ -23,15 +27,13 @@ static const osThreadAttr_t UsbDataHandler_TaskAttr = { // Static queue data structures static osMessageQueueId_t usbDataHandlerQueue; -static uint8_t usbDataHandlerQueueControlBlock[32]; -static uint8_t usbDataHandlerQueueStorageArea[NUM_BUFFERS * sizeof(uint32_t)]; static const osMessageQueueAttr_t usbDataHandlerQueueAttr = { .name = "UsbDataHandlerQueue", .attr_bits = 0, - .cb_mem = &usbDataHandlerQueueControlBlock, - .cb_size = sizeof(usbDataHandlerQueueControlBlock), - .mq_mem = usbDataHandlerQueueStorageArea, - .mq_size = sizeof(usbDataHandlerQueueStorageArea)}; + .cb_mem = 0, + .cb_size = 0, + .mq_mem = 0, + .mq_size = 0}; @@ -50,10 +52,10 @@ union { } mem_msg_decode; -static Packet_u buffers[NUM_BUFFERS]; -static uint32_t bufferIndex = 0; -static uint32_t dataIndex = 0; -static uint16_t packetLength = 0; +Packet_u buffers[NUM_BUFFERS]; +uint32_t USB_bufferIndex = 0; +uint32_t USB_dataIndex = 0; +uint16_t USB_packetLength = 0; void UsbDataHandler_Task(void *argument); @@ -72,7 +74,6 @@ void UsbDataHandler_Start() { Error_Handler(); } - MX_USB_DEVICE_Init(); } @@ -89,7 +90,7 @@ typedef struct { #define MESSAGE_HANDLER(type, message) \ - { type, DataClbk_##message, &mem_msg_decode.msg_##message, message##_size, message##_fields } + { type, DataClbk_##message, &mem_msg_decode.msg_##message, sizeof( message ), message##_fields } message_handler_t message_handlers[] = { @@ -101,6 +102,10 @@ message_handler_t message_handlers[] = { void UsbDataHandler_Task(void *argument) { + MX_USB_DEVICE_Init(); + USB_bufferIndex = 0; + USB_dataIndex = 0; + USB_packetLength = 0; while (1) { UsbDataHandler_Runner(); } @@ -115,7 +120,7 @@ void UsbDataHandler_Runner() { osStatus_t msg_stat = osMessageQueueGet(usbDataHandlerQueue, &msg_buffer_index, NULL, osWaitForever); if (msg_stat != osOK) { return; - } + } pb_istream_t stream = pb_istream_from_buffer(buffers[msg_buffer_index].pack.data, buffers[msg_buffer_index].pack.head.length); @@ -136,37 +141,37 @@ void UsbDataHandler_Runner() { int UsbDataHandler_RxCallback(uint8_t *Buf, uint32_t Len) { /* Copy the data into the current buffer */ for (uint32_t i = 0; i < Len; i++) { - buffers[bufferIndex].bytes[dataIndex] = Buf[i]; - dataIndex++; + buffers[USB_bufferIndex].bytes[USB_dataIndex] = Buf[i]; + USB_dataIndex++; /* Check if we have received the packet type and length */ - if (dataIndex == sizeof(UsbDataPacketHead)) { + if (USB_dataIndex == sizeof(UsbDataPacketHead)) { /* Extract the packet length */ - packetLength = buffers[bufferIndex].pack.head.length; + USB_packetLength = buffers[USB_bufferIndex].pack.head.length; // the header checksum is invalid - if (!UsbDataPacket_head_check(&buffers[bufferIndex].pack)) { - dataIndex = 0; - packetLength = 0; + if (!UsbDataPacket_head_check(&buffers[USB_bufferIndex].pack)) { + USB_dataIndex = 0; + USB_packetLength = 0; return -1; } - if (packetLength >= MAX_PACKET_SIZE) { - dataIndex = 0; - packetLength = 0; + if (USB_packetLength >= MAX_PACKET_SIZE) { + USB_dataIndex = 0; + USB_packetLength = 0; return -1; } } /* Check if we have received a full packet */ - if (dataIndex - sizeof(UsbDataPacketHead) == packetLength) { + if (USB_dataIndex - sizeof(UsbDataPacketHead) == USB_packetLength) { /* Notify the task that a full packet is received */ - osMessageQueuePut(usbDataHandlerQueue, &bufferIndex, 0, 0); + osMessageQueuePut(usbDataHandlerQueue, &USB_bufferIndex, 0, 0); /* Prepare for the next packet */ - bufferIndex = (bufferIndex + 1) % NUM_BUFFERS; - dataIndex = 0; - packetLength = 0; + USB_bufferIndex = (USB_bufferIndex + 1) % NUM_BUFFERS; + USB_dataIndex = 0; + USB_packetLength = 0; } } return 0; @@ -185,7 +190,7 @@ bool UsbDataPacket_head_check(const UsbDataPacket *p) { } -__attribute__((weak)) void DataClbk_FirmwareStart(void *msg, uint32_t length) {} -__attribute__((weak)) void DataClbk_FirmwarePackage(void *msg, uint32_t length) {} -__attribute__((weak)) void DataClbk_FirmwarePackageAck(void *msg, uint32_t length) {} -__attribute__((weak)) void DataClbk_FirmwareDone(void *msg, uint32_t length) {} \ No newline at end of file +//__attribute__((weak)) void DataClbk_FirmwareStart(void *msg, uint32_t length) {} +//__attribute__((weak)) void DataClbk_FirmwarePackage(void *msg, uint32_t length) {} +//__attribute__((weak)) void DataClbk_FirmwarePackageAck(void *msg, uint32_t length) {} +//__attribute__((weak)) void DataClbk_FirmwareDone(void *msg, uint32_t length) {} \ No newline at end of file diff --git a/Application/Tasks/UsbDataHandler.h b/Application/Tasks/UsbDataHandler.h index 87296cc..bff3239 100644 --- a/Application/Tasks/UsbDataHandler.h +++ b/Application/Tasks/UsbDataHandler.h @@ -8,7 +8,6 @@ extern "C" { #endif -#define MAX_PACKET_SIZE 512 - 4 // Define your maximum packet size /** * @struct UsbDataPacketHead @@ -24,6 +23,8 @@ typedef struct { uint8_t check; // Check byte of the USB data packet. } __attribute__((packed)) UsbDataPacketHead; +#define MAX_PACKET_SIZE 512 - sizeof(UsbDataPacketHead) // Define your maximum packet size + /** * @struct UsbDataPacket @@ -102,7 +103,7 @@ int UsbDataHandler_RxCallback(uint8_t* Buf, uint32_t Len); * * @return void */ -__attribute__((weak)) void DataClbk_FirmwareStart(void* msg, uint32_t length); + void DataClbk_FirmwareStart(void* msg, uint32_t length); /** * @brief Callback function that is invoked when a firmware package message is received. @@ -114,7 +115,7 @@ __attribute__((weak)) void DataClbk_FirmwareStart(void* msg, uint32_t length); * * @return void */ -__attribute__((weak)) void DataClbk_FirmwarePackage(void* msg, uint32_t length); + void DataClbk_FirmwarePackage(void* msg, uint32_t length); /** * @brief Callback function that is invoked when a firmware package acknowledgment message is received. @@ -126,7 +127,7 @@ __attribute__((weak)) void DataClbk_FirmwarePackage(void* msg, uint32_t length); * * @return void */ -__attribute__((weak)) void DataClbk_FirmwarePackageAck(void* msg, uint32_t length); +void DataClbk_FirmwarePackageAck(void* msg, uint32_t length); /** * @brief Callback function that is invoked when firmware update done message. @@ -138,7 +139,7 @@ __attribute__((weak)) void DataClbk_FirmwarePackageAck(void* msg, uint32_t lengt * * @return void */ -__attribute__((weak)) void DataClbk_FirmwareDone(void* msg, uint32_t length); +void DataClbk_FirmwareDone(void* msg, uint32_t length); #ifdef __cplusplus }