How to Define Variables in On-Chip Standby RAM
In embedded low-power design, Standby RAM is a critical hardware resource that retains data even when the chip enters deep sleep mode. However, many developers struggle to utilize this feature efficiently due to configuration differences across development environments.
This article will use the three mainstream development environments – e2studio (Renesas), KEIL MDK (ARM), and IAR EW (IAR Embedded Workbench) – as examples. We will walk through step-by-step how to achieve the ultimate goal of "precisely allocating variables to Standby RAM" on the Renesas RA6M4 platform. The configuration process described here can be referenced for other Renesas RA series MCU products with built-in Standby RAM, with appropriate modifications based on the hardware manual.
In this example, the Standby RAM has a start address of 0x28000000 and a size of 0x400 bytes (1 KB).
1. In e2studio
1.1 Add the following content to the fsp.ld file to define the Standby RAM region:
1.2 Declare the section_copy function and external variables in “hal_entry.c”.
The section_copy function implements memory data copying.
Add the following content in “R_BSP_WarmStart” to enable Standby RAM and initialize it.
1.3 Build & Debug the project, and open the “Memory” window for verification.
Data that needs to be placed in the Standby RAM region requires a specific declaration. For example:
uint8_t g_standby_ram_variable[512] BSP_PLACE_IN_SECTION(“.standby_ram”) = {0,1,2,3,4,5,6,7,8,9,10};
The image below shows that the data from the array g_standby_ram_variable[512] has been placed in the Standby RAM region.
2. In KEIL MDK
2.1 Open the KEIL MDK project, click “Options for Target”.
On the “Target” tab → “Read/Write Memory Areas”, define a region.
Click the “Linker” tab, uncheck “Use Memory Layout from Target Dialog”, click “Edit...” to customize the linker script.
Define the region in the script, noting that the placement of this defined region in the fsp.scat file must be consistent with the memory map in the hardware manual.
2.2 Define the variable:
uint8_t var00[10] __attribute__((section("SAMPLE_NAME_A")));
2.3 Add the following codes to write data to this variable in your application.
2.4 Build & Debug, then verify.
From the “Memory” window, you can see that the variable placed in the Standby RAM region is written correctly.
3. In IAR EW
3.1 Modify the linker configuration file (.icf).
Define the Standby RAM region and section in the project's linker configuration file:
define region STANDBY_RAM = mem:[from 0x28000000 to 0x280003FF];
define block STANDBY_BLOCK { section .standby_ram };
place in STANDBY_RAM { block STANDBY_BLOCK };
do not initialize { section .standby_ram};
3.2 Declare the variable in code.
Use the “__no_init” keyword and “#pragma location” directive to allocate the variable to the specified section:
#pragma location = ".standby_ram"
__no_init uint8_t g_standby_ram_variable[512];
3.3 Manually initialize and assign values in user codes.
3.4 Build & Debug, then verify.
From the “Memory” window, confirm the variable's address and value.
Through the steps above, we have achieved Standby RAM variable configuration in the three major development environments. Whether you use e2studio, KEIL MDK, or IAR EW, the core logic remains consistent:
- Compiler/Linker Level: Isolate the memory region using the linker script.
- Code Level: Implement conditional initialization based on reset type detection.