existing FW file check to avoid redundant transmit
+ refactro dupliacte code
This commit is contained in:
@@ -13,8 +13,8 @@ static FirmwareStart msg_FirmwareStart;
|
|||||||
static FirmwarePackage msg_FirmwarePackage;
|
static FirmwarePackage msg_FirmwarePackage;
|
||||||
static FirmwarePackageAck msg_FirmwarePackageAck;
|
static FirmwarePackageAck msg_FirmwarePackageAck;
|
||||||
static FirmwareDone msg_FirmwareDone;
|
static FirmwareDone msg_FirmwareDone;
|
||||||
|
static FirmwareFileCheck msg_FirmwareFileCheck;
|
||||||
static UsbDataPacket pack_FirmwarePackageAck;
|
static UsbDataPacket pack_FirmwarePackage;
|
||||||
|
|
||||||
|
|
||||||
static FIL FwFile = {0};
|
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.crc_pac = crc;
|
||||||
msg_FirmwarePackageAck.device_id =device;
|
msg_FirmwarePackageAck.device_id =device;
|
||||||
|
|
||||||
|
UsbDataPacketSendMessage(UsbPackageType_FIRMWAREPACKAGEACK, &pack_FirmwarePackage, FirmwarePackageAck_fields, &msg_FirmwarePackageAck);
|
||||||
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 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) {
|
void DataClbk_FirmwareStart(void *msg, uint32_t length) {
|
||||||
DATA_CLBK_SETUP(FirmwareStart);
|
DATA_CLBK_SETUP(FirmwareStart);
|
||||||
fwStartTime = osKernelGetSysTimerCount();
|
fwStartTime = osKernelGetSysTimerCount();
|
||||||
fwPackageCounter = 0;
|
fwPackageCounter = 0;
|
||||||
|
uint32_t crc = 0;
|
||||||
|
UINT totalRead = 0;
|
||||||
|
UINT bytesRead = 0;
|
||||||
|
|
||||||
if(FileOpen) {
|
if(FileOpen) {
|
||||||
f_close(&FwFile);
|
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);
|
fresult_open = f_open(&FwFile, msg_FirmwareStart.name, FA_CREATE_ALWAYS | FA_WRITE);
|
||||||
FileOpen=true;
|
FileOpen=true;
|
||||||
|
DataSend_FirmwareFileCheck(crc, msg_FirmwareStart.device_id, fresult_open==FR_OK, totalRead, msg_FirmwareStart.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "CLSAddress.h"
|
#include "CLSAddress.h"
|
||||||
#include "fatfs.h"
|
#include "fatfs.h"
|
||||||
#include "FirmwareUpdate.h"
|
#include "FirmwareUpdate.h"
|
||||||
|
#include "UsbDataHandler.h"
|
||||||
|
|
||||||
// Memory for the task
|
// Memory for the task
|
||||||
StaticTask_t CLS_FW_Task_cb;
|
StaticTask_t CLS_FW_Task_cb;
|
||||||
@@ -22,7 +23,6 @@ const osThreadAttr_t CLS_FW_Task_attr = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
osMutexId_t CLS_FW_Task_FileLock = NULL;
|
osMutexId_t CLS_FW_Task_FileLock = NULL;
|
||||||
static FirmwareUpdateArgs configuration = {0};
|
|
||||||
static FIL fw_file;
|
static FIL fw_file;
|
||||||
static FwFrame frame = {0};
|
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);
|
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
|
// 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);
|
// wait_for_start_callback // MessageCode::Firmware(FirmwareChannel::SlaveOutMasterIn);
|
||||||
CanData_regEventMsg(ready_canid, wait_for_start_callback);
|
CanData_regEventMsg(ready_canid, wait_for_start_callback);
|
||||||
|
|
||||||
// setup the command to send the slave into booloader mode
|
// 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};
|
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() {
|
void running(FirmwareUpdateArgs * configuration) {
|
||||||
uint16_t error_canid = GENERATE_CLS_ADDRESS(CLS_CODE_FIMWARE, configuration.device, CLS_CH_FW_MISO);
|
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 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);
|
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);
|
CLS_BSP_TxHeaderType header = CREATE_BSP_CAN_HEADER(target_canid,CLS_BSP_DLC_BYTES_8);
|
||||||
|
|
||||||
CanData_regEventMsg(error_canid,running_callback_error);
|
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);
|
void CLSFirmwareUpdateTask_func(void *argument);
|
||||||
|
|
||||||
@@ -139,31 +140,54 @@ void FirmwareUpdateTask_start(FirmwareUpdateArgs args) {
|
|||||||
CLS_FW_Task_FileLock = osMutexNew(NULL);
|
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) {
|
if(CLS_FW_Task_FileLock == NULL) {
|
||||||
// error cant create mutex
|
// error cant create mutex
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osMessageQueuePut(fwUpdateQueue, &args, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
// check CLS_FW_Task_id is null or stopped
|
// check CLS_FW_Task_id is null or stopped
|
||||||
// only one Task can runn at once
|
// only one Task can runn at once
|
||||||
if(CLS_FW_Task_id == NULL || osThreadGetState(CLS_FW_Task_id) == osThreadTerminated) {
|
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);
|
CLS_FW_Task_id = osThreadNew(CLSFirmwareUpdateTask_func, NULL, &CLS_FW_Task_attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UsbDataPacket buffer;
|
||||||
void CLSFirmwareUpdateTask_func(void *argument) {
|
void CLSFirmwareUpdateTask_func(void *argument) {
|
||||||
char * filename = configuration.name;
|
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) {
|
if(f_open(&fw_file, filename, FA_READ) != FR_OK) {
|
||||||
// TODO: Logging
|
// TODO: Logging
|
||||||
osThreadExit();
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_for_start();
|
wait_for_start(&args);
|
||||||
|
|
||||||
running();
|
running(&args);
|
||||||
|
FirmwareUpdateDone done = {
|
||||||
|
.device_id = args.device,
|
||||||
|
};
|
||||||
|
|
||||||
|
//UsbDataPacketSendMessage(UsbPackageType_FIRMWAREUPDATEDONE, &buffer,FirmwareUpdateDone_fields,&done);
|
||||||
f_close(&fw_file);
|
f_close(&fw_file);
|
||||||
osThreadExit();
|
}
|
||||||
}
|
}
|
||||||
@@ -195,22 +195,30 @@ bool UsbDataPacket_head_check(const UsbDataPacket *p) {
|
|||||||
|
|
||||||
#include "usbd_cdc_if.h"
|
#include "usbd_cdc_if.h"
|
||||||
#include <pb_encode.h>
|
#include <pb_encode.h>
|
||||||
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);
|
bool status = pb_encode(&ostream, fields ,msg);
|
||||||
packet.head.length = ostream.bytes_written;
|
buffer->head.length = ostream.bytes_written;
|
||||||
packet.head.type = typeid;
|
buffer->head.type = type;
|
||||||
packet.head.check = UsbDataPacket_head_sum(&packet);
|
buffer->head.check = UsbDataPacket_head_sum(buffer);
|
||||||
|
|
||||||
if(status) {
|
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);
|
osDelay(3);
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {}
|
//__attribute__((weak)) void DataClbk_FirmwareStart(void *msg, uint32_t length) {}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "stdbool.h"
|
#include "stdbool.h"
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
#include "pb_common.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -60,6 +60,9 @@ uint8_t UsbDataPacket_head_sum(const UsbDataPacket* p);
|
|||||||
*/
|
*/
|
||||||
bool UsbDataPacket_head_check(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.
|
* @brief This function starts the USB data handler.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ enum UsbPackageType {
|
|||||||
FIRMWAREPACKAGE = 3842; // 0xF02
|
FIRMWAREPACKAGE = 3842; // 0xF02
|
||||||
FIRMWAREDONE = 3843; // 0xF03
|
FIRMWAREDONE = 3843; // 0xF03
|
||||||
FIRMWAREPACKAGEACK = 3844; // 0xF04
|
FIRMWAREPACKAGEACK = 3844; // 0xF04
|
||||||
|
FIRMWAREFILECHECK = 3845; // 0xF05
|
||||||
|
FIRMWAREUPDATEDONE = 3846; // 0xF06
|
||||||
REQUEST_DEVICE_LIST = 1000;
|
REQUEST_DEVICE_LIST = 1000;
|
||||||
RESPONSE_DEVICE_LIST = 1001;
|
RESPONSE_DEVICE_LIST = 1001;
|
||||||
}
|
}
|
||||||
@@ -20,6 +22,14 @@ message FirmwareStart {
|
|||||||
required uint32 crc_fw = 5;
|
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 {
|
message FirmwarePackage {
|
||||||
required uint32 counter = 1;
|
required uint32 counter = 1;
|
||||||
required uint32 crc_pac = 2;
|
required uint32 crc_pac = 2;
|
||||||
@@ -41,6 +51,12 @@ message FirmwareDone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message FirmwareUpdateDone {
|
||||||
|
required uint32 device_id = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
message RequestDeviceList {
|
message RequestDeviceList {
|
||||||
required uint32 msg =1;
|
required uint32 msg =1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user