#include #include #include #include "hex-parser.h" #include /* This is used to get the defines for the external watchdog */ #include #include #include #include #include "flash-writer.h" #include static volatile unsigned int wait_tick; static void watchdog_ack(void) { IWDG->KR = 0xAAAA; } static void external_watchdog_disable(void) { RCC->AHB1ENR |= SAFETY_EXT_WATCHDOG_RCC_MASK; __DSB(); /* Set Pin to input. This disables the external watchdog. */ SAFETY_EXT_WATCHDOG_PORT->MODER &= MODER_DELETE(SAFETY_EXT_WATCHDOG_PIN); } void sdio_wait_ms(unsigned int ms) { wait_tick = 0; while (wait_tick < ms); } static FATFS _fs; #define fs (&_fs) static void __attribute__((noreturn)) ram_code_exit(bool updated) { struct safety_memory_boot_status boot_status; safety_memory_get_boot_status(&boot_status); boot_status.code_updated = updated ? 0xFFFFFFFFUL : 0x0UL; boot_status.reboot_to_bootloader = 0x0UL; safety_memory_set_boot_status(&boot_status); NVIC_SystemReset(); while(1); } static int check_hex_file(const char *fname) { enum hex_parser_ret hex_ret; struct hex_parser parser; uint32_t addr; char data[128]; size_t dlen; int retval = -1; uint32_t flash_base; uint32_t flash_top; flash_base = flash_writer_get_base_address(); flash_top = flash_base + flash_writer_get_flash_size(); hex_ret = hex_parser_open(&parser, fname); if (hex_ret != HEX_PARSER_OK) { retval = -1; goto exit; } do { hex_ret = hex_parser_parse(&parser, &addr, data, sizeof(data), &dlen); if (hex_ret == HEX_PARSER_DATA_OK) { if (addr < flash_base || addr+dlen >= flash_top) { retval = -2; goto ret_close_parser; } } } while (hex_ret == HEX_PARSER_DATA_OK || hex_ret == HEX_PARSER_OK); if (hex_ret == HEX_PARSER_EOF_RECORD) { retval = 0; } ret_close_parser: hex_parser_close(&parser); exit: return retval; } int ram_code_main(void) { FRESULT fres; int res; enum safety_memory_state safety_mem_state; static char filename[256]; SysTick_Config(168000UL); external_watchdog_disable(); __enable_irq(); res = safety_memory_init(&safety_mem_state); if (res || safety_mem_state != SAFETY_MEMORY_INIT_VALID_MEMORY) { ram_code_exit(false); } fres = f_mount(fs, "0:/", 1); if (fres != FR_OK) { ram_code_exit(false); } res = safety_memory_get_update_filename(filename, NULL); if (res) ram_code_exit(false); if (check_hex_file(filename)) { ram_code_exit(false); } while(1) { __WFI(); } return 0; } void SysTick_Handler(void) { static uint32_t tick_cnt = 0; wait_tick++; tick_cnt++; watchdog_ack(); if (tick_cnt >= 250) { GPIOB->ODR ^= (1<<2); tick_cnt = 0; } }