mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 05:12:57 +01:00
cpu/cortexm_common: Make Low-Power SRAM available to programs
Many MCUs contain some Backup or Low Power SRAM that is retained'even in the deepest sleep modes. In such sleep modes the MCU is essentually turned off with only the RTC still running. It can be woken by a GPIO or a RTC alarm. When this happens, a reset is triggered and the normal startup routine is invoked. This adds bss & data section for this memory in the linker script. This allows for structures to be placed in it e.g.: e.g.: static uint8_t persistent_buffer[64] __attribute__((section(".backup.bss"))); static uint32_t persistent_counter __attribute__((section(".backup.data"))) = 1234;
This commit is contained in:
parent
c9b827e5d5
commit
2c09d9bd5b
@ -15,6 +15,12 @@ ifneq (,$(ROM_START_ADDR)$(RAM_START_ADDR)$(ROM_LEN)$(RAM_LEN))
|
||||
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_length=$(RAM_LEN)
|
||||
endif
|
||||
|
||||
ifneq (,$(BACKUP_RAM_LEN))
|
||||
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_backup_ram_start_addr=$(BACKUP_RAM_ADDR)
|
||||
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_backup_ram_len=$(BACKUP_RAM_LEN)
|
||||
CFLAGS += -DCPU_HAS_BACKUP_RAM=1
|
||||
endif
|
||||
|
||||
TOOLCHAINS_SUPPORTED = gnu llvm
|
||||
|
||||
# Only define the linker symbol if the variable is set
|
||||
|
@ -24,8 +24,8 @@ INCLUDE cortexm_rom_offset.ld
|
||||
|
||||
MEMORY
|
||||
{
|
||||
rom (rx) : ORIGIN = _rom_start_addr + _rom_offset, LENGTH = _fw_rom_length
|
||||
ram (w!rx) : ORIGIN = _ram_start_addr, LENGTH = _ram_length
|
||||
rom (rx) : ORIGIN = _rom_start_addr + _rom_offset, LENGTH = _fw_rom_length
|
||||
ram (w!rx) : ORIGIN = _ram_start_addr, LENGTH = _ram_length
|
||||
}
|
||||
|
||||
INCLUDE cortexm_base.ld
|
||||
|
@ -34,6 +34,15 @@ SEARCH_DIR(.)
|
||||
/* This is only used by gdb to understand where to start */
|
||||
ENTRY(reset_handler_default)
|
||||
|
||||
_backup_ram_start_addr = DEFINED( _backup_ram_start_addr ) ? _backup_ram_start_addr : 0x0 ;
|
||||
_backup_ram_len = DEFINED( _backup_ram_len ) ? _backup_ram_len : 0x0 ;
|
||||
|
||||
/* not all Cortex-M platforms use cortexm.ld yet */
|
||||
MEMORY
|
||||
{
|
||||
bkup-ram (w!rx) : ORIGIN = _backup_ram_start_addr, LENGTH = _backup_ram_len
|
||||
}
|
||||
|
||||
/* Section Definitions */
|
||||
SECTIONS
|
||||
{
|
||||
@ -159,4 +168,21 @@ SECTIONS
|
||||
/* Populate information about ram size */
|
||||
_sram = ORIGIN(ram);
|
||||
_eram = ORIGIN(ram) + LENGTH(ram);
|
||||
|
||||
_sbackup_data_load = LOADADDR(.backup.data);
|
||||
.backup.data : ALIGN(4) {
|
||||
_sbackup_data = .;
|
||||
*(.backup.data)
|
||||
_ebackup_data = .;
|
||||
/* Round size so that we can use 4 byte copy in init */
|
||||
. = ALIGN(4);
|
||||
} > bkup-ram AT> rom
|
||||
|
||||
.backup.bss (NOLOAD) : ALIGN(4) {
|
||||
_sbackup_bss = .;
|
||||
*(.backup.bss)
|
||||
_ebackup_bss = .;
|
||||
/* Round size so that we can use 4 byte copy in init */
|
||||
. = ALIGN(4);
|
||||
} > bkup-ram
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph_cpu.h"
|
||||
#include "kernel_init.h"
|
||||
#include "board.h"
|
||||
#include "mpu.h"
|
||||
@ -39,6 +40,10 @@
|
||||
#define SRAM_BASE 0
|
||||
#endif
|
||||
|
||||
#ifndef CPU_BACKUP_RAM_NOT_RETAINED
|
||||
#define CPU_BACKUP_RAM_NOT_RETAINED 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Memory markers, defined in the linker script
|
||||
* @{
|
||||
@ -54,6 +59,15 @@ extern uint32_t _sstack;
|
||||
extern uint32_t _estack;
|
||||
extern uint8_t _sram;
|
||||
extern uint8_t _eram;
|
||||
|
||||
/* Support for LPRAM. */
|
||||
#ifdef CPU_HAS_BACKUP_RAM
|
||||
extern const uint32_t _sbackup_data_load[];
|
||||
extern uint32_t _sbackup_data[];
|
||||
extern uint32_t _ebackup_data[];
|
||||
extern uint32_t _sbackup_bss[];
|
||||
extern uint32_t _ebackup_bss[];
|
||||
#endif /* CPU_HAS_BACKUP_RAM */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@ -101,11 +115,30 @@ void reset_handler_default(void)
|
||||
for (dst = &_srelocate; dst < &_erelocate; ) {
|
||||
*(dst++) = *(src++);
|
||||
}
|
||||
|
||||
/* default bss section to zero */
|
||||
for (dst = &_szero; dst < &_ezero; ) {
|
||||
*(dst++) = 0;
|
||||
}
|
||||
|
||||
#ifdef CPU_HAS_BACKUP_RAM
|
||||
if (!cpu_woke_from_backup() ||
|
||||
CPU_BACKUP_RAM_NOT_RETAINED) {
|
||||
|
||||
/* load low-power data section. */
|
||||
for (dst = _sbackup_data, src = _sbackup_data_load;
|
||||
dst < _ebackup_data;
|
||||
dst++, src++) {
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/* zero-out low-power bss. */
|
||||
for (dst = _sbackup_bss; dst < _ebackup_bss; dst++) {
|
||||
*dst = 0;
|
||||
}
|
||||
}
|
||||
#endif /* CPU_HAS_BACKUP_RAM */
|
||||
|
||||
#ifdef MODULE_MPU_STACK_GUARD
|
||||
if (((uintptr_t)&_sstack) != SRAM_BASE) {
|
||||
mpu_configure(
|
||||
|
Loading…
Reference in New Issue
Block a user