diff --git a/firmware/config/stm32f7ems/efifeatures.h b/firmware/config/stm32f7ems/efifeatures.h index 8bc8166ded..014d17f026 100644 --- a/firmware/config/stm32f7ems/efifeatures.h +++ b/firmware/config/stm32f7ems/efifeatures.h @@ -55,3 +55,6 @@ #undef ENABLE_PERF_TRACE #define ENABLE_PERF_TRACE TRUE + +// F7 may have dual bank, so flash on its own (low priority) thread so as to not block any other operations +#define EFI_FLASH_WRITE_THREAD TRUE diff --git a/firmware/controllers/flash_main.cpp b/firmware/controllers/flash_main.cpp index b74ecfe7b8..7f8947fef0 100644 --- a/firmware/controllers/flash_main.cpp +++ b/firmware/controllers/flash_main.cpp @@ -63,8 +63,10 @@ void setNeedToWriteConfiguration(void) { needToWriteConfiguration = true; #if EFI_FLASH_WRITE_THREAD - // Signal the flash writer thread to wake up and write at its leisure - flashWriteSemaphore.signal(); + if (allowFlashWhileRunning()) { + // Signal the flash writer thread to wake up and write at its leisure + flashWriteSemaphore.signal(); + } #endif // EFI_FLASH_WRITE_THREAD } @@ -73,15 +75,13 @@ bool getNeedToWriteConfiguration(void) { } void writeToFlashIfPending() { -// with a flash write thread, the schedule happens directly from -// setNeedToWriteConfiguration, so there's nothing to do here -#if !EFI_FLASH_WRITE_THREAD - if (!getNeedToWriteConfiguration()) { + // with a flash write thread, the schedule happens directly from + // setNeedToWriteConfiguration, so there's nothing to do here + if (allowFlashWhileRunning() || !getNeedToWriteConfiguration()) { return; } writeToFlashNow(); -#endif } // Erase and write a copy of the configuration at the specified address @@ -254,7 +254,9 @@ void initFlash() { addConsoleAction("rewriteconfig", rewriteConfig); #if EFI_FLASH_WRITE_THREAD - chThdCreateStatic(flashWriteStack, sizeof(flashWriteStack), PRIO_FLASH_WRITE, flashWriteThread, nullptr); + if (allowFlashWhileRunning()) { + chThdCreateStatic(flashWriteStack, sizeof(flashWriteStack), PRIO_FLASH_WRITE, flashWriteThread, nullptr); + } #endif } diff --git a/firmware/hw_layer/ports/cypress/mpu_util.cpp b/firmware/hw_layer/ports/cypress/mpu_util.cpp index 78650fe145..281a765a20 100644 --- a/firmware/hw_layer/ports/cypress/mpu_util.cpp +++ b/firmware/hw_layer/ports/cypress/mpu_util.cpp @@ -238,6 +238,10 @@ CANDriver * detectCanDevice(brain_pin_e pinRx, brain_pin_e pinTx) { #endif /* EFI_CAN_SUPPORT */ +bool allowFlashWhileRunning() { + return false; +} + size_t flashSectorSize(flashsector_t sector) { // sectors 0..11 are the 1st memory bank (1Mb), and 12..23 are the 2nd (the same structure). if (sector <= 3 || (sector >= 12 && sector <= 15)) diff --git a/firmware/hw_layer/ports/kinetis/mpu_util.cpp b/firmware/hw_layer/ports/kinetis/mpu_util.cpp index 3be2a1a2c0..d82d052b9f 100644 --- a/firmware/hw_layer/ports/kinetis/mpu_util.cpp +++ b/firmware/hw_layer/ports/kinetis/mpu_util.cpp @@ -230,6 +230,10 @@ CANDriver * detectCanDevice(brain_pin_e pinRx, brain_pin_e pinTx) { #endif /* EFI_CAN_SUPPORT */ +bool allowFlashWhileRunning() { + return false; +} + size_t flashSectorSize(flashsector_t sector) { // sectors 0..11 are the 1st memory bank (1Mb), and 12..23 are the 2nd (the same structure). if (sector <= 3 || (sector >= 12 && sector <= 15)) diff --git a/firmware/hw_layer/ports/mpu_util.h b/firmware/hw_layer/ports/mpu_util.h index 881ab7b1b2..01d27bc3b3 100644 --- a/firmware/hw_layer/ports/mpu_util.h +++ b/firmware/hw_layer/ports/mpu_util.h @@ -9,6 +9,7 @@ // Base MCU void baseMCUInit(void); void jump_to_bootloader(); +bool allowFlashWhileRunning(); // ADC #if HAL_USE_ADC diff --git a/firmware/hw_layer/ports/stm32/stm32f4/mpu_util.cpp b/firmware/hw_layer/ports/stm32/stm32f4/mpu_util.cpp index 6de64c408c..bf4dca7a1b 100644 --- a/firmware/hw_layer/ports/stm32/stm32f4/mpu_util.cpp +++ b/firmware/hw_layer/ports/stm32/stm32f4/mpu_util.cpp @@ -7,6 +7,11 @@ #include "flash_int.h" +bool allowFlashWhileRunning() { + // Never allow flash while running on F4, dual bank not implemented. + return false; +} + size_t flashSectorSize(flashsector_t sector) { // sectors 0..11 are the 1st memory bank (1Mb), and 12..23 are the 2nd (the same structure). if (sector <= 3 || (sector >= 12 && sector <= 15)) diff --git a/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp b/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp index f9580e58ac..d22497f725 100644 --- a/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp +++ b/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp @@ -49,6 +49,11 @@ static DeviceType determineDevice() { return DeviceType::Unknown; } +bool allowFlashWhileRunning() { + // Allow flash-while-running if dual bank mode is enabled, and we're a 2MB device (ie, no code located in second bank) + return determineDevice() == DeviceType::DualBank2MB; +} + // See ST AN4826 size_t flashSectorSize(flashsector_t sector) { // 1MB devices have 8 sectors per bank diff --git a/firmware/hw_layer/ports/stm32/stm32h7/mpu_util.cpp b/firmware/hw_layer/ports/stm32/stm32h7/mpu_util.cpp index f880cbab0a..13483978dd 100644 --- a/firmware/hw_layer/ports/stm32/stm32h7/mpu_util.cpp +++ b/firmware/hw_layer/ports/stm32/stm32h7/mpu_util.cpp @@ -7,6 +7,11 @@ #include "flash_int.h" +bool allowFlashWhileRunning() { + // We only support dual bank H7, so always allow flash while running. + return true; +} + size_t flashSectorSize(flashsector_t sector) { // All sectors on H7 are 128k return 128 * 1024;