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;
+}