first draft FirmwareHandler
FirmwareHandler has no own Task. Only uses callbacks from messges. so it run in the UsbDataHandler Task.
This commit is contained in:
@@ -7,6 +7,7 @@ add_library(${PROJECT_NAME} STATIC "")
|
|||||||
target_sources(${PROJECT_NAME}
|
target_sources(${PROJECT_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${CMAKE_CURRENT_LIST_DIR}/UsbDataHandler.c
|
${CMAKE_CURRENT_LIST_DIR}/UsbDataHandler.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/FirmwareHandler.c
|
||||||
INTERFACE
|
INTERFACE
|
||||||
${CMAKE_CURRENT_LIST_DIR}/UsbDataHandler.h
|
${CMAKE_CURRENT_LIST_DIR}/UsbDataHandler.h
|
||||||
)
|
)
|
||||||
|
|||||||
132
Application/Tasks/FirmwareHandler.c
Normal file
132
Application/Tasks/FirmwareHandler.c
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
|
||||||
|
#include "fatfs.h"
|
||||||
|
#include "usbd_cdc_if.h"
|
||||||
|
#include "firmware.pb.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include <pb_encode.h>
|
||||||
|
#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
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,20 +1,24 @@
|
|||||||
#include "UsbDataHandler.h"
|
#include "UsbDataHandler.h"
|
||||||
#include "cmsis_os2.h"
|
#include "cmsis_os2.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
#include "firmware.pb.h"
|
#include "firmware.pb.h"
|
||||||
#include "usb_device.h"
|
#include "usb_device.h"
|
||||||
#include <pb_decode.h>
|
#include <pb_decode.h>
|
||||||
|
|
||||||
|
|
||||||
/* Declare the thread function */
|
/* Declare the thread function */
|
||||||
#define NUM_BUFFERS 4 // Define the number of buffers you want to use
|
#define NUM_BUFFERS 4 // Define the number of buffers you want to use
|
||||||
|
|
||||||
|
|
||||||
/* Define the task attributes */
|
/* Define the task attributes */
|
||||||
#define TASK_STACK_SIZE 1024
|
#define TASK_STACK_SIZE 2048
|
||||||
#define TASK_PRIORITY osPriorityNormal
|
#define TASK_PRIORITY osPriorityNormal
|
||||||
/* Declare static memory for the task */
|
/* Declare static memory for the task */
|
||||||
static uint32_t UsbDataHandler_TaskStack[TASK_STACK_SIZE];
|
static uint32_t UsbDataHandler_TaskStack[TASK_STACK_SIZE];
|
||||||
|
static uint8_t UsbDataHandler_TaskCB[sizeof(StaticTask_t)];
|
||||||
static const osThreadAttr_t UsbDataHandler_TaskAttr = {
|
static const osThreadAttr_t UsbDataHandler_TaskAttr = {
|
||||||
|
.attr_bits =0,
|
||||||
|
.cb_mem= UsbDataHandler_TaskCB,
|
||||||
|
.cb_size= sizeof(UsbDataHandler_TaskCB),
|
||||||
.name = "UsbDataHandler",
|
.name = "UsbDataHandler",
|
||||||
.stack_mem = UsbDataHandler_TaskStack,
|
.stack_mem = UsbDataHandler_TaskStack,
|
||||||
.stack_size = sizeof(UsbDataHandler_TaskStack),
|
.stack_size = sizeof(UsbDataHandler_TaskStack),
|
||||||
@@ -23,15 +27,13 @@ static const osThreadAttr_t UsbDataHandler_TaskAttr = {
|
|||||||
|
|
||||||
// Static queue data structures
|
// Static queue data structures
|
||||||
static osMessageQueueId_t usbDataHandlerQueue;
|
static osMessageQueueId_t usbDataHandlerQueue;
|
||||||
static uint8_t usbDataHandlerQueueControlBlock[32];
|
|
||||||
static uint8_t usbDataHandlerQueueStorageArea[NUM_BUFFERS * sizeof(uint32_t)];
|
|
||||||
static const osMessageQueueAttr_t usbDataHandlerQueueAttr = {
|
static const osMessageQueueAttr_t usbDataHandlerQueueAttr = {
|
||||||
.name = "UsbDataHandlerQueue",
|
.name = "UsbDataHandlerQueue",
|
||||||
.attr_bits = 0,
|
.attr_bits = 0,
|
||||||
.cb_mem = &usbDataHandlerQueueControlBlock,
|
.cb_mem = 0,
|
||||||
.cb_size = sizeof(usbDataHandlerQueueControlBlock),
|
.cb_size = 0,
|
||||||
.mq_mem = usbDataHandlerQueueStorageArea,
|
.mq_mem = 0,
|
||||||
.mq_size = sizeof(usbDataHandlerQueueStorageArea)};
|
.mq_size = 0};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -50,10 +52,10 @@ union {
|
|||||||
} mem_msg_decode;
|
} mem_msg_decode;
|
||||||
|
|
||||||
|
|
||||||
static Packet_u buffers[NUM_BUFFERS];
|
Packet_u buffers[NUM_BUFFERS];
|
||||||
static uint32_t bufferIndex = 0;
|
uint32_t USB_bufferIndex = 0;
|
||||||
static uint32_t dataIndex = 0;
|
uint32_t USB_dataIndex = 0;
|
||||||
static uint16_t packetLength = 0;
|
uint16_t USB_packetLength = 0;
|
||||||
|
|
||||||
|
|
||||||
void UsbDataHandler_Task(void *argument);
|
void UsbDataHandler_Task(void *argument);
|
||||||
@@ -72,7 +74,6 @@ void UsbDataHandler_Start() {
|
|||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
MX_USB_DEVICE_Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
#define MESSAGE_HANDLER(type, message) \
|
#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[] = {
|
message_handler_t message_handlers[] = {
|
||||||
@@ -101,6 +102,10 @@ message_handler_t message_handlers[] = {
|
|||||||
|
|
||||||
|
|
||||||
void UsbDataHandler_Task(void *argument) {
|
void UsbDataHandler_Task(void *argument) {
|
||||||
|
MX_USB_DEVICE_Init();
|
||||||
|
USB_bufferIndex = 0;
|
||||||
|
USB_dataIndex = 0;
|
||||||
|
USB_packetLength = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
UsbDataHandler_Runner();
|
UsbDataHandler_Runner();
|
||||||
}
|
}
|
||||||
@@ -136,37 +141,37 @@ void UsbDataHandler_Runner() {
|
|||||||
int UsbDataHandler_RxCallback(uint8_t *Buf, uint32_t Len) {
|
int UsbDataHandler_RxCallback(uint8_t *Buf, uint32_t Len) {
|
||||||
/* Copy the data into the current buffer */
|
/* Copy the data into the current buffer */
|
||||||
for (uint32_t i = 0; i < Len; i++) {
|
for (uint32_t i = 0; i < Len; i++) {
|
||||||
buffers[bufferIndex].bytes[dataIndex] = Buf[i];
|
buffers[USB_bufferIndex].bytes[USB_dataIndex] = Buf[i];
|
||||||
dataIndex++;
|
USB_dataIndex++;
|
||||||
|
|
||||||
/* Check if we have received the packet type and length */
|
/* Check if we have received the packet type and length */
|
||||||
if (dataIndex == sizeof(UsbDataPacketHead)) {
|
if (USB_dataIndex == sizeof(UsbDataPacketHead)) {
|
||||||
/* Extract the packet length */
|
/* Extract the packet length */
|
||||||
packetLength = buffers[bufferIndex].pack.head.length;
|
USB_packetLength = buffers[USB_bufferIndex].pack.head.length;
|
||||||
|
|
||||||
// the header checksum is invalid
|
// the header checksum is invalid
|
||||||
if (!UsbDataPacket_head_check(&buffers[bufferIndex].pack)) {
|
if (!UsbDataPacket_head_check(&buffers[USB_bufferIndex].pack)) {
|
||||||
dataIndex = 0;
|
USB_dataIndex = 0;
|
||||||
packetLength = 0;
|
USB_packetLength = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packetLength >= MAX_PACKET_SIZE) {
|
if (USB_packetLength >= MAX_PACKET_SIZE) {
|
||||||
dataIndex = 0;
|
USB_dataIndex = 0;
|
||||||
packetLength = 0;
|
USB_packetLength = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we have received a full packet */
|
/* 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 */
|
/* 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 */
|
/* Prepare for the next packet */
|
||||||
bufferIndex = (bufferIndex + 1) % NUM_BUFFERS;
|
USB_bufferIndex = (USB_bufferIndex + 1) % NUM_BUFFERS;
|
||||||
dataIndex = 0;
|
USB_dataIndex = 0;
|
||||||
packetLength = 0;
|
USB_packetLength = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 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_FirmwareStart(void *msg, uint32_t length) {}
|
||||||
__attribute__((weak)) void DataClbk_FirmwarePackage(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_FirmwarePackageAck(void *msg, uint32_t length) {}
|
||||||
__attribute__((weak)) void DataClbk_FirmwareDone(void *msg, uint32_t length) {}
|
//__attribute__((weak)) void DataClbk_FirmwareDone(void *msg, uint32_t length) {}
|
||||||
@@ -8,7 +8,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_PACKET_SIZE 512 - 4 // Define your maximum packet size
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct UsbDataPacketHead
|
* @struct UsbDataPacketHead
|
||||||
@@ -24,6 +23,8 @@ typedef struct {
|
|||||||
uint8_t check; // Check byte of the USB data packet.
|
uint8_t check; // Check byte of the USB data packet.
|
||||||
} __attribute__((packed)) UsbDataPacketHead;
|
} __attribute__((packed)) UsbDataPacketHead;
|
||||||
|
|
||||||
|
#define MAX_PACKET_SIZE 512 - sizeof(UsbDataPacketHead) // Define your maximum packet size
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct UsbDataPacket
|
* @struct UsbDataPacket
|
||||||
@@ -102,7 +103,7 @@ int UsbDataHandler_RxCallback(uint8_t* Buf, uint32_t Len);
|
|||||||
*
|
*
|
||||||
* @return void
|
* @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.
|
* @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
|
* @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.
|
* @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
|
* @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.
|
* @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
|
* @return void
|
||||||
*/
|
*/
|
||||||
__attribute__((weak)) void DataClbk_FirmwareDone(void* msg, uint32_t length);
|
void DataClbk_FirmwareDone(void* msg, uint32_t length);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user