diff --git a/Application/CMakeLists.txt b/Application/CMakeLists.txt index 5f46ae4..7fd0300 100644 --- a/Application/CMakeLists.txt +++ b/Application/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(Tasks) add_subdirectory(CLS) add_subdirectory(CLS_BSP) -add_subdirectory(BSP) \ No newline at end of file +add_subdirectory(BSP) +add_subdirectory(ram_loader) \ No newline at end of file diff --git a/Application/Tasks/CMakeLists.txt b/Application/Tasks/CMakeLists.txt index 4529b81..0f1b3a0 100644 --- a/Application/Tasks/CMakeLists.txt +++ b/Application/Tasks/CMakeLists.txt @@ -22,4 +22,4 @@ target_sources(${PROJECT_NAME} target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) target_link_libraries(${PROJECT_NAME} PUBLIC PROTOS CLS) -target_link_libraries(${PROJECT_NAME} PRIVATE Revision CLS_BSP BSP ulog) \ No newline at end of file +target_link_libraries(${PROJECT_NAME} PRIVATE Revision CLS_BSP BSP ulog ram_loader) \ No newline at end of file diff --git a/Application/Tasks/FirmwareHandler.c b/Application/Tasks/FirmwareHandler.c index b106fb9..78381fe 100644 --- a/Application/Tasks/FirmwareHandler.c +++ b/Application/Tasks/FirmwareHandler.c @@ -10,6 +10,9 @@ #include "crc.h" #include "FirmwareUpdate.h" #include "stdbool.h" +#include "CLS.h" +#include "stdbool.h" +#include "ram_loader.h" // static memory only for decoding messages static cls_firmware_Start msg_cls_firmware_Start; @@ -58,19 +61,15 @@ void DataSend_FirmwareFileCheck(uint32_t crc, uint32_t device_id, bool ready_for #define CHUNK_SIZE 256 // Change this to the size of chunks you want to read static uint8_t crc_buffer[CHUNK_SIZE]; -void DataClbk_cls_firmware_Start(void *msg, uint32_t length) { - DATA_CLBK_SETUP(cls_firmware_Start); - fwStartTime = osKernelGetSysTimerCount(); - fwPackageCounter = 0; + +void fw_Start_Slave( cls_firmware_Start * msg) { + uint32_t crc = 0; UINT totalRead = 0; UINT bytesRead = 0; - if(FileOpen) { - f_close(&FwFile); - } // Check if file already exists - if(f_open(&FwFile, msg_cls_firmware_Start.name, FA_READ) == FR_OK) { + if(f_open(&FwFile, msg->name, FA_READ) == FR_OK) { __HAL_CRC_DR_RESET(&hcrc); do { @@ -80,16 +79,38 @@ void DataClbk_cls_firmware_Start(void *msg, uint32_t length) { } while(bytesRead == CHUNK_SIZE); f_close(&FwFile); - if(crc == msg_cls_firmware_Start.crc_fw) { + if(crc == msg->crc_fw) { // CRC matches, no need for transfer - DataSend_FirmwareFileCheck(crc, msg_cls_firmware_Start.device_id, false, totalRead, msg_cls_firmware_Start.name); + DataSend_FirmwareFileCheck(crc, msg->device_id, false, totalRead, msg->name); return; } } - fresult_open = f_open(&FwFile, msg_cls_firmware_Start.name, FA_CREATE_ALWAYS | FA_WRITE); + fresult_open = f_open(&FwFile, msg->name, FA_CREATE_ALWAYS | FA_WRITE); FileOpen=true; - DataSend_FirmwareFileCheck(crc, msg_cls_firmware_Start.device_id, fresult_open==FR_OK, totalRead, msg_cls_firmware_Start.name); + DataSend_FirmwareFileCheck(crc, msg->device_id, fresult_open==FR_OK, totalRead, msg->name); +} + +void fw_Start_Master( cls_firmware_Start * msg) { + fresult_open = f_open(&FwFile, "firm.bin", FA_CREATE_ALWAYS | FA_WRITE); + FileOpen=true; + DataSend_FirmwareFileCheck(0, msg->device_id, fresult_open==FR_OK, 0, msg->name); +} + +void DataClbk_cls_firmware_Start(void *msg, uint32_t length) { + DATA_CLBK_SETUP(cls_firmware_Start); + fwStartTime = osKernelGetSysTimerCount(); + fwPackageCounter = 0; + + if(FileOpen) { + f_close(&FwFile); + } + + if(msg_cls_firmware_Start.device_id == gCLS_DEVICE_ADDRESS) { + fw_Start_Master(&msg_cls_firmware_Start); + } else { + fw_Start_Slave(&msg_cls_firmware_Start); + } } @@ -133,10 +154,14 @@ void DataClbk_cls_firmware_Done(void *msg, uint32_t length) { fresult_open = 0xFF; FileOpen=false; - FirmwareUpdateArgs args; - args.device = msg_cls_firmware_Done.device_id; - memcpy(args.name, msg_cls_firmware_Start.name, sizeof(args.name)); + if(msg_cls_firmware_Done.device_id == gCLS_DEVICE_ADDRESS) { + RamLoader_LoadApplication(); + } else { - FirmwareUpdateTask_start(args); - + FirmwareUpdateArgs args; + args.device = msg_cls_firmware_Done.device_id; + memcpy(args.name, msg_cls_firmware_Start.name, sizeof(args.name)); + + FirmwareUpdateTask_start(args); + } } \ No newline at end of file diff --git a/Application/Tasks/FirmwareUpdate.c b/Application/Tasks/FirmwareUpdate.c index 291e161..afb1d23 100644 --- a/Application/Tasks/FirmwareUpdate.c +++ b/Application/Tasks/FirmwareUpdate.c @@ -160,7 +160,6 @@ void FirmwareUpdateTask_start(FirmwareUpdateArgs args) { } } -UsbDataPacket buffer; void CLSFirmwareUpdateTask_func(void *argument) { FirmwareUpdateArgs args; osStatus_t status; diff --git a/Application/ram_loader/CMakeLists.txt b/Application/ram_loader/CMakeLists.txt new file mode 100644 index 0000000..42ef0e5 --- /dev/null +++ b/Application/ram_loader/CMakeLists.txt @@ -0,0 +1,34 @@ +# Set the minimum required CMake version +cmake_minimum_required(VERSION 3.12) + +# Set the project name +project(ram_loader) + +# Add the source files for the library +set(SOURCES + ram_loader.c +) + +# Add the header files for the library +set(HEADERS + ram_loader.h +) + +# Create the library target +add_library(ram_loader ${SOURCES} ${HEADERS}) + +# Set the include directories for the library +target_include_directories(ram_loader PUBLIC ./) + +# Set any additional compiler flags or options +# target_compile_options(${PROJECT_NAME} PRIVATE ...) + +# Set any additional linker flags or options +# target_link_options(${PROJECT_NAME} PRIVATE ...) + +# Specify any dependencies for the library +# target_link_libraries(${PROJECT_NAME} ...) + +# Optionally, add an executable target for testing +# add_executable(test_ram_loader test/test_ram_loader.cpp) +# target_link_libraries(test_ram_loader ${PROJECT_NAME}) \ No newline at end of file diff --git a/Application/ram_loader/ram_loader.c b/Application/ram_loader/ram_loader.c new file mode 100644 index 0000000..f062c64 --- /dev/null +++ b/Application/ram_loader/ram_loader.c @@ -0,0 +1,110 @@ +#include "fatfs.h" +#include "string.h" + +#define RAM_LOADER_BUFFER_SIZE 15*1024 +#define RAM_LOADER_ADDRESS 0x38000000 +#define APP_START_ADDRESS RAM_LOADER_ADDRESS +uint8_t * ram_loader_buffer = (uint8_t *) RAM_LOADER_ADDRESS; + +void _app_start(void) +{ + __disable_irq(); + // Reset USB + + //De-init all peripherals + //HAL_ADC_DeInit(&hadc1); + + // Disable Systick + SysTick->CTRL = 0; + SysTick->LOAD = 0; + SysTick->VAL = 0; + + // Reset clock to default + HAL_RCC_DeInit(); + + // Clear all interrupt bits + for (uint8_t i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) + { + NVIC->ICER[i] = 0xFFFFFFFF; + NVIC->ICPR[i] = 0xFFFFFFFF; + } + + __enable_irq(); + + + // set the vector table offset register + SCB->VTOR = APP_START_ADDRESS; + + // get the application stack pointer + __set_MSP(((uint32_t *)APP_START_ADDRESS)[0]); + + + // jump to the application + ((void (*)(void))((uint32_t *)APP_START_ADDRESS)[1])(); + + // the application should never return + // ULOG_ERROR("Failed to start application"); + while (1) {} + +} + +static uint8_t buffer[512]; + +void RamLoader_LoadApplication() +{ + + // check if the file "load.bin" exists + FIL file; + FRESULT res = f_open(&file, "load.bin", FA_READ); + if (res != FR_OK) { + // ULOG_ERROR("Failed to open file load.bin"); + return; + } + + UINT size = f_size(&file); + // ensure the file is not larger than the buffer + if (size > RAM_LOADER_BUFFER_SIZE ) { + // ULOG_ERROR("File load.bin is too large"); + return; + } + + // read the file into the buffer + UINT bytes_read; + uint32_t remaining_bytes = size; + uint8_t *destination_ptr = ram_loader_buffer; + uint8_t *buffer_ptr = buffer; + while (remaining_bytes > 0) { + UINT read_size = remaining_bytes > 512 ? 512 : remaining_bytes; + res = f_read(&file, buffer_ptr, read_size, &bytes_read); + if (res != FR_OK) { + // ULOG_ERROR("Failed to read file load.bin"); + return; + } + if (bytes_read != read_size) { + // ULOG_ERROR("Failed to read file load.bin completely"); + return; + } + + memcpy(destination_ptr, buffer_ptr, read_size); + remaining_bytes -= read_size; + destination_ptr += read_size; + } + + // close the file + f_close(&file); + + + // check that the file to flash exists ("firm.bin") + res = f_open(&file, "firm.bin", FA_READ); + if (res != FR_OK) { + // ULOG_ERROR("Failed to open file firm.bin"); + return; + } + //close the file + f_close(&file); + + + _app_start(); + + +} \ No newline at end of file diff --git a/Application/ram_loader/ram_loader.h b/Application/ram_loader/ram_loader.h new file mode 100644 index 0000000..33094af --- /dev/null +++ b/Application/ram_loader/ram_loader.h @@ -0,0 +1,3 @@ +#pragma once + +void RamLoader_LoadApplication(); \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f9c4cb4..1b90e48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,7 +140,7 @@ add_subdirectory("Application") add_executable(${CMAKE_PROJECT_NAME}) target_sources(${CMAKE_PROJECT_NAME} PUBLIC ${sources_SRCS}) -target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Tasks CLS CLS_BSP BSP EE24 INA219 ulog) +target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Tasks CLS CLS_BSP BSP EE24 INA219 ulog ram_loader) #target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC PROTOS) target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC uart_driver) #target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC lwrb) diff --git a/Core/Src/main.c b/Core/Src/main.c index 68097f9..d15f5b9 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -41,6 +41,7 @@ #include "BSP_POWER.h" #include "BSP_GPIO.h" #include "BSP_ADC.h" +#include "ram_loader.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -73,13 +74,12 @@ static void MPU_Config(void); void MX_FREERTOS_Init(void); /* USER CODE BEGIN PFP */ void ULOG_SendLPUART(ulog_level_t level, char *msg); -void JumpToBootloader_system(void); + /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ -const uint32_t OS_BOOTFLAG_ADDRESS = 0x38000000; -const uint32_t OS_BOOTFLAG_MAGIC = 0xDEADBEFF; + /* USER CODE END 0 */ /** @@ -90,19 +90,6 @@ int main(void) { /* USER CODE BEGIN 1 */ - // Check if the bootloader magic number is set at the given address - volatile uint32_t * ptr = (uint32_t *)OS_BOOTFLAG_ADDRESS; - if (*ptr == OS_BOOTFLAG_MAGIC) { - // Jump to the bootloader - *ptr = 0; - JumpToBootloader_system(); - } - - if (*ptr == 0) { - *ptr = 2; - NVIC_SystemReset(); - } - /* USER CODE END 1 */ @@ -302,58 +289,8 @@ void ULOG_SendLPUART(ulog_level_t level, char *msg) { HAL_UART_Transmit(&hlpuart1, (const uint8_t*)ulog_send_buffer, send_length, LOG_TIMEOUT); } -void JumpToBootloader(void) -{ - - // Set the magic number to the given address - volatile uint32_t * ptr = (uint32_t *)OS_BOOTFLAG_ADDRESS; - *ptr = OS_BOOTFLAG_MAGIC; - - - NVIC_SystemReset(); -} - -void JumpToBootloader_system(void) -{ -#define conBootloadAddress 0x1FF09800 - - void (*SysMemBootJump)(void); - uint8_t i; - - __disable_irq(); - // Reset USB - //USBD_DeInit(&hUsbDeviceHS); - - //De-init all peripherals - //HAL_ADC_DeInit(&hadc1); - - // Disable Systick - SysTick->CTRL = 0; - SysTick->LOAD = 0; - SysTick->VAL = 0; - - // Reset clock to default - HAL_RCC_DeInit(); - - // Clear all interrupt bits - for (i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) - { - NVIC->ICER[i] = 0xFFFFFFFF; - NVIC->ICPR[i] = 0xFFFFFFFF; - } - - __enable_irq(); - - SysMemBootJump = (void (*)(void)) (*((uint32_t *) (conBootloadAddress + 4))); - __set_MSP(*(uint32_t *)conBootloadAddress); - SysMemBootJump(); - - while (1); // Just in case... -} - - void DataClbk_cls_usb_JumpToBootloader(void* msg, uint32_t length) { - JumpToBootloader(); + RamLoader_LoadApplication(); } /* USER CODE END 4 */ diff --git a/tools/send_fw.py b/tools/send_fw.py index 42c5523..c6ba97b 100644 --- a/tools/send_fw.py +++ b/tools/send_fw.py @@ -30,7 +30,7 @@ def make_header(typeid: PackageType, length: int) -> bytearray: struct_format = '> 8) & 0xFF) + (typeidint & 0xFF) + ((typeidint >> 8) & 0xFF) + check = ((length & 0xFF) + ((length >> 8) & 0xFF) + (typeidint & 0xFF) + ((typeidint >> 8) & 0xFF) ) & 0xff packed_data = struct.pack(struct_format, length, typeid, check) return packed_data