diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c858831ed86a80964624b7c2f84fdc3338b0aba..72dfec3d779256845c691e855da0396714f59ce2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -290,6 +290,9 @@ sbs_target(test-i2c-f7 stm32f767zi_nucleo) add_executable(test-wiz5500 src/tests/drivers/test-wiz5500.cpp) sbs_target(test-wiz5500 stm32f767zi_gemini_gs) +add_executable(test-bsram src/tests/drivers/test-bsram.cpp) +sbs_target(test-bsram stm32f767zi_lyra_biscotto) + #-----------------------------------------------------------------------------# # Tests - Events # #-----------------------------------------------------------------------------# diff --git a/libs/miosix-kernel b/libs/miosix-kernel index 8bd5f902130fbde9235a0af750f59b9353ec3451..a52d94acbfd617ae567a5efc1626e9b88703a0dd 160000 --- a/libs/miosix-kernel +++ b/libs/miosix-kernel @@ -1 +1 @@ -Subproject commit 8bd5f902130fbde9235a0af750f59b9353ec3451 +Subproject commit a52d94acbfd617ae567a5efc1626e9b88703a0dd diff --git a/src/bsps/stm32f767zi_compute_unit_v2/config/board_options.cmake b/src/bsps/stm32f767zi_compute_unit_v2/config/board_options.cmake index bc751fb1b2b7ecce6c7add7bf61a3cc23038a693..0028955170363faa88ecb730fbeea85b6818f66f 100644 --- a/src/bsps/stm32f767zi_compute_unit_v2/config/board_options.cmake +++ b/src/bsps/stm32f767zi_compute_unit_v2/config/board_options.cmake @@ -103,4 +103,5 @@ set(ARCH_SRC ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp ${KPATH}/arch/common/drivers/serial_stm32.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp + ${KPATH}/arch/common/drivers/stm32_bsram.cpp ) diff --git a/src/bsps/stm32f767zi_compute_unit_v2/config/board_options_no_xram.cmake b/src/bsps/stm32f767zi_compute_unit_v2/config/board_options_no_xram.cmake index e16999d91d3d137f94caf4e64654575e4bdeb1c6..ac3f3e5fc97409cf570f5a4e416c50d808c24d65 100644 --- a/src/bsps/stm32f767zi_compute_unit_v2/config/board_options_no_xram.cmake +++ b/src/bsps/stm32f767zi_compute_unit_v2/config/board_options_no_xram.cmake @@ -103,4 +103,5 @@ set(ARCH_SRC ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp ${KPATH}/arch/common/drivers/serial_stm32.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp + ${KPATH}/arch/common/drivers/stm32_bsram.cpp ) diff --git a/src/bsps/stm32f767zi_compute_unit_v2/core/stage_1_boot.cpp b/src/bsps/stm32f767zi_compute_unit_v2/core/stage_1_boot.cpp index 83eac53b4b0b56309c0a9c26aacb7ff4289558d0..95d830c5c71f91b8ccc78c62ff5cb7c9a462b0c2 100644 --- a/src/bsps/stm32f767zi_compute_unit_v2/core/stage_1_boot.cpp +++ b/src/bsps/stm32f767zi_compute_unit_v2/core/stage_1_boot.cpp @@ -68,6 +68,8 @@ void program_startup() memcpy(data, etext, edata - data); memset(bss_start, 0, bss_end - bss_start); + miosix::configureBackupSram(); + // Move on to stage 2 _init(); diff --git a/src/bsps/stm32f767zi_compute_unit_v2/interfaces-impl/bsp.cpp b/src/bsps/stm32f767zi_compute_unit_v2/interfaces-impl/bsp.cpp index 366e5457e1fa63b17abf93c563edae9ce5755213..cebec9b0160ce8cfabad83a3db3bc6005df6321f 100644 --- a/src/bsps/stm32f767zi_compute_unit_v2/interfaces-impl/bsp.cpp +++ b/src/bsps/stm32f767zi_compute_unit_v2/interfaces-impl/bsp.cpp @@ -37,7 +37,7 @@ #include "drivers/sd_stm32f2_f4_f7.h" #include "drivers/serial.h" #include "drivers/serial_stm32.h" -#include "drivers/stm32_sgm.h" +#include "drivers/stm32_bsram.h" #include "filesystem/console/console_device.h" #include "filesystem/file_access.h" #include "interfaces/arch_registers.h" @@ -222,6 +222,28 @@ void configureSdram() #endif } +void configureBackupSram() +{ + // Initialize the backup SRAM device + BSRAM::init(); + + // Defined in the linker script + extern unsigned char _preserve_start asm("_preserve_start"); + extern unsigned char _preserve_end asm("_preserve_end"); + extern unsigned char _preserve_load asm("_preserve_load"); + + unsigned char *preserve_start = &_preserve_start; + unsigned char *preserve_end = &_preserve_end; + unsigned char *preserve_load = &_preserve_load; + + // Load the .preserve section from flash if not a software reset + if (miosix::lastResetReason() != miosix::ResetReason::SOFTWARE) + { + BSRAM::EnableWriteLock l; + memcpy(preserve_start, preserve_load, preserve_end - preserve_start); + } +} + void IRQbspInit() { // Enable USART1 pins port diff --git a/src/bsps/stm32f767zi_compute_unit_v2/interfaces-impl/bsp_impl.h b/src/bsps/stm32f767zi_compute_unit_v2/interfaces-impl/bsp_impl.h index feb02c1280930087540af07157270b0ac858f57c..6cbcdde743840c5890416a8aaffcf2b3d3d5eaca 100644 --- a/src/bsps/stm32f767zi_compute_unit_v2/interfaces-impl/bsp_impl.h +++ b/src/bsps/stm32f767zi_compute_unit_v2/interfaces-impl/bsp_impl.h @@ -31,6 +31,15 @@ #include "config/miosix_settings.h" #include "interfaces/gpio.h" +/** + * Macro to place a variable in the backup SRAM. Variables are allowed to have a + * default value. The kernel initializes the variable to the provided value if + * the reset reason is not a software reset. + * + * Example usage: `PRESERVE int myVar = 0;` + */ +#define PRESERVE __attribute__((section(".preserve"))) + namespace miosix { @@ -46,6 +55,13 @@ namespace miosix */ void configureSdram(); +/** + * \internal + * Called by stage_1_boot.cpp to configure the backup SRAM and .preserve region + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureBackupSram(); + /** * \internal * Board pin definition diff --git a/src/bsps/stm32f767zi_compute_unit_v2/stm32_2m+32m_xram.ld b/src/bsps/stm32f767zi_compute_unit_v2/stm32_2m+32m_xram.ld index 044ba1c62814ca2a4081a49fa5bca4d686ca16d5..3c7843ff586ea8d42f88f51c0fb55eba92badcca 100644 --- a/src/bsps/stm32f767zi_compute_unit_v2/stm32_2m+32m_xram.ld +++ b/src/bsps/stm32f767zi_compute_unit_v2/stm32_2m+32m_xram.ld @@ -178,7 +178,7 @@ SECTIONS _end = .; PROVIDE(end = .); - .preserve(NOLOAD) : ALIGN(4) + .preserve : ALIGN(4) { _preserve_start = .; . = ALIGN(4); @@ -186,5 +186,6 @@ SECTIONS *(.preserve*); . = ALIGN(4); _preserve_end = .; - } > bram + } > bram AT > flash + _preserve_load = LOADADDR(.preserve); } diff --git a/src/bsps/stm32f767zi_compute_unit_v2/stm32_2m+384k_ram.ld b/src/bsps/stm32f767zi_compute_unit_v2/stm32_2m+384k_ram.ld index 497bd5198760b9637c774bf3900fd9dfbc01a2b2..b25d3fe8e93d1fad0573ec2067b3e703040b7eba 100644 --- a/src/bsps/stm32f767zi_compute_unit_v2/stm32_2m+384k_ram.ld +++ b/src/bsps/stm32f767zi_compute_unit_v2/stm32_2m+384k_ram.ld @@ -177,7 +177,7 @@ SECTIONS _end = .; PROVIDE(end = .); - .preserve(NOLOAD) : ALIGN(4) + .preserve : ALIGN(4) { _preserve_start = .; . = ALIGN(4); @@ -185,5 +185,6 @@ SECTIONS *(.preserve*); . = ALIGN(4); _preserve_end = .; - } > bram + } > bram AT > flash + _preserve_load = LOADADDR(.preserve); } diff --git a/src/bsps/stm32f767zi_lyra_biscotto/config/board_options.cmake b/src/bsps/stm32f767zi_lyra_biscotto/config/board_options.cmake index 955e95ee82285219d583cd3e8a73e7a9259584ae..1f21a96fb6da6f81cde3f259f1a60abd7480e2e8 100644 --- a/src/bsps/stm32f767zi_lyra_biscotto/config/board_options.cmake +++ b/src/bsps/stm32f767zi_lyra_biscotto/config/board_options.cmake @@ -103,4 +103,5 @@ set(ARCH_SRC ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp ${KPATH}/arch/common/drivers/serial_stm32.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp + ${KPATH}/arch/common/drivers/stm32_bsram.cpp ) diff --git a/src/bsps/stm32f767zi_lyra_biscotto/core/stage_1_boot.cpp b/src/bsps/stm32f767zi_lyra_biscotto/core/stage_1_boot.cpp index 83eac53b4b0b56309c0a9c26aacb7ff4289558d0..95d830c5c71f91b8ccc78c62ff5cb7c9a462b0c2 100644 --- a/src/bsps/stm32f767zi_lyra_biscotto/core/stage_1_boot.cpp +++ b/src/bsps/stm32f767zi_lyra_biscotto/core/stage_1_boot.cpp @@ -68,6 +68,8 @@ void program_startup() memcpy(data, etext, edata - data); memset(bss_start, 0, bss_end - bss_start); + miosix::configureBackupSram(); + // Move on to stage 2 _init(); diff --git a/src/bsps/stm32f767zi_lyra_biscotto/interfaces-impl/bsp.cpp b/src/bsps/stm32f767zi_lyra_biscotto/interfaces-impl/bsp.cpp index ba299ab90c3eb8b74e40ba541d395ae07731cb0a..e48915e327ee42f901d41805c8cbca0a91134fd1 100644 --- a/src/bsps/stm32f767zi_lyra_biscotto/interfaces-impl/bsp.cpp +++ b/src/bsps/stm32f767zi_lyra_biscotto/interfaces-impl/bsp.cpp @@ -37,7 +37,7 @@ #include "drivers/sd_stm32f2_f4_f7.h" #include "drivers/serial.h" #include "drivers/serial_stm32.h" -#include "drivers/stm32_sgm.h" +#include "drivers/stm32_bsram.h" #include "filesystem/console/console_device.h" #include "filesystem/file_access.h" #include "hwmapping.h" @@ -223,6 +223,28 @@ void configureSdram() #endif } +void configureBackupSram() +{ + // Initialize the backup SRAM device + BSRAM::init(); + + // Defined in the linker script + extern unsigned char _preserve_start asm("_preserve_start"); + extern unsigned char _preserve_end asm("_preserve_end"); + extern unsigned char _preserve_load asm("_preserve_load"); + + unsigned char *preserve_start = &_preserve_start; + unsigned char *preserve_end = &_preserve_end; + unsigned char *preserve_load = &_preserve_load; + + // Load the .preserve section from flash if not a software reset + if (miosix::lastResetReason() != miosix::ResetReason::SOFTWARE) + { + BSRAM::EnableWriteLock l; + memcpy(preserve_start, preserve_load, preserve_end - preserve_start); + } +} + void IRQbspInit() { // Enable USART1 pins port diff --git a/src/bsps/stm32f767zi_lyra_biscotto/interfaces-impl/bsp_impl.h b/src/bsps/stm32f767zi_lyra_biscotto/interfaces-impl/bsp_impl.h index feb02c1280930087540af07157270b0ac858f57c..6cbcdde743840c5890416a8aaffcf2b3d3d5eaca 100644 --- a/src/bsps/stm32f767zi_lyra_biscotto/interfaces-impl/bsp_impl.h +++ b/src/bsps/stm32f767zi_lyra_biscotto/interfaces-impl/bsp_impl.h @@ -31,6 +31,15 @@ #include "config/miosix_settings.h" #include "interfaces/gpio.h" +/** + * Macro to place a variable in the backup SRAM. Variables are allowed to have a + * default value. The kernel initializes the variable to the provided value if + * the reset reason is not a software reset. + * + * Example usage: `PRESERVE int myVar = 0;` + */ +#define PRESERVE __attribute__((section(".preserve"))) + namespace miosix { @@ -46,6 +55,13 @@ namespace miosix */ void configureSdram(); +/** + * \internal + * Called by stage_1_boot.cpp to configure the backup SRAM and .preserve region + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureBackupSram(); + /** * \internal * Board pin definition diff --git a/src/bsps/stm32f767zi_lyra_biscotto/stm32_2m+32m_xram.ld b/src/bsps/stm32f767zi_lyra_biscotto/stm32_2m+32m_xram.ld index 044ba1c62814ca2a4081a49fa5bca4d686ca16d5..991fc8a4b132a01c80247fd23c5cc5c885a94d7b 100644 --- a/src/bsps/stm32f767zi_lyra_biscotto/stm32_2m+32m_xram.ld +++ b/src/bsps/stm32f767zi_lyra_biscotto/stm32_2m+32m_xram.ld @@ -177,8 +177,12 @@ SECTIONS _end = .; PROVIDE(end = .); - - .preserve(NOLOAD) : ALIGN(4) + + /* + * .preserve section: global variables preserved across software reboots go + * to bram, but also store a copy to flash to initialize them + */ + .preserve : ALIGN(4) { _preserve_start = .; . = ALIGN(4); @@ -186,5 +190,6 @@ SECTIONS *(.preserve*); . = ALIGN(4); _preserve_end = .; - } > bram + } > bram AT > flash + _preserve_load = LOADADDR(.preserve); } diff --git a/src/bsps/stm32f767zi_lyra_biscotto/stm32_2m+384k_ram.ld b/src/bsps/stm32f767zi_lyra_biscotto/stm32_2m+384k_ram.ld index 497bd5198760b9637c774bf3900fd9dfbc01a2b2..a0c1415c382a477b1adbd11e91ec1af334f44466 100644 --- a/src/bsps/stm32f767zi_lyra_biscotto/stm32_2m+384k_ram.ld +++ b/src/bsps/stm32f767zi_lyra_biscotto/stm32_2m+384k_ram.ld @@ -176,8 +176,12 @@ SECTIONS _end = .; PROVIDE(end = .); - - .preserve(NOLOAD) : ALIGN(4) + + /* + * .preserve section: global variables preserved across software reboots go + * to bram, but also store a copy to flash to initialize them + */ + .preserve : ALIGN(4) { _preserve_start = .; . = ALIGN(4); @@ -185,5 +189,6 @@ SECTIONS *(.preserve*); . = ALIGN(4); _preserve_end = .; - } > bram + } > bram AT > flash + _preserve_load = LOADADDR(.preserve); } diff --git a/src/bsps/stm32f767zi_lyra_motor/config/board_options.cmake b/src/bsps/stm32f767zi_lyra_motor/config/board_options.cmake index 23ec4d215754bd85ad99c104802e53cf7a8423f7..75d406fa5f2ca9a99b8aa8d1e1f37b50a71cbb48 100644 --- a/src/bsps/stm32f767zi_lyra_motor/config/board_options.cmake +++ b/src/bsps/stm32f767zi_lyra_motor/config/board_options.cmake @@ -103,4 +103,5 @@ set(ARCH_SRC ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp ${KPATH}/arch/common/drivers/serial_stm32.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp + ${KPATH}/arch/common/drivers/stm32_bsram.cpp ) diff --git a/src/bsps/stm32f767zi_lyra_motor/core/stage_1_boot.cpp b/src/bsps/stm32f767zi_lyra_motor/core/stage_1_boot.cpp index 83eac53b4b0b56309c0a9c26aacb7ff4289558d0..95d830c5c71f91b8ccc78c62ff5cb7c9a462b0c2 100644 --- a/src/bsps/stm32f767zi_lyra_motor/core/stage_1_boot.cpp +++ b/src/bsps/stm32f767zi_lyra_motor/core/stage_1_boot.cpp @@ -68,6 +68,8 @@ void program_startup() memcpy(data, etext, edata - data); memset(bss_start, 0, bss_end - bss_start); + miosix::configureBackupSram(); + // Move on to stage 2 _init(); diff --git a/src/bsps/stm32f767zi_lyra_motor/interfaces-impl/bsp.cpp b/src/bsps/stm32f767zi_lyra_motor/interfaces-impl/bsp.cpp index 1ac009ad000c06421bd21a764b6635e7dacee1ea..6698f1979cdc34cca79965cfb98a9bff54f862b5 100644 --- a/src/bsps/stm32f767zi_lyra_motor/interfaces-impl/bsp.cpp +++ b/src/bsps/stm32f767zi_lyra_motor/interfaces-impl/bsp.cpp @@ -37,7 +37,7 @@ #include "drivers/sd_stm32f2_f4_f7.h" #include "drivers/serial.h" #include "drivers/serial_stm32.h" -#include "drivers/stm32_sgm.h" +#include "drivers/stm32_bsram.h" #include "filesystem/console/console_device.h" #include "filesystem/file_access.h" #include "hwmapping.h" @@ -223,6 +223,28 @@ void configureSdram() #endif } +void configureBackupSram() +{ + // Initialize the backup SRAM device + BSRAM::init(); + + // Defined in the linker script + extern unsigned char _preserve_start asm("_preserve_start"); + extern unsigned char _preserve_end asm("_preserve_end"); + extern unsigned char _preserve_load asm("_preserve_load"); + + unsigned char *preserve_start = &_preserve_start; + unsigned char *preserve_end = &_preserve_end; + unsigned char *preserve_load = &_preserve_load; + + // Load the .preserve section from flash if not a software reset + if (miosix::lastResetReason() != miosix::ResetReason::SOFTWARE) + { + BSRAM::EnableWriteLock l; + memcpy(preserve_start, preserve_load, preserve_end - preserve_start); + } +} + void IRQbspInit() { // Enable USART1 pins port diff --git a/src/bsps/stm32f767zi_lyra_motor/interfaces-impl/bsp_impl.h b/src/bsps/stm32f767zi_lyra_motor/interfaces-impl/bsp_impl.h index feb02c1280930087540af07157270b0ac858f57c..6cbcdde743840c5890416a8aaffcf2b3d3d5eaca 100644 --- a/src/bsps/stm32f767zi_lyra_motor/interfaces-impl/bsp_impl.h +++ b/src/bsps/stm32f767zi_lyra_motor/interfaces-impl/bsp_impl.h @@ -31,6 +31,15 @@ #include "config/miosix_settings.h" #include "interfaces/gpio.h" +/** + * Macro to place a variable in the backup SRAM. Variables are allowed to have a + * default value. The kernel initializes the variable to the provided value if + * the reset reason is not a software reset. + * + * Example usage: `PRESERVE int myVar = 0;` + */ +#define PRESERVE __attribute__((section(".preserve"))) + namespace miosix { @@ -46,6 +55,13 @@ namespace miosix */ void configureSdram(); +/** + * \internal + * Called by stage_1_boot.cpp to configure the backup SRAM and .preserve region + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureBackupSram(); + /** * \internal * Board pin definition diff --git a/src/bsps/stm32f767zi_lyra_motor/stm32_2m+32m_xram.ld b/src/bsps/stm32f767zi_lyra_motor/stm32_2m+32m_xram.ld index 044ba1c62814ca2a4081a49fa5bca4d686ca16d5..3c7843ff586ea8d42f88f51c0fb55eba92badcca 100644 --- a/src/bsps/stm32f767zi_lyra_motor/stm32_2m+32m_xram.ld +++ b/src/bsps/stm32f767zi_lyra_motor/stm32_2m+32m_xram.ld @@ -178,7 +178,7 @@ SECTIONS _end = .; PROVIDE(end = .); - .preserve(NOLOAD) : ALIGN(4) + .preserve : ALIGN(4) { _preserve_start = .; . = ALIGN(4); @@ -186,5 +186,6 @@ SECTIONS *(.preserve*); . = ALIGN(4); _preserve_end = .; - } > bram + } > bram AT > flash + _preserve_load = LOADADDR(.preserve); } diff --git a/src/bsps/stm32f767zi_lyra_motor/stm32_2m+384k_ram.ld b/src/bsps/stm32f767zi_lyra_motor/stm32_2m+384k_ram.ld index 497bd5198760b9637c774bf3900fd9dfbc01a2b2..b25d3fe8e93d1fad0573ec2067b3e703040b7eba 100644 --- a/src/bsps/stm32f767zi_lyra_motor/stm32_2m+384k_ram.ld +++ b/src/bsps/stm32f767zi_lyra_motor/stm32_2m+384k_ram.ld @@ -177,7 +177,7 @@ SECTIONS _end = .; PROVIDE(end = .); - .preserve(NOLOAD) : ALIGN(4) + .preserve : ALIGN(4) { _preserve_start = .; . = ALIGN(4); @@ -185,5 +185,6 @@ SECTIONS *(.preserve*); . = ALIGN(4); _preserve_end = .; - } > bram + } > bram AT > flash + _preserve_load = LOADADDR(.preserve); } diff --git a/src/bsps/stm32f767zi_rig_v2/config/board_options.cmake b/src/bsps/stm32f767zi_rig_v2/config/board_options.cmake index a7586b6b8252cd68321f195967b57be8bfcb30f8..e62c44e7cf899a1ec6e8dfdae12a77f739d5c083 100644 --- a/src/bsps/stm32f767zi_rig_v2/config/board_options.cmake +++ b/src/bsps/stm32f767zi_rig_v2/config/board_options.cmake @@ -103,4 +103,5 @@ set(ARCH_SRC ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp ${KPATH}/arch/common/drivers/serial_stm32.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp + ${KPATH}/arch/common/drivers/stm32_bsram.cpp ) diff --git a/src/bsps/stm32f767zi_rig_v2/core/stage_1_boot.cpp b/src/bsps/stm32f767zi_rig_v2/core/stage_1_boot.cpp index 83eac53b4b0b56309c0a9c26aacb7ff4289558d0..95d830c5c71f91b8ccc78c62ff5cb7c9a462b0c2 100644 --- a/src/bsps/stm32f767zi_rig_v2/core/stage_1_boot.cpp +++ b/src/bsps/stm32f767zi_rig_v2/core/stage_1_boot.cpp @@ -68,6 +68,8 @@ void program_startup() memcpy(data, etext, edata - data); memset(bss_start, 0, bss_end - bss_start); + miosix::configureBackupSram(); + // Move on to stage 2 _init(); diff --git a/src/bsps/stm32f767zi_rig_v2/interfaces-impl/bsp.cpp b/src/bsps/stm32f767zi_rig_v2/interfaces-impl/bsp.cpp index c796ad7dfce926c3c1a3e0900b133193ecc31d86..2c764c17e533c986fee63a0a288905cd29928560 100644 --- a/src/bsps/stm32f767zi_rig_v2/interfaces-impl/bsp.cpp +++ b/src/bsps/stm32f767zi_rig_v2/interfaces-impl/bsp.cpp @@ -37,7 +37,7 @@ #include "drivers/sd_stm32f2_f4_f7.h" #include "drivers/serial.h" #include "drivers/serial_stm32.h" -#include "drivers/stm32_sgm.h" +#include "drivers/stm32_bsram.h" #include "filesystem/console/console_device.h" #include "filesystem/file_access.h" #include "hwmapping.h" @@ -223,6 +223,28 @@ void configureSdram() #endif } +void configureBackupSram() +{ + // Initialize the backup SRAM device + BSRAM::init(); + + // Defined in the linker script + extern unsigned char _preserve_start asm("_preserve_start"); + extern unsigned char _preserve_end asm("_preserve_end"); + extern unsigned char _preserve_load asm("_preserve_load"); + + unsigned char *preserve_start = &_preserve_start; + unsigned char *preserve_end = &_preserve_end; + unsigned char *preserve_load = &_preserve_load; + + // Load the .preserve section from flash if not a software reset + if (miosix::lastResetReason() != miosix::ResetReason::SOFTWARE) + { + BSRAM::EnableWriteLock l; + memcpy(preserve_start, preserve_load, preserve_end - preserve_start); + } +} + void IRQbspInit() { // Enable USART1 pins port diff --git a/src/bsps/stm32f767zi_rig_v2/interfaces-impl/bsp_impl.h b/src/bsps/stm32f767zi_rig_v2/interfaces-impl/bsp_impl.h index feb02c1280930087540af07157270b0ac858f57c..6cbcdde743840c5890416a8aaffcf2b3d3d5eaca 100644 --- a/src/bsps/stm32f767zi_rig_v2/interfaces-impl/bsp_impl.h +++ b/src/bsps/stm32f767zi_rig_v2/interfaces-impl/bsp_impl.h @@ -31,6 +31,15 @@ #include "config/miosix_settings.h" #include "interfaces/gpio.h" +/** + * Macro to place a variable in the backup SRAM. Variables are allowed to have a + * default value. The kernel initializes the variable to the provided value if + * the reset reason is not a software reset. + * + * Example usage: `PRESERVE int myVar = 0;` + */ +#define PRESERVE __attribute__((section(".preserve"))) + namespace miosix { @@ -46,6 +55,13 @@ namespace miosix */ void configureSdram(); +/** + * \internal + * Called by stage_1_boot.cpp to configure the backup SRAM and .preserve region + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureBackupSram(); + /** * \internal * Board pin definition diff --git a/src/bsps/stm32f767zi_rig_v2/stm32_2m+32m_xram.ld b/src/bsps/stm32f767zi_rig_v2/stm32_2m+32m_xram.ld index 044ba1c62814ca2a4081a49fa5bca4d686ca16d5..3c7843ff586ea8d42f88f51c0fb55eba92badcca 100644 --- a/src/bsps/stm32f767zi_rig_v2/stm32_2m+32m_xram.ld +++ b/src/bsps/stm32f767zi_rig_v2/stm32_2m+32m_xram.ld @@ -178,7 +178,7 @@ SECTIONS _end = .; PROVIDE(end = .); - .preserve(NOLOAD) : ALIGN(4) + .preserve : ALIGN(4) { _preserve_start = .; . = ALIGN(4); @@ -186,5 +186,6 @@ SECTIONS *(.preserve*); . = ALIGN(4); _preserve_end = .; - } > bram + } > bram AT > flash + _preserve_load = LOADADDR(.preserve); } diff --git a/src/bsps/stm32f767zi_rig_v2/stm32_2m+384k_ram.ld b/src/bsps/stm32f767zi_rig_v2/stm32_2m+384k_ram.ld index 497bd5198760b9637c774bf3900fd9dfbc01a2b2..b25d3fe8e93d1fad0573ec2067b3e703040b7eba 100644 --- a/src/bsps/stm32f767zi_rig_v2/stm32_2m+384k_ram.ld +++ b/src/bsps/stm32f767zi_rig_v2/stm32_2m+384k_ram.ld @@ -177,7 +177,7 @@ SECTIONS _end = .; PROVIDE(end = .); - .preserve(NOLOAD) : ALIGN(4) + .preserve : ALIGN(4) { _preserve_start = .; . = ALIGN(4); @@ -185,5 +185,6 @@ SECTIONS *(.preserve*); . = ALIGN(4); _preserve_end = .; - } > bram + } > bram AT > flash + _preserve_load = LOADADDR(.preserve); } diff --git a/src/tests/drivers/test-bsram.cpp b/src/tests/drivers/test-bsram.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8fcda4ab0c1fefc3182629a98290bb9937a4b7f2 --- /dev/null +++ b/src/tests/drivers/test-bsram.cpp @@ -0,0 +1,102 @@ +/* Copyright (c) 2024 Skyward Experimental Rocketry + * Authors: Emilio Corigliano, Niccolò Betto + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <arch/common/drivers/stm32_bsram.h> +#include <miosix.h> + +#include <iostream> + +int PRESERVE preservedVariable = 42; + +std::string to_string(miosix::ResetReason reason) +{ + switch (reason) + { + case miosix::ResetReason::UNKNOWN: + return "UNKNOWN"; + case miosix::ResetReason::LOW_POWER: + return "LOW_POWER"; + case miosix::ResetReason::WINDOW_WATCHDOG: + return "WINDOW_WATCHDOG"; + case miosix::ResetReason::INDEPENDENT_WATCHDOG: + return "INDEPENDENT_WATCHDOG"; + case miosix::ResetReason::SOFTWARE: + return "SOFTWARE"; + case miosix::ResetReason::POWER_ON: + return "POWER_ON"; + case miosix::ResetReason::PIN: + return "PIN"; + default: + return "ResetReason not valid"; + } +} + +void printInfo() +{ + std::cout << "preservedVariable: " << preservedVariable << "\n"; + std::cout << "resetReason: " << to_string(miosix::lastResetReason()) + << "\n"; + std::cout.flush(); +} + +int main() +{ + while (true) + { + printInfo(); + + int option; + std::cout << "Select option" + << " (1 = set preserved variable; 2 = software reset): "; + std::cin >> option; + + switch (option) + { + case 1: + int userInput; + std::cout << "Input the new value of the preserved variable" + << std::endl; + std::cin >> userInput; + { + // Enabling BSRAM write only in this scope + miosix::BSRAM::EnableWriteLock l; + preservedVariable = userInput; + } + + // Set variable out of the allowed scope to check it isn't + // written + // cppcheck-suppress redundantAssignment + preservedVariable = 1337; + break; + + case 2: + miosix::reboot(); + break; + + default: + std::cout << "Invalid option: " << option << std::endl; + break; + } + } + + return 0; +}