diff --git a/miosix/arch/common/drivers/stm32_sgm.cpp b/miosix/arch/common/drivers/stm32_backup_domain.cpp similarity index 55% rename from miosix/arch/common/drivers/stm32_sgm.cpp rename to miosix/arch/common/drivers/stm32_backup_domain.cpp index 64849679173480fc7788605ce7d3341a756de9e8..b6294fdc185124bfd8665fe4e242a45b9533c93b 100644 --- a/miosix/arch/common/drivers/stm32_sgm.cpp +++ b/miosix/arch/common/drivers/stm32_backup_domain.cpp @@ -23,108 +23,115 @@ * * * You should have received a copy of the GNU General Public License * * along with this program; if not, see <http://www.gnu.org/licenses/> * - ***************************************************************************/ + ***************************************************************************/ -#include "board_settings.h" -#include "stm32_sgm.h" -#include <string.h> -#include "miosix.h" +#include "stm32_backup_domain.h" -namespace miosix { +#include <string.h> -extern unsigned char _preserve_start asm("_preserve_start"); -extern unsigned char _preserve_end asm("_preserve_end"); +#include "board_settings.h" +#include "miosix.h" -static unsigned char *preserve_start=&_preserve_start; -static unsigned char *preserve_end=&_preserve_end; +#if defined(_ARCH_CORTEXM3_STM32F2) || defined(_ARCH_CORTEXM4_STM32F4) +#define PWR_CR1 PWR->CR +#define PWR_CR1_DBP PWR_CR_DBP +#define PWR_CSR1 PWR->CSR +#define PWR_CSR1_BRE PWR_CSR_BRE +#define PWR_CSR1_BRR PWR_CSR_BRR +#define RCC_CSR_IWDGRSTF RCC_CSR_WDGRSTF +#define RCC_CSR_PINRSTF RCC_CSR_PADRSTF +#elif defined(_ARCH_CORTEXM7_STM32F7) +#define PWR_CSR1 PWR->CSR1 +#define PWR_CR1 PWR->CR1 +#endif + +namespace miosix +{ -SGM& SGM::instance() +BackupDomain &BackupDomain::instance() { - static SGM singleton; + static BackupDomain singleton; return singleton; } -SGM::SGM() +void BackupDomain::enable() { - /* Enable PWR clock */ + // Enable PWR clock RCC->APB1ENR |= RCC_APB1ENR_PWREN; - - /* Enable backup SRAM Clock */ - RCC->AHB1ENR |= RCC_AHB1ENR_BKPSRAMEN; - - enableWrite(); - /* Enable Backup regulator */ - PWR->CSR |= PWR_CSR_BRE; - - /* Enable the Backup SRAM low power Regulator */ - PWR->CSR |= PWR_CSR_BRE; - - /* Wait for backup regulator */ - while (!(PWR->CSR & (PWR_CSR_BRR))); + // Enable access to the backup domain + PWR_CR1 |= PWR_CR1_DBP; +} - /* Retrive last reset reason and clear the pending flag */ - readResetRegister(); +void BackupDomain::disable() +{ + // Disable PWR clock + RCC->APB1ENR &= ~RCC_APB1ENR_PWREN; - /* - * If the reset wasn't caused by software failure we cannot trust - * the content of the backup memory and we need to clear it. - */ - if(lastReset != RST_SW) - { - memset(preserve_start, 0, preserve_end-preserve_start); - } + // Disable access to the backup domain + PWR_CR1 &= ~PWR_CR1_DBP; } -void SGM::disableWrite() +void BackupDomain::enableBackupSRAM() { - /* Enable Backup Domain write protection */ - PWR->CR &= ~PWR_CR_DBP; + // Enable backup SRAM Clock + RCC->AHB1ENR |= RCC_AHB1ENR_BKPSRAMEN; + + // Enable Backup regulator + PWR_CSR1 |= PWR_CSR1_BRE; } -void SGM::enableWrite() +void BackupDomain::disableBackupSRAM() { - /* Disable Backup Domain write protection */ - PWR->CR |= PWR_CR_DBP; + // Disable backup SRAM Clock + RCC->AHB1ENR &= ~RCC_AHB1ENR_BKPSRAMEN; + + // Disable Backup regulator + PWR_CSR1 &= ~PWR_CSR1_BRE; } -void SGM::clearResetFlag() +BackupDomain::BackupDomain() { - RCC->CSR |= RCC_CSR_RMVF; + // Retrive last reset reason and clear the pending flag + readResetRegister(); } -void SGM::readResetRegister() +void BackupDomain::clearResetFlag() { RCC->CSR |= RCC_CSR_RMVF; } + +void BackupDomain::readResetRegister() { uint32_t resetReg = RCC->CSR; + clearResetFlag(); - if(resetReg & RCC_CSR_LPWRRSTF) + + if (resetReg & RCC_CSR_LPWRRSTF) { - lastReset = RST_LOW_PWR; + lastReset = ResetReason::RST_LOW_PWR; } - else if( resetReg & RCC_CSR_WWDGRSTF) + else if (resetReg & RCC_CSR_WWDGRSTF) { - lastReset = RST_WINDOW_WDG; + lastReset = ResetReason::RST_WINDOW_WDG; } - else if( resetReg & RCC_CSR_WDGRSTF) + else if (resetReg & RCC_CSR_IWDGRSTF) { - lastReset = RST_INDEPENDENT_WDG; + lastReset = ResetReason::RST_INDEPENDENT_WDG; } - else if( resetReg & RCC_CSR_SFTRSTF) + else if (resetReg & RCC_CSR_SFTRSTF) { - lastReset = RST_SW; + lastReset = ResetReason::RST_SW; } - else if( resetReg & RCC_CSR_PORRSTF) + else if (resetReg & RCC_CSR_PORRSTF) { - lastReset = RST_POWER_ON; + lastReset = ResetReason::RST_POWER_ON; } - else if( resetReg & RCC_CSR_PADRSTF) + else if (resetReg & RCC_CSR_PINRSTF) { - lastReset = RST_PIN; + lastReset = ResetReason::RST_PIN; } else { - lastReset = RST_UNKNOWN; + lastReset = ResetReason::RST_UNKNOWN; } } -} // namespace miosix +} // namespace miosix diff --git a/miosix/arch/common/drivers/stm32_sgm.h b/miosix/arch/common/drivers/stm32_backup_domain.h similarity index 67% rename from miosix/arch/common/drivers/stm32_sgm.h rename to miosix/arch/common/drivers/stm32_backup_domain.h index 10cc6dc9d9fe875f055e20011b7e055e6215e9d8..82fb9b8a8779d6fbc7bde15d577838d2a3d9f791 100644 --- a/miosix/arch/common/drivers/stm32_sgm.h +++ b/miosix/arch/common/drivers/stm32_backup_domain.h @@ -23,53 +23,62 @@ * * * You should have received a copy of the GNU General Public License * * along with this program; if not, see <http://www.gnu.org/licenses/> * - ***************************************************************************/ - + ***************************************************************************/ + #include "board_settings.h" -#define PRESERVE __attribute__((section(".preserve"))) +#define PRESERVE __attribute__((section(".preserve"))) -namespace miosix { +namespace miosix +{ /** * Possible causes for an STM32 reset */ -enum ResetReason +enum class ResetReason { - RST_LOW_PWR=0, - RST_WINDOW_WDG=1, - RST_INDEPENDENT_WDG=2, - RST_SW=3, - RST_POWER_ON=4, - RST_PIN=5, - RST_UNKNOWN=6, + RST_LOW_PWR = 0, // Low power + RST_WINDOW_WDG = 1, // Reset from the windows watchdog + RST_INDEPENDENT_WDG = 2, // Reset from the independent watchdog + RST_SW = 3, // Sofware reset + RST_POWER_ON = 4, // System power on + RST_PIN = 5, // Reset pin + RST_UNKNOWN = 6, // Unknown }; /** - * Driver for the STM32F2 and STM32F4 backup SRAM, here used as - * SafeGuard Memory, that is, a memory whose value is preseved across resets. + * Driver for the backup SRAM. + * + * @warning Tested only on stm32f2, stm32f4 and stm32f7 microcontrollers. */ -class SGM +class BackupDomain { public: /** - * \return an instance of this class (singleton) + * @return An instance of this class (singleton). + */ + static BackupDomain& instance(); + + /** + * Enables the backup domain clock and write access. */ - static SGM& instance(); + void enable(); /** - * Temporarily disable writing to the safeguard memory. - * By deafult, from reset to when the contrsuctor of this class is called - * the safeguard memory is not writable. After the constructor is called, - * the safeguard memory is writable. + * Disable the backup domain clock and write access. */ - void disableWrite(); + void disable(); /** - * Make the safeguard memory writable again, after a call to disableWrite() + * Enable the backup SRAM. */ - void enableWrite(); - + void enableBackupSRAM(); + + /** + * Disable the backup SRAM. + */ + void disableBackupSRAM(); + /** * Return the cause of the last reset of the microcontroller */ @@ -78,14 +87,12 @@ public: private: ResetReason lastReset; - SGM(const SGM&)=delete; - SGM& operator=(const SGM&)=delete; + BackupDomain(const BackupDomain&) = delete; + BackupDomain& operator=(const BackupDomain&) = delete; - SGM(); + BackupDomain(); void readResetRegister(); void clearResetFlag(); - }; - -} \ No newline at end of file +} // namespace miosix \ No newline at end of file diff --git a/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/interfaces-impl/bsp.cpp b/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/interfaces-impl/bsp.cpp index ae4216e00a850137aed771eb940d9a1ac1880158..30f6b33ad960b7b18146cb756c11de712656c27d 100644 --- a/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/interfaces-impl/bsp.cpp +++ b/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/interfaces-impl/bsp.cpp @@ -42,6 +42,7 @@ #include "drivers/sd_stm32f2_f4_f7.h" #include "drivers/serial.h" #include "drivers/serial_stm32.h" +#include "drivers/stm32_backup_domain.h" #include "filesystem/console/console_device.h" #include "filesystem/file_access.h" #include "interfaces/arch_registers.h" @@ -235,6 +236,37 @@ void bspInit2() { #ifdef WITH_FILESYSTEM basicFilesystemSetup(SDIODriver::instance()); #endif // WITH_FILESYSTEM + + #ifdef WITH_BACKUP_SRAM + BackupDomain::instance().enable(); + BackupDomain::instance().enableBackupSRAM(); + #endif + + // Print the reset reason + bootlog("Reset reson: "); + switch(BackupDomain::instance().lastResetReason()) { + case ResetReason::RST_LOW_PWR: + bootlog("low power\n"); + break; + case ResetReason::RST_WINDOW_WDG: + bootlog("window watchdog\n"); + break; + case ResetReason::RST_INDEPENDENT_WDG: + bootlog("indeendent watchdog\n"); + break; + case ResetReason::RST_SW: + bootlog("software reset\n"); + break; + case ResetReason::RST_POWER_ON: + bootlog("power on\n"); + break; + case ResetReason::RST_PIN: + bootlog("reset pin\n"); + break; + case ResetReason::RST_UNKNOWN: + bootlog("unknown\n"); + break; + } } // diff --git a/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/stm32_2m+384k_ram.ld b/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/stm32_2m+384k_ram.ld index b38e3ac5433159c0cc84abfd5d4ae5ab3b8b7896..497bd5198760b9637c774bf3900fd9dfbc01a2b2 100644 --- a/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/stm32_2m+384k_ram.ld +++ b/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/stm32_2m+384k_ram.ld @@ -61,6 +61,7 @@ MEMORY { sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M } @@ -175,4 +176,14 @@ SECTIONS _end = .; PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram } diff --git a/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/stm32_2m+8m_xram.ld b/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/stm32_2m+8m_xram.ld index 2213d451b3451983d09008fdef712a45ed1cfbb1..50a2e68efc3681c04e5bf2767fa52e2f5f96b51f 100644 --- a/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/stm32_2m+8m_xram.ld +++ b/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit/stm32_2m+8m_xram.ld @@ -62,6 +62,7 @@ MEMORY xram(wx) : ORIGIN = 0xd0000000, LENGTH = 8M sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M } @@ -176,4 +177,14 @@ SECTIONS _end = .; PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram } diff --git a/miosix/config/miosix_settings.h b/miosix/config/miosix_settings.h index 6a77af2f819c2e802aa3fd595569698b4fbda2be..029a536f323da2f093f7d2d6a309771b2420b114 100644 --- a/miosix/config/miosix_settings.h +++ b/miosix/config/miosix_settings.h @@ -137,7 +137,9 @@ const unsigned char MAX_OPEN_FILES=8; /// By default it is defined (error information is printed) #define WITH_ERRLOG - +/// \def WITH_SGM +/// Uncomment to enable the Backup SRAM at boot. +#define WITH_BACKUP_SRAM // // Kernel related options (stack sizes, priorities) diff --git a/miosix/config/options.cmake b/miosix/config/options.cmake index 9e9b650d589063615afb8a497ed285da5227110c..e62c9c413b834971d01e94a24e911b93e5b903ab 100644 --- a/miosix/config/options.cmake +++ b/miosix/config/options.cmake @@ -2024,7 +2024,7 @@ elseif(${ARCH} STREQUAL cortexM4_stm32f4) set(ARCH_SRC ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp - ${KPATH}/arch/common/drivers/stm32_sgm.cpp + ${KPATH}/arch/common/drivers/stm32_backup_domain.cpp ${KPATH}/arch/common/drivers/stm32_wd.cpp ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp ) @@ -2127,7 +2127,7 @@ elseif(${ARCH} STREQUAL cortexM4_stm32f4) set(ARCH_SRC ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp - ${KPATH}/arch/common/drivers/stm32_sgm.cpp + ${KPATH}/arch/common/drivers/stm32_backup_domain.cpp ${KPATH}/arch/common/drivers/stm32_wd.cpp ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp ) @@ -2292,7 +2292,7 @@ elseif(${ARCH} STREQUAL cortexM4_stm32f4) set(ARCH_SRC ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp - ${KPATH}/arch/common/drivers/stm32_sgm.cpp + ${KPATH}/arch/common/drivers/stm32_backup_domain.cpp ${KPATH}/arch/common/drivers/stm32_wd.cpp ${KPATH}/arch/common/drivers/servo_stm32.cpp ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp @@ -2328,7 +2328,7 @@ elseif(${ARCH} STREQUAL cortexM4_stm32f4) set(ARCH_SRC ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp - ${KPATH}/arch/common/drivers/stm32_sgm.cpp + ${KPATH}/arch/common/drivers/stm32_backup_domain.cpp ${KPATH}/arch/common/drivers/stm32_wd.cpp ${KPATH}/arch/common/drivers/servo_stm32.cpp ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp @@ -2364,7 +2364,7 @@ elseif(${ARCH} STREQUAL cortexM4_stm32f4) set(ARCH_SRC ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp - ${KPATH}/arch/common/drivers/stm32_sgm.cpp + ${KPATH}/arch/common/drivers/stm32_backup_domain.cpp ${KPATH}/arch/common/drivers/stm32_wd.cpp ${KPATH}/arch/common/drivers/servo_stm32.cpp ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp @@ -2400,7 +2400,7 @@ elseif(${ARCH} STREQUAL cortexM4_stm32f4) set(ARCH_SRC ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp - ${KPATH}/arch/common/drivers/stm32_sgm.cpp + ${KPATH}/arch/common/drivers/stm32_backup_domain.cpp ${KPATH}/arch/common/drivers/stm32_wd.cpp ${KPATH}/arch/common/drivers/servo_stm32.cpp ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp @@ -2535,7 +2535,7 @@ elseif(${ARCH} STREQUAL cortexM4_stm32f4) set(ARCH_SRC ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp - ${KPATH}/arch/common/drivers/stm32_sgm.cpp + ${KPATH}/arch/common/drivers/stm32_backup_domain.cpp ${KPATH}/arch/common/drivers/stm32_wd.cpp ${KPATH}/arch/common/drivers/servo_stm32.cpp ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp @@ -3141,7 +3141,10 @@ elseif(${ARCH} STREQUAL cortexM7_stm32f7) ## Select architecture specific files ## These are the files in arch/<arch name>/<board name> - set(ARCH_SRC ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp) + set(ARCH_SRC + ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/drivers/stm32_backup_domain.cpp + ) ## Add a #define to allow querying board name list(APPEND CFLAGS_BASE -D_BOARD_STM32F767ZI_COMPUTE_UNIT)