From 08ec458e8f7eca8372ae42880dee12aa3c187991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Thu, 8 Apr 2021 21:23:25 +0200 Subject: [PATCH] Add update code to updater and use uart for status updates --- .../{ => periph-config}/shell-uart-config.h | 0 stm-firmware/main.c | 2 +- stm-firmware/updater/ram-code/CMakeLists.txt | 2 +- stm-firmware/updater/ram-code/flash-writer.c | 10 +- stm-firmware/updater/ram-code/flash-writer.h | 2 +- stm-firmware/updater/ram-code/main.c | 127 +++++++++++++++++- stm-firmware/updater/ram-code/uart.c | 29 ++++ stm-firmware/updater/ram-code/uart.h | 10 ++ 8 files changed, 173 insertions(+), 9 deletions(-) rename stm-firmware/include/reflow-controller/{ => periph-config}/shell-uart-config.h (100%) create mode 100644 stm-firmware/updater/ram-code/uart.c create mode 100644 stm-firmware/updater/ram-code/uart.h diff --git a/stm-firmware/include/reflow-controller/shell-uart-config.h b/stm-firmware/include/reflow-controller/periph-config/shell-uart-config.h similarity index 100% rename from stm-firmware/include/reflow-controller/shell-uart-config.h rename to stm-firmware/include/reflow-controller/periph-config/shell-uart-config.h diff --git a/stm-firmware/main.c b/stm-firmware/main.c index e78e6b6..63a73f8 100644 --- a/stm-firmware/main.c +++ b/stm-firmware/main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/stm-firmware/updater/ram-code/CMakeLists.txt b/stm-firmware/updater/ram-code/CMakeLists.txt index 5cd4cf3..ee004a6 100644 --- a/stm-firmware/updater/ram-code/CMakeLists.txt +++ b/stm-firmware/updater/ram-code/CMakeLists.txt @@ -13,7 +13,7 @@ set(ELFFILE "${PROJECT_NAME}.elf") aux_source_directory("." SRCS) aux_source_directory("fatfs" FATFS_SRCS) aux_source_directory("fatfs/shimatta_sdio_driver" SDIO_SRCS) -aux_source_directory("../../stm-periph" STM_PERIPH_SRCS) +set(STM_PERIPH_SRCS "../../stm-periph/backup-ram.c" "../../stm-periph/rcc-manager.c" "../../stm-periph/crc-unit.c") set(SAFETY_MEMORY_SRCS "../../safety/safety-memory.c") add_executable(${ELFFILE} ${SRCS} ${FATFS_SRCS} ${SDIO_SRCS} ${STM_PERIPH_SRCS} ${SAFETY_MEMORY_SRCS}) diff --git a/stm-firmware/updater/ram-code/flash-writer.c b/stm-firmware/updater/ram-code/flash-writer.c index dfcabe9..e8498b2 100644 --- a/stm-firmware/updater/ram-code/flash-writer.c +++ b/stm-firmware/updater/ram-code/flash-writer.c @@ -37,22 +37,22 @@ void flash_writer_perform_mass_erase(void) uint32_t flash_writer_get_flash_size(void) { uint32_t flash_size; - const uint32_t *flash_size_ptr = (const uint32_t *)0x1FFF7A22UL; + const uint16_t *flash_size_ptr = (const uint16_t *)0x1FFF7A22UL; - flash_size = *flash_size_ptr; + flash_size = (uint32_t)*flash_size_ptr; flash_size *= 1024; return flash_size; } -int flash_writer_write_to_memory(void *dest, void *src, uint32_t size) +int flash_writer_write_to_memory(void *dest, const void *src, uint32_t size) { uint32_t full_word_cnt; uint32_t byte_cnt; uint32_t idx; - uint32_t *word_src_ptr; + const uint32_t *word_src_ptr; uint32_t *word_dest_ptr; - char *char_src_ptr; + const char *char_src_ptr; char *char_dest_ptr; flash_writer_enable_access(); diff --git a/stm-firmware/updater/ram-code/flash-writer.h b/stm-firmware/updater/ram-code/flash-writer.h index 69c9ba4..4dc5935 100644 --- a/stm-firmware/updater/ram-code/flash-writer.h +++ b/stm-firmware/updater/ram-code/flash-writer.h @@ -11,6 +11,6 @@ uint32_t flash_writer_get_flash_size(void); uint32_t flash_writer_get_base_address(void); -int flash_writer_write_to_memory(void *dest, void *src, uint32_t size); +int flash_writer_write_to_memory(void *dest, const void *src, uint32_t size); #endif /* _FLASH_WRITER_H_ */ diff --git a/stm-firmware/updater/ram-code/main.c b/stm-firmware/updater/ram-code/main.c index 3a48eba..8a54446 100644 --- a/stm-firmware/updater/ram-code/main.c +++ b/stm-firmware/updater/ram-code/main.c @@ -13,6 +13,8 @@ #include "flash-writer.h" #include +#include +#include "uart.h" static volatile unsigned int wait_tick; @@ -46,6 +48,9 @@ static void __attribute__((noreturn)) ram_code_exit(bool updated) boot_status.reboot_to_bootloader = 0x0UL; safety_memory_set_boot_status(&boot_status); + uart_send_string("Rebooting in 1s...\r\n"); + sdio_wait_ms(1000); + NVIC_SystemReset(); while(1); } @@ -90,17 +95,103 @@ exit: return retval; } +int write_flash_from_buffer(const char *buffer, uint32_t len, uint32_t addr) +{ + return flash_writer_write_to_memory((void *)addr, buffer, len); +} + +int update_flash_from_file(const char *fname) +{ + enum hex_parser_ret hex_ret; + struct hex_parser parser; + static char write_buffer[4096]; + uint32_t wbuffer_base_addr = 0; + uint32_t wbuffer_fill_level = 0; + uint32_t addr; + static char tmp_buff[256]; + size_t dlen; + int retval = 0; + int res; + + hex_ret = hex_parser_open(&parser, fname); + if (hex_ret != HEX_PARSER_OK) { + uart_send_string("Error reading hex file.\r\n"); + return -1; + } + + do { + hex_ret = hex_parser_parse(&parser, &addr, tmp_buff, sizeof(tmp_buff), &dlen); + if (hex_ret == HEX_PARSER_DATA_OK) { + /* Check if tmp would fit in wbuffer */ + if (dlen + wbuffer_fill_level > sizeof(write_buffer)) { + /* Write out the buffer and clean it if it doens't fit */ + res = write_flash_from_buffer(write_buffer, wbuffer_fill_level, wbuffer_base_addr); + if (res) { + retval = -4; + goto exit_parser_close; + } + wbuffer_fill_level = 0; + wbuffer_base_addr = 0; + } + + /* Check if parsed data can be linearily appended to buffer */ + if (wbuffer_fill_level && wbuffer_base_addr + wbuffer_fill_level != addr) { + /* Write out the buffer and clean it if it cannot be appended */ + res = write_flash_from_buffer(write_buffer, wbuffer_fill_level, wbuffer_base_addr); + if (res) { + retval = -4; + goto exit_parser_close; + } + wbuffer_fill_level = 0; + wbuffer_base_addr = 0; + } + + /* Fill in the data into the buffer */ + if (wbuffer_fill_level == 0) { + wbuffer_base_addr = addr; + } + memcpy(&write_buffer[wbuffer_fill_level], tmp_buff, dlen); + wbuffer_fill_level += dlen; + } + } while (hex_ret == HEX_PARSER_DATA_OK || hex_ret == HEX_PARSER_OK); + + if (hex_ret == HEX_PARSER_EOF_RECORD) { + if (wbuffer_fill_level > 0) { + res = write_flash_from_buffer(write_buffer, wbuffer_fill_level, wbuffer_base_addr); + if (res) { + retval = -4; + goto exit_parser_close; + } + } + retval = 0; + } else { + retval = -3; + } + +exit_parser_close: + hex_parser_close(&parser); + + return retval; +} + int ram_code_main(void) { FRESULT fres; int res; enum safety_memory_state safety_mem_state; static char filename[256]; + int retries = 3; SysTick_Config(168000UL); external_watchdog_disable(); __enable_irq(); - + + /* Init the uart module + * Pins don't need configuration. They're already setup by the main program + */ + uart_init(); + uart_send_string("Updater started.\r\n"); + res = safety_memory_init(&safety_mem_state); if (res || safety_mem_state != SAFETY_MEMORY_INIT_VALID_MEMORY) { ram_code_exit(false); @@ -108,6 +199,7 @@ int ram_code_main(void) fres = f_mount(fs, "0:/", 1); if (fres != FR_OK) { + uart_send_string("Could not mount SD card\r\n"); ram_code_exit(false); } @@ -115,10 +207,43 @@ int ram_code_main(void) if (res) ram_code_exit(false); + uart_send_string("Checking hex file\r\n"); + uart_send_string(filename); + uart_send_string("\r\n"); if (check_hex_file(filename)) { + uart_send_string("Error in hex file\r\n"); ram_code_exit(false); } + uart_send_string("File "); + uart_send_string(filename); + uart_send_string(" checked successfully.\r\n"); + uart_send_string("Starting updater...\r\n"); + + do { + uart_send_string("Erasing chip..."); + flash_writer_perform_mass_erase(); + uart_send_string(" done\r\n"); + + uart_send_string("Programming flash...\r\n"); + res = update_flash_from_file(filename); + + if (res) { + uart_send_string("Programming NOT successful.\r\n"); + if (retries > 0) { + uart_send_string("Will retry...\r\n"); + } + } else { + uart_send_string("Programming completed successfully!\r\n"); + break; + } + + } while (retries > 0); + + if (res) { + + } + while(1) { __WFI(); } diff --git a/stm-firmware/updater/ram-code/uart.c b/stm-firmware/updater/ram-code/uart.c new file mode 100644 index 0000000..c9e8d1e --- /dev/null +++ b/stm-firmware/updater/ram-code/uart.c @@ -0,0 +1,29 @@ +#include "uart.h" +#include +#include +#include + +void uart_init(void) +{ + SHELL_UART_RCC_REG |= SHELL_UART_RCC_MASK; + SHELL_UART_PERIPH->BRR = SHELL_UART_BRR_REG_VALUE; + SHELL_UART_PERIPH->CR2 = 0; + SHELL_UART_PERIPH->CR3 = 0; + SHELL_UART_PERIPH->CR1 = USART_CR1_TE | USART_CR1_UE; +} + +void uart_send_char(char c) +{ + while (!(SHELL_UART_PERIPH->SR & USART_SR_TXE)); + SHELL_UART_PERIPH->DR = c; +} + +void uart_send_string(const char *str) +{ + int len, i; + + len = strlen(str); + for (i = 0; i < len; i++) { + uart_send_char(str[i]); + } +} diff --git a/stm-firmware/updater/ram-code/uart.h b/stm-firmware/updater/ram-code/uart.h new file mode 100644 index 0000000..61c0021 --- /dev/null +++ b/stm-firmware/updater/ram-code/uart.h @@ -0,0 +1,10 @@ +#ifndef _UART_H_ +#define _UART_H_ + +void uart_init(void); + +void uart_send_char(char c); + +void uart_send_string(const char *str); + +#endif /* _UART_H_ */