rework of the UsbDataHandler

This commit is contained in:
2024-02-02 19:53:32 +01:00
parent 83830808a9
commit 766a3f021c
2 changed files with 251 additions and 99 deletions

View File

@@ -1,26 +1,24 @@
#include "UsbDataHandler.h"
#include "cmsis_os2.h"
#include "firmware.pb.h"
#include "usb_device.h"
#include <pb_decode.h>
#include "firmware.pb.h"
#include "UsbDataHandler.h"
/* Declare the thread function */
#define MAX_PACKET_SIZE 512-4 // Define your maximum packet size
#define NUM_BUFFERS 4 // Define the number of buffers you want to use
/* Define the task attributes */
#define TASK_STACK_SIZE 1024
#define TASK_PRIORITY osPriorityNormal
#define TASK_PRIORITY osPriorityNormal
/* Declare static memory for the task */
static uint32_t UsbDataHandler_TaskStack[TASK_STACK_SIZE];
static const osThreadAttr_t UsbDataHandler_TaskAttr = {
.name = "UsbDataHandler",
.stack_mem = UsbDataHandler_TaskStack,
.stack_size = sizeof(UsbDataHandler_TaskStack),
.priority = TASK_PRIORITY
};
.priority = TASK_PRIORITY};
// Static queue data structures
@@ -33,66 +31,67 @@ static const osMessageQueueAttr_t usbDataHandlerQueueAttr = {
.cb_mem = &usbDataHandlerQueueControlBlock,
.cb_size = sizeof(usbDataHandlerQueueControlBlock),
.mq_mem = usbDataHandlerQueueStorageArea,
.mq_size = sizeof(usbDataHandlerQueueStorageArea)
};
.mq_size = sizeof(usbDataHandlerQueueStorageArea)};
typedef struct {
uint16_t type;
uint16_t length;
uint8_t data[MAX_PACKET_SIZE];
} Packet;
typedef union {
Packet pack;
uint8_t bytes[sizeof(Packet)];
}Packet_u;
UsbDataPacket pack;
uint8_t bytes[sizeof(UsbDataPacket)];
} Packet_u;
// static memory only for decoding messages
union {
FirmwareStart msg_FirmwareStart;
FirmwarePackage msg_FirmwarePackage;
FirmwarePackageAck msg_FirmwarePackageAck;
FirmwareDone msg_FirmwareDone;
FirmwareStart msg_FirmwareStart;
FirmwarePackage msg_FirmwarePackage;
FirmwarePackageAck msg_FirmwarePackageAck;
FirmwareDone msg_FirmwareDone;
} mem_msg_decode;
Packet_u buffers[NUM_BUFFERS];
uint32_t bufferIndex = 0;
uint32_t dataIndex = 0;
uint16_t packetLength = 0;
static Packet_u buffers[NUM_BUFFERS];
static uint32_t bufferIndex = 0;
static uint32_t dataIndex = 0;
static uint16_t packetLength = 0;
void UsbDataHandler_Task(void *argument);
void UsbDataHandler_Start() {
/* Create the task */
osThreadId_t UsbDataHandler_TaskHandle = osThreadNew(UsbDataHandler_Task, NULL, &UsbDataHandler_TaskAttr);
/* Create the task */
osThreadId_t UsbDataHandler_TaskHandle = osThreadNew(UsbDataHandler_Task, NULL, &UsbDataHandler_TaskAttr);
/* Create the message queue */
usbDataHandlerQueue = osMessageQueueNew(NUM_BUFFERS, sizeof(uint32_t), &usbDataHandlerQueueAttr);
/* Create the message queue */
usbDataHandlerQueue = osMessageQueueNew(NUM_BUFFERS, sizeof(uint32_t), &usbDataHandlerQueueAttr);
/* Check if the task was created successfully */
if (UsbDataHandler_TaskHandle == NULL || usbDataHandlerQueue == NULL) {
/* Handle error */
Error_Handler();
}
MX_USB_DEVICE_Init();
/* Check if the task was created successfully */
if (UsbDataHandler_TaskHandle == NULL || usbDataHandlerQueue == NULL) {
/* Handle error */
Error_Handler();
}
MX_USB_DEVICE_Init();
}
typedef void (*callback_func_t)(void*, uint32_t length);
typedef void (*callback_func_t)(void *, uint32_t length);
typedef struct {
uint16_t type;
callback_func_t callback_func;
void *msg_ptr;
uint32_t msg_size;
const pb_msgdesc_t *fields;
uint16_t type;
callback_func_t callback_func;
void *msg_ptr;
uint32_t msg_size;
const pb_msgdesc_t *fields;
} message_handler_t;
#define MESSAGE_HANDLER(type, message) {type, DataClbk_##message, &mem_msg_decode.msg_##message,message##_size , message##_fields}
#define MESSAGE_HANDLER(type, message) \
{ type, DataClbk_##message, &mem_msg_decode.msg_##message, message##_size, message##_fields }
message_handler_t message_handlers[] = {
MESSAGE_HANDLER(0xF01, FirmwareStart),
MESSAGE_HANDLER(0xF02, FirmwarePackage),
@@ -100,62 +99,93 @@ message_handler_t message_handlers[] = {
MESSAGE_HANDLER(0xF04, FirmwarePackageAck),
};
void UsbDataHandler_Task(void *argument) {
uint32_t msg_buffer_index;
bool status;
while(1) {
/* Wait for a full packet */
osMessageQueueGet(usbDataHandlerQueue, &msg_buffer_index, NULL, osWaitForever);
pb_istream_t stream = pb_istream_from_buffer(buffers[msg_buffer_index].pack.data, buffers[msg_buffer_index].pack.length);
for (uint32_t i = 0; i < sizeof(message_handlers) / sizeof(message_handler_t); i++) {
if (buffers[msg_buffer_index].pack.type == message_handlers[i].type) {
status = pb_decode(&stream, message_handlers[i].fields, message_handlers[i].msg_ptr);
if (!status) {
// Handle decode error
}
message_handlers[i].callback_func(message_handlers[i].msg_ptr, message_handlers[i].msg_size);
break;
}
}
}
while (1) {
UsbDataHandler_Runner();
}
}
USBD_StatusTypeDef 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++;
void UsbDataHandler_Runner() {
uint32_t msg_buffer_index;
bool status;
/* Check if we have received the packet type and length */
if (dataIndex == 4) {
/* Extract the packet length */
packetLength = buffers[bufferIndex].pack.length;
/* Wait for a full packet */
osStatus_t msg_stat = osMessageQueueGet(usbDataHandlerQueue, &msg_buffer_index, NULL, osWaitForever);
if (msg_stat != osOK) {
return;
}
if (packetLength >= MAX_PACKET_SIZE ) {
dataIndex = 0;
packetLength = 0;
return USBD_FAIL;
}
}
/* Check if we have received a full packet */
if (dataIndex - 4 == packetLength) {
/* Notify the task that a full packet is received */
osMessageQueuePut(usbDataHandlerQueue, &bufferIndex, 0, 0);
pb_istream_t stream =
pb_istream_from_buffer(buffers[msg_buffer_index].pack.data, buffers[msg_buffer_index].pack.head.length);
/* Prepare for the next packet */
bufferIndex = (bufferIndex + 1) % NUM_BUFFERS;
dataIndex = 0;
packetLength = 0;
}
for (uint32_t i = 0; i < sizeof(message_handlers) / sizeof(message_handler_t); i++) {
if (buffers[msg_buffer_index].pack.head.type == message_handlers[i].type) {
status = pb_decode(&stream, message_handlers[i].fields, message_handlers[i].msg_ptr);
if (!status) {
// Handle decode error
}
message_handlers[i].callback_func(message_handlers[i].msg_ptr, message_handlers[i].msg_size);
return;
}
return USBD_OK;
}
}
__weak void DataClbk_FirmwareStart(void * msg, uint32_t length) {}
__weak void DataClbk_FirmwarePackage(void * msg, uint32_t length) {}
__weak void DataClbk_FirmwarePackageAck(void * msg, uint32_t length) {}
__weak void DataClbk_FirmwareDone(void * msg, uint32_t length) {}
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++;
/* Check if we have received the packet type and length */
if (dataIndex == sizeof(UsbDataPacketHead)) {
/* Extract the packet length */
packetLength = buffers[bufferIndex].pack.head.length;
// the header checksum is invalid
if (!UsbDataPacket_head_check(&buffers[bufferIndex].pack)) {
dataIndex = 0;
packetLength = 0;
return -1;
}
if (packetLength >= MAX_PACKET_SIZE) {
dataIndex = 0;
packetLength = 0;
return -1;
}
}
/* Check if we have received a full packet */
if (dataIndex - sizeof(UsbDataPacketHead) == packetLength) {
/* Notify the task that a full packet is received */
osMessageQueuePut(usbDataHandlerQueue, &bufferIndex, 0, 0);
/* Prepare for the next packet */
bufferIndex = (bufferIndex + 1) % NUM_BUFFERS;
dataIndex = 0;
packetLength = 0;
}
}
return 0;
}
uint8_t UsbDataPacket_head_sum(const UsbDataPacket *p) {
const uint8_t *type = (const uint8_t *)&p->head.type;
const uint8_t *length = (const uint8_t *)&p->head.length;
return type[0] + type[1] + length[0] + length[1];
}
bool UsbDataPacket_head_check(const UsbDataPacket *p) {
return p->head.check == UsbDataPacket_head_sum(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) {}