implement full fwupdate stack
This commit is contained in:
@@ -9,10 +9,12 @@ target_sources(${PROJECT_NAME}
|
||||
${CMAKE_CURRENT_LIST_DIR}/UsbDataHandler.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/CanDataTask.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/FirmwareHandler.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/FirmwareUpdate.c
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/UsbDataHandler.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/CanDataTask.h
|
||||
|
||||
${CMAKE_CURRENT_LIST_DIR}/FirmwareUpdate.h
|
||||
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <pb_encode.h>
|
||||
#include "UsbDataHandler.h"
|
||||
#include "crc.h"
|
||||
#include "FirmwareUpdate.h"
|
||||
|
||||
// static memory only for decoding messages
|
||||
static FirmwareStart msg_FirmwareStart;
|
||||
@@ -123,14 +124,10 @@ void DataClbk_FirmwareDone(void *msg, uint32_t length) {
|
||||
fresult_open = 0xFF;
|
||||
FileOpen=false;
|
||||
|
||||
FirmwareUpdateArgs args;
|
||||
args.device = msg_FirmwareDone.device_id;
|
||||
memcpy(args.name, msg_FirmwareStart.name, sizeof(args.name));
|
||||
|
||||
// Spawn Task to Send this File over CAN
|
||||
// this task should
|
||||
// 1. send can message to send device with matching device id into bootloader mode
|
||||
// - open the fw file on the SD card.
|
||||
// 2. wait for the device to get ready.
|
||||
// - send data 4x data
|
||||
// - wait for ack
|
||||
// 3 onec we are at the EOF
|
||||
// - send done
|
||||
FirmwareUpdateTask_start(args);
|
||||
|
||||
}
|
||||
169
Application/Tasks/FirmwareUpdate.c
Normal file
169
Application/Tasks/FirmwareUpdate.c
Normal file
@@ -0,0 +1,169 @@
|
||||
#include "CanDataHandler.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "CLSAddress.h"
|
||||
#include "fatfs.h"
|
||||
#include "FirmwareUpdate.h"
|
||||
|
||||
// Memory for the task
|
||||
StaticTask_t CLS_FW_Task_cb;
|
||||
uint32_t CLS_FW_Task_stk[512];
|
||||
// Attributes for the task
|
||||
osThreadId_t CLS_FW_Task_id;
|
||||
const osThreadAttr_t CLS_FW_Task_attr = {
|
||||
.name = "CLS_FW_Task",
|
||||
.attr_bits = 0U,
|
||||
.cb_mem = &CLS_FW_Task_cb,
|
||||
.cb_size = sizeof(CLS_FW_Task_cb),
|
||||
.stack_mem = CLS_FW_Task_stk,
|
||||
.stack_size = sizeof(CLS_FW_Task_stk),
|
||||
.priority = osPriorityNormal,
|
||||
.reserved = 0U
|
||||
};
|
||||
|
||||
osMutexId_t CLS_FW_Task_FileLock = NULL;
|
||||
static FirmwareUpdateArgs configuration = {0};
|
||||
static FIL fw_file;
|
||||
static FwFrame frame = {0};
|
||||
|
||||
|
||||
|
||||
// wait_for_start_callback to get notified when the slave is ready
|
||||
void wait_for_start_callback(uint16_t canid, uint8_t * data, uint8_t size) {
|
||||
osThreadFlagsSet(CLS_FW_Task_id, TASK_FLAG_WAIT);
|
||||
}
|
||||
|
||||
void wait_for_start() {
|
||||
|
||||
// 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);
|
||||
// wait_for_start_callback // MessageCode::Firmware(FirmwareChannel::SlaveOutMasterIn);
|
||||
CanData_regEventMsg(ready_canid, wait_for_start_callback);
|
||||
|
||||
// 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);
|
||||
uint8_t bootloader_call[8] = {0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab};
|
||||
|
||||
|
||||
// wait for the slave to be ready to update:
|
||||
uint32_t counter = 0;
|
||||
do {
|
||||
// send bootloader command
|
||||
CLS_BSP_TxHeaderType header = CREATE_BSP_CAN_HEADER(target_canid,CLS_BSP_DLC_BYTES_8);
|
||||
CLS_BSP_CAN_AddMessageToSend(&header,bootloader_call);
|
||||
counter++;
|
||||
|
||||
// after some time abort if we dont get a connection
|
||||
if(counter > BOOTLOADER_CALL_MAX_TRIES) {
|
||||
// TODO: Logging
|
||||
CanData_removeEvent(ready_canid);
|
||||
f_close(&fw_file);
|
||||
osThreadExit();
|
||||
}
|
||||
|
||||
// wait for the slave
|
||||
} while(osThreadFlagsWait(TASK_FLAG_WAIT,osFlagsWaitAny,BOOTLOADER_CALL_RETRY_TIME) == (uint32_t)osErrorTimeout);
|
||||
|
||||
//remove the wait_for_start_callback again
|
||||
CanData_removeEvent(ready_canid);
|
||||
|
||||
// reset the fw_file
|
||||
f_lseek(&fw_file,0);
|
||||
frame.counter = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void running_callback_error(uint16_t canid, uint8_t * data, uint8_t size) {
|
||||
osMutexAcquire(CLS_FW_Task_FileLock, osWaitForever);
|
||||
f_lseek(&fw_file,0);
|
||||
frame.counter = 0;
|
||||
osMutexRelease(CLS_FW_Task_FileLock);
|
||||
osThreadFlagsSet(CLS_FW_Task_id, TASK_FLAG_RUNNING);
|
||||
}
|
||||
|
||||
void running_callback_ack(uint16_t canid, uint8_t * data, uint8_t size) {
|
||||
osThreadFlagsSet(CLS_FW_Task_id, TASK_FLAG_RUNNING);
|
||||
}
|
||||
|
||||
|
||||
void running() {
|
||||
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 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);
|
||||
|
||||
CanData_regEventMsg(error_canid,running_callback_error);
|
||||
CanData_regEventMsg(ack_canid, running_callback_ack);
|
||||
|
||||
unsigned int read_bytes = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
// read fw file and and send data
|
||||
osMutexAcquire(CLS_FW_Task_FileLock, osWaitForever);
|
||||
f_read(&fw_file, &frame.data, sizeof(frame.data), &read_bytes);
|
||||
CLS_BSP_CAN_AddMessageToSend(&header, (uint8_t*)&frame);
|
||||
frame.counter++;
|
||||
osMutexRelease(CLS_FW_Task_FileLock);
|
||||
|
||||
// transport window response
|
||||
if(frame.counter % UPDATE_ACK_WINDOW == 0) {
|
||||
osThreadFlagsWait(TASK_FLAG_RUNNING, osFlagsWaitAny, osWaitForever);
|
||||
}
|
||||
|
||||
// end of file
|
||||
if(read_bytes != sizeof(frame.data)) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint64_t done = UPDATE_DONE_MSG;
|
||||
CLS_BSP_CAN_AddMessageToSend(&header,(uint8_t*)&done);
|
||||
|
||||
CanData_removeEvent(error_canid);
|
||||
CanData_removeEvent(ack_canid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CLSFirmwareUpdateTask_func(void *argument);
|
||||
|
||||
void FirmwareUpdateTask_start(FirmwareUpdateArgs args) {
|
||||
// Task functionality here
|
||||
if(CLS_FW_Task_FileLock == NULL) {
|
||||
CLS_FW_Task_FileLock = osMutexNew(NULL);
|
||||
}
|
||||
|
||||
if(CLS_FW_Task_FileLock == NULL) {
|
||||
// error cant create mutex
|
||||
return;
|
||||
}
|
||||
|
||||
// check CLS_FW_Task_id is null or stopped
|
||||
// only one Task can runn at once
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CLSFirmwareUpdateTask_func(void *argument) {
|
||||
char * filename = configuration.name;
|
||||
if( f_open(&fw_file, filename, FA_READ) != FR_OK) {
|
||||
// TODO: Logging
|
||||
osThreadExit();
|
||||
}
|
||||
|
||||
wait_for_start();
|
||||
|
||||
running();
|
||||
|
||||
f_close(&fw_file);
|
||||
osThreadExit();
|
||||
}
|
||||
27
Application/Tasks/FirmwareUpdate.h
Normal file
27
Application/Tasks/FirmwareUpdate.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#define BOOTLOADER_CALL_RETRY_TIME 1000
|
||||
#define BOOTLOADER_CALL_MAX_TRIES 10
|
||||
|
||||
#define TASK_FLAG_WAIT 1
|
||||
#define TASK_FLAG_RUNNING 2
|
||||
|
||||
#define UPDATE_ACK_WINDOW 4
|
||||
#define UPDATE_DONE_MSG 0xFFFFD04EFFFFD04E
|
||||
|
||||
|
||||
typedef struct {
|
||||
char name[32];
|
||||
uint8_t device;
|
||||
} FirmwareUpdateArgs;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t counter;
|
||||
uint8_t data[4];
|
||||
} FwFrame;
|
||||
|
||||
|
||||
void FirmwareUpdateTask_start(FirmwareUpdateArgs args);
|
||||
Reference in New Issue
Block a user