rework of the UsbDataHandler
This commit is contained in:
@@ -1,12 +1,11 @@
|
|||||||
|
#include "UsbDataHandler.h"
|
||||||
#include "cmsis_os2.h"
|
#include "cmsis_os2.h"
|
||||||
|
#include "firmware.pb.h"
|
||||||
#include "usb_device.h"
|
#include "usb_device.h"
|
||||||
#include <pb_decode.h>
|
#include <pb_decode.h>
|
||||||
#include "firmware.pb.h"
|
|
||||||
#include "UsbDataHandler.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Declare the thread function */
|
/* 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 NUM_BUFFERS 4 // Define the number of buffers you want to use
|
||||||
|
|
||||||
|
|
||||||
@@ -19,8 +18,7 @@ static const osThreadAttr_t UsbDataHandler_TaskAttr = {
|
|||||||
.name = "UsbDataHandler",
|
.name = "UsbDataHandler",
|
||||||
.stack_mem = UsbDataHandler_TaskStack,
|
.stack_mem = UsbDataHandler_TaskStack,
|
||||||
.stack_size = sizeof(UsbDataHandler_TaskStack),
|
.stack_size = sizeof(UsbDataHandler_TaskStack),
|
||||||
.priority = TASK_PRIORITY
|
.priority = TASK_PRIORITY};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Static queue data structures
|
// Static queue data structures
|
||||||
@@ -33,20 +31,14 @@ static const osMessageQueueAttr_t usbDataHandlerQueueAttr = {
|
|||||||
.cb_mem = &usbDataHandlerQueueControlBlock,
|
.cb_mem = &usbDataHandlerQueueControlBlock,
|
||||||
.cb_size = sizeof(usbDataHandlerQueueControlBlock),
|
.cb_size = sizeof(usbDataHandlerQueueControlBlock),
|
||||||
.mq_mem = usbDataHandlerQueueStorageArea,
|
.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 {
|
typedef union {
|
||||||
Packet pack;
|
UsbDataPacket pack;
|
||||||
uint8_t bytes[sizeof(Packet)];
|
uint8_t bytes[sizeof(UsbDataPacket)];
|
||||||
}Packet_u;
|
} Packet_u;
|
||||||
|
|
||||||
|
|
||||||
// static memory only for decoding messages
|
// static memory only for decoding messages
|
||||||
@@ -57,10 +49,12 @@ union {
|
|||||||
FirmwareDone msg_FirmwareDone;
|
FirmwareDone msg_FirmwareDone;
|
||||||
} mem_msg_decode;
|
} mem_msg_decode;
|
||||||
|
|
||||||
Packet_u buffers[NUM_BUFFERS];
|
|
||||||
uint32_t bufferIndex = 0;
|
static Packet_u buffers[NUM_BUFFERS];
|
||||||
uint32_t dataIndex = 0;
|
static uint32_t bufferIndex = 0;
|
||||||
uint16_t packetLength = 0;
|
static uint32_t dataIndex = 0;
|
||||||
|
static uint16_t packetLength = 0;
|
||||||
|
|
||||||
|
|
||||||
void UsbDataHandler_Task(void *argument);
|
void UsbDataHandler_Task(void *argument);
|
||||||
|
|
||||||
@@ -79,10 +73,11 @@ void UsbDataHandler_Start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MX_USB_DEVICE_Init();
|
MX_USB_DEVICE_Init();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*callback_func_t)(void*, uint32_t length);
|
|
||||||
|
typedef void (*callback_func_t)(void *, uint32_t length);
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
@@ -92,7 +87,11 @@ typedef struct {
|
|||||||
const pb_msgdesc_t *fields;
|
const pb_msgdesc_t *fields;
|
||||||
} message_handler_t;
|
} 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_t message_handlers[] = {
|
||||||
MESSAGE_HANDLER(0xF01, FirmwareStart),
|
MESSAGE_HANDLER(0xF01, FirmwareStart),
|
||||||
MESSAGE_HANDLER(0xF02, FirmwarePackage),
|
MESSAGE_HANDLER(0xF02, FirmwarePackage),
|
||||||
@@ -100,49 +99,67 @@ message_handler_t message_handlers[] = {
|
|||||||
MESSAGE_HANDLER(0xF04, FirmwarePackageAck),
|
MESSAGE_HANDLER(0xF04, FirmwarePackageAck),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void UsbDataHandler_Task(void *argument) {
|
void UsbDataHandler_Task(void *argument) {
|
||||||
|
while (1) {
|
||||||
|
UsbDataHandler_Runner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UsbDataHandler_Runner() {
|
||||||
uint32_t msg_buffer_index;
|
uint32_t msg_buffer_index;
|
||||||
bool status;
|
bool status;
|
||||||
|
|
||||||
while(1) {
|
|
||||||
/* Wait for a full packet */
|
/* Wait for a full packet */
|
||||||
osMessageQueueGet(usbDataHandlerQueue, &msg_buffer_index, NULL, osWaitForever);
|
osStatus_t msg_stat = 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);
|
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);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sizeof(message_handlers) / sizeof(message_handler_t); i++) {
|
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) {
|
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);
|
status = pb_decode(&stream, message_handlers[i].fields, message_handlers[i].msg_ptr);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
// Handle decode error
|
// Handle decode error
|
||||||
}
|
}
|
||||||
message_handlers[i].callback_func(message_handlers[i].msg_ptr, message_handlers[i].msg_size);
|
message_handlers[i].callback_func(message_handlers[i].msg_ptr, message_handlers[i].msg_size);
|
||||||
break;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
USBD_StatusTypeDef 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[bufferIndex].bytes[dataIndex] = Buf[i];
|
||||||
dataIndex++;
|
dataIndex++;
|
||||||
|
|
||||||
/* Check if we have received the packet type and length */
|
/* Check if we have received the packet type and length */
|
||||||
if (dataIndex == 4) {
|
if (dataIndex == sizeof(UsbDataPacketHead)) {
|
||||||
/* Extract the packet length */
|
/* Extract the packet length */
|
||||||
packetLength = buffers[bufferIndex].pack.length;
|
packetLength = buffers[bufferIndex].pack.head.length;
|
||||||
|
|
||||||
if (packetLength >= MAX_PACKET_SIZE ) {
|
// the header checksum is invalid
|
||||||
|
if (!UsbDataPacket_head_check(&buffers[bufferIndex].pack)) {
|
||||||
dataIndex = 0;
|
dataIndex = 0;
|
||||||
packetLength = 0;
|
packetLength = 0;
|
||||||
return USBD_FAIL;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packetLength >= MAX_PACKET_SIZE) {
|
||||||
|
dataIndex = 0;
|
||||||
|
packetLength = 0;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we have received a full packet */
|
/* Check if we have received a full packet */
|
||||||
if (dataIndex - 4 == packetLength) {
|
if (dataIndex - sizeof(UsbDataPacketHead) == 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, &bufferIndex, 0, 0);
|
||||||
|
|
||||||
@@ -152,10 +169,23 @@ USBD_StatusTypeDef UsbDataHandler_RxCallback(uint8_t* Buf, uint32_t Len) {
|
|||||||
packetLength = 0;
|
packetLength = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return USBD_OK;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__weak void DataClbk_FirmwareStart(void * msg, uint32_t length) {}
|
|
||||||
__weak void DataClbk_FirmwarePackage(void * msg, uint32_t length) {}
|
uint8_t UsbDataPacket_head_sum(const UsbDataPacket *p) {
|
||||||
__weak void DataClbk_FirmwarePackageAck(void * msg, uint32_t length) {}
|
const uint8_t *type = (const uint8_t *)&p->head.type;
|
||||||
__weak void DataClbk_FirmwareDone(void * msg, uint32_t length) {}
|
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) {}
|
||||||
@@ -1,22 +1,144 @@
|
|||||||
#ifndef USBDATAHANDLER_H
|
#ifndef USBDATAHANDLER_H
|
||||||
#define USBDATAHANDLER_H
|
#define USBDATAHANDLER_H
|
||||||
|
|
||||||
#include "usbd_cdc_if.h"
|
#include "stdbool.h"
|
||||||
#include "firmware.pb.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MAX_PACKET_SIZE 512 - 4 // Define your maximum packet size
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct UsbDataPacketHead
|
||||||
|
* @brief This structure represents the header of a USB data packet.
|
||||||
|
*
|
||||||
|
* The header includes the length and type of the packet, as well as a check byte.
|
||||||
|
* The structure is packed to ensure that the memory layout is exactly as defined,
|
||||||
|
* without any padding bytes.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint16_t length; // Length of the USB data packet
|
||||||
|
uint16_t type; // Type of the USB data packet(used to parse the message content).
|
||||||
|
uint8_t check; // Check byte of the USB data packet.
|
||||||
|
} __attribute__((packed)) UsbDataPacketHead;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct UsbDataPacket
|
||||||
|
* @brief This structure represents a USB data packet.
|
||||||
|
*
|
||||||
|
* The packet includes a header and a data array. The structure is packed to ensure
|
||||||
|
* that the memory layout is exactly as defined, without any padding bytes.
|
||||||
|
*
|
||||||
|
* @var UsbDataPacket::head
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @var UsbDataPacket::data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
UsbDataPacketHead head; // Header of the USB data packet.
|
||||||
|
uint8_t data[MAX_PACKET_SIZE]; // Data of the USB data packet.
|
||||||
|
} __attribute__((packed)) UsbDataPacket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculate the chekcsum of the header of a USB data packet.
|
||||||
|
*
|
||||||
|
* @param p Pointer to the USB data packet.
|
||||||
|
* @return Sum of the header of the USB data packet.
|
||||||
|
*/
|
||||||
|
uint8_t UsbDataPacket_head_sum(const UsbDataPacket* p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check the header of a USB data packet.
|
||||||
|
*
|
||||||
|
* @param p Pointer to the USB data packet.
|
||||||
|
* @return True if the header is valid, false otherwise.
|
||||||
|
*/
|
||||||
|
bool UsbDataPacket_head_check(const UsbDataPacket* p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function starts the USB data handler.
|
||||||
|
*
|
||||||
|
* It initializes any necessary hardware or software resources
|
||||||
|
* and prepares the data handler to process USB data.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
void UsbDataHandler_Start();
|
void UsbDataHandler_Start();
|
||||||
|
|
||||||
USBD_StatusTypeDef UsbDataHandler_RxCallback(uint8_t* Buf, uint32_t Len);
|
/**
|
||||||
|
* @brief This function runs the USB data handler.
|
||||||
|
*
|
||||||
|
* It processes any pending USB data and performs any necessary
|
||||||
|
* tasks related to USB data handling. It should be called
|
||||||
|
* periodically in the main loop of your program.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void UsbDataHandler_Runner();
|
||||||
|
|
||||||
void DataClbk_FirmwareStart(void * msg, uint32_t length);
|
/**
|
||||||
void DataClbk_FirmwarePackage(void * msg, uint32_t length);
|
* @brief This function is a callback that is invoked when USB data is received.
|
||||||
void DataClbk_FirmwarePackageAck(void * msg, uint32_t length);
|
*
|
||||||
void DataClbk_FirmwareDone(void * msg, uint32_t length);
|
* It processes the received data and performs any necessary tasks.
|
||||||
|
*
|
||||||
|
* @param Buf A pointer to the buffer that contains the received data.
|
||||||
|
* @param Len The length of the received data, in bytes.
|
||||||
|
*
|
||||||
|
* @return int Returns 0 on success, or a non-zero error code on failure.
|
||||||
|
*/
|
||||||
|
int UsbDataHandler_RxCallback(uint8_t* Buf, uint32_t Len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function that is invoked when firmware update message is received.
|
||||||
|
*
|
||||||
|
* Other parts of the software can implement this function to handle the start of a firmware update.
|
||||||
|
*
|
||||||
|
* @param msg A pointer to the message related to the firmware start.
|
||||||
|
* @param length The length of the message, in bytes.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
__attribute__((weak)) void DataClbk_FirmwareStart(void* msg, uint32_t length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function that is invoked when a firmware package message is received.
|
||||||
|
*
|
||||||
|
* Other parts of the software can implement this function to handle each received firmware package.
|
||||||
|
*
|
||||||
|
* @param msg A pointer to the message related to the received firmware package.
|
||||||
|
* @param length The length of the message, in bytes.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
__attribute__((weak)) void DataClbk_FirmwarePackage(void* msg, uint32_t length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function that is invoked when a firmware package acknowledgment message is received.
|
||||||
|
*
|
||||||
|
* Other parts of the software can implement this function to handle the acknowledgment of a received firmware package.
|
||||||
|
*
|
||||||
|
* @param msg A pointer to the message related to the firmware package acknowledgment.
|
||||||
|
* @param length The length of the message, in bytes.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
__attribute__((weak)) void DataClbk_FirmwarePackageAck(void* msg, uint32_t length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function that is invoked when firmware update done message.
|
||||||
|
*
|
||||||
|
* Other parts of the software can implement this function to handle the completion of a firmware update.
|
||||||
|
*
|
||||||
|
* @param msg A pointer to the message related to the completion of the firmware update.
|
||||||
|
* @param length The length of the message, in bytes.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
__attribute__((weak)) void DataClbk_FirmwareDone(void* msg, uint32_t length);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user