The scope of this tutorial is to make it clear how a developer can adjust the RAM and FLASH memory start addresses. The examples demonstrated in this tutorial uses SDK 15.2 The first three Sections explains which RAM and FLASH start addresses should be used under different circumstances. Section 4, 5, and 6 demonstrates how the addresses can be set before compilation. Section 7 shows how the SoftDevice Handler library can be used to find the exact RAM start address required by the Application. The last section demonstrates how the RAM start address can be found during debugging.
For your Application to run correct, the RAM and FLASH start addresses must be correct. There are three things you should consider when you are defining these addresses in your configuration.
- The Application does not use a SoftDevice or a Master Boot Record (MBR)
- The Application only uses a Master Boot Record (MBR)
- The Application uses a SoftDevice
The tutorial have the following table of content:
- The Application does not use a SoftDevice.
- The Application only uses a Master Boot Record (MBR).
- The Application uses a SoftDevice.
- Change start addresses in Segger Embedded Studio.
- Change start addresses in Keil 5.
- Change start addresses for the ARM GCC Compiler.
- Change start addresses for IAR.
- Correct the RAM start address in Segger Embedded Studio.
- Find the RAM start address by debugging.
1. The Application does not use a SoftDevice
If the Application does not use a SoftDevice or a Master Boot Record, then the start address for the FLASH memory should always be set to 0x0 and the start address for the RAM should be set to 0x2000 0000.
2. The Application only uses a Master Boot Record (MBR)
For nRF52 devices, if the Application only uses a Master Boot Record (MBR), then the start address for the FLASH memory should always be set to 0x1000 and the start address for the RAM should be set to 0x2000 0008.
3. The Application uses a SoftDevice
If your Application uses a SoftDevice the start address for the FLASH memory must be set to the correct value for the corresponding SoftDevice, otherwise the Application will not run. This is because the SoftDevice expects the Application to start at one specific address. The RAM start address on the other hand can vary depending on the number of features used in the SoftDevice, but it has always a lowest possible starting address. If you are unsure on what the correct start address for the RAM should be, then it is possible to find this value using SoftDevice Handler library. This will be demonstrated using Segger Embedded Studio Section 7 of this Tutorial.
Table 1 below show different start addresses for RAM and FLASH in some of the different SoftDevice versions. As mentioned above, the value of the start address for RAM is the lowest value possible to set for the Application to run. It may not perform as expected if your SoftDevice uses many features.
SoftDevice |
Version |
Minimum RAM Start |
FLASH start |
S110 |
8.0.0 |
0x20002000 |
0x18000 |
S112 |
5.1.0-2.alpha |
0x20000E98 |
0x19000 |
S112 |
5.1.0 |
0x20000EB8 |
0x18000 |
S112 |
6.0.0 |
0x20000F70 |
0x19000 |
S112 |
6.1.0 |
0x20000F70 |
0x19000 |
S112 |
6.1.1 |
0x20000F70 |
0x19000 |
S112 |
7.0.0 |
0x20000EB8 |
0x19000 |
S113 |
7.0.0 |
0x20001198 |
0x1C000 |
S113 |
7.1.0 |
0x20001198 |
0x1C000 |
S113 |
7.2.0 |
0x20001198 |
0x1C000 |
S120 |
2.0.0 |
0x20002800 |
0x1D000 |
S120 |
2.1.0 |
0x20002800 |
0x1D000 |
S130 |
1.0.0 |
0x20002800 |
0x1C000 |
S130 |
2.0.0-4.alpha |
0x20001268 |
0x1C000 |
S130 |
2.0.0-7.alpha |
0x20001230 |
0x1B000 |
S130 |
2.0.0-8.alpha |
0x200012B8 |
0x1B000 |
S130 |
2.0.0 |
0x200013C8 |
0x1B000 |
S130 |
2.0.1 |
0x200013C8 |
0x1B000 |
S132 |
1.0.0-2.alpha |
0x20002800 |
0x1F000 |
S132 |
1.0.0-3.alpha |
0x20002800 |
0x1F000 |
S132 |
2.0.0-4.alpha |
0x20001268 |
0x1F000 |
S132 |
2.0.0-7.alpha |
0x20001230 |
0x1B000 |
S132 |
2.0.0-8.alpha |
0x200012B8 |
0x1C000 |
S132 |
2.0.0 |
0x200013C8 |
0x1C000 |
S132 |
2.0.1 |
0x200013C8 |
0x1C000 |
S132 |
3.0.0-1.alpha |
0x200010E0 |
0x1D000 |
S132 |
3.0.0-2.alpha |
0x20001660 |
0x1F000 |
S132 |
3.0.0 |
0x200019C0 |
0x1F000 |
S132 |
3.1.0 |
0x200019C0 |
0x1F000 |
S132 |
4.0.0-1.alpha |
0x20001470 |
0x1F000 |
S132 |
4.0.0-2.alpha |
0x20001460 |
0x1F000 |
S132 |
4.0.0 |
0x200013C0 |
0x1F000 |
S132 |
4.0.2 |
0x200013C0 |
0x1F000 |
S132 |
4.0.3 |
0x200013C0 |
0x1F000 |
S132 |
4.0.4 |
0x200013C0 |
0x1F000 |
S132 |
4.0.5 |
0x200013C0 |
0x1F000 |
S132 |
5.0.0-1.alpha |
0x200019C0 |
0x20000 |
S132 |
5.0.0-2.alpha |
0x20001478 |
0x21000 |
S132 |
5.0.0-3.alpha |
0x20001368 |
0x23000 |
S132 |
5.0.0 |
0x200014B8 |
0x23000 |
S132 |
5.0.1 |
0x20001380 |
0x23000 |
S132 |
6.0.0 |
0x20001628 |
0x26000 |
S132 |
6.1.0 |
0x20001628 |
0x26000 |
S132 |
6.1.1 |
0x20001628 |
0x26000 |
S132 |
7.0.0 |
0x20001668 |
0x26000 |
S140 |
5.0.0-1.alpha |
0x200019C0 |
0x21000 |
S140 |
5.0.0-2.alpha |
0x20001468 |
0x21400 |
S140 |
5.0.0-3.alpha |
0x200014B8 |
0x24000 |
S140 |
6.0.0-6.alpha |
0x20001530 |
0x25000 |
S140 |
6.0.0 |
0x20001628 |
0x26000 |
S140 |
6.1.0 |
0x20001628 |
0x26000 |
S140 |
6.1.1 |
0x20001628 |
0x26000 |
S140 |
7.0.0 |
0x20001678 |
0x27000 |
S140 |
7.2.0 |
0x20001678 |
0x27000 |
S212 |
4.0.2 |
0x20000A80 |
0x12000 |
S212 |
5.0.0 |
0x20000B80 |
0x12000 |
S212 |
6.1.1 |
0x20000B80 |
0x12000 |
S312 |
6.1.1 |
0x20001300 |
0x24000 |
S332 |
4.0.2 |
0x20001E30 |
0x29000 |
S332 |
5.0.0 |
0x20001F30 |
0x2D000 |
S332 |
6.1.1 |
0x20002000 |
0x30000 |
S340 |
6.1.1 |
0x20002000 |
0x31000 |
Table 1: Different start addresses for RAM and FLASH memory.
4. Change start addresses in Segger Embedded Studio
Segger Embedded Studio uses Section Placement Macros for defining the RAM and FLASH memory. RAM_START is the macro used for the RAM start address and FLASH_START is the macro used for the FLASH start address. You can easily conyfigure the values in Segger Embedded Studio doing the following steps:
- Open your project in Segger Embedded Studio
- Right click on the Project folder
- Select Edit Options...
- Select the Common configuration
- Click on Linker
- Double click on Section Placement Macros
- The Section Placement Macros window will open:
Edit the values RAM_START and FLASH_START, note that FLASH_SIZE should not be larger than (FLASH_PH_SIZE - FLASH_START), and that (RAM_SIZE + RAM_START) should not be larger than (RAM_PH_START + RAM_PH_SIZE).
When you are finished editing the values, click OK, and Click OK on the Options window
The screenshot on the left shows how to select the Common configuration, the screenshot on the right shows where the Section Placement Macros are found.
In the Table 2 below you can see the different values for the blinky example in SDK 15.2 for the nRF52840 board, with and without a SoftDevice found in Segger Embedded Studio.
blinky example with SoftDevice |
blinky example without SoftDevice and MBR |
FLASH_PH_START=0x0 |
FLASH_PH_START=0x0 |
Table 2: Section Placement Macros in Segger Embedded Studio
5. Change start addresses in Keil 5
Keil 5 does not use Section Placement Macros. In Keil 5 you simply configure the RAM and FLASH memory addresses in the options window for your board.
To edit the start and size of RAM and FLASH in Keil 5:
- Open the project in Keil 5
- Right click on the folder with the board name, i.e nrf52840_xxaa
- Select Edit Options for Target ...
- Select the Target tab
- IROM1 is for FLASH, and IRAM1 is for RAM.
- Edit the values IROM1 Start and IRAM1 Start, note that IROM1 Size should not be larger than (Size of Flash available - IROM1 Start), and that (IRAM1 Size + IRAM1 Start) should not be larger than the size of available RAM.
When you are finished editing the values, click on OK.
Screenshot of the Options for Target window in Keil 5.
6. Change start addresses for the ARM GCC Compiler
The ARM GCC Compiler uses a linker file to store the RAM and FLASH memory addresses.
To edit the start and size of RAM and FLASH the GNU linker file:
- Open the <project_name>_gcc_nrf52.ld file found in the armgcc folder in your preferred editor.
- Located in the linker file is the following code, you have to modify:
FLASH (rx) : ORIGIN = is the FLASH start address, and LENGTH = sets the size of FLASH
RAM (rwx) : ORIGIN = is the RAM start address, and LENGTH = sets the size of RAM - Save the file after you have modified it.
Screenshot of the linker file.
7. Change start addresses for the IAR
To change the start addresses in IAR, just right click on the project in the menu, and click on Options, click on Linker, click on the Config tab, click on Edit... and a new window will open where you click on Memory Regions.
The option ROM is the FLASH memory, and the option RAM is for the RAM.
When you have typed in the values you wanted, click on Save to exit and save the values.
8. Correct the RAM start address in Segger Embedded Studio
The following defines should be set in the sdk_config.h file in your project.
NRF_LOG_BACKEND_RTT_ENABLED 1 NRF_LOG_ENABLED 1 NRF_LOG_DEFAULT_LEVEL 4 NRF_SDH_BLE_LOG_ENABLED 1 NRF_SDH_BLE_LOG_LEVEL 4 NRF_SDH_LOG_ENABLED 1 NRF_SDH_LOG_LEVEL 4
Build your project using the Debug configuration and start debugging by clicking on F5.
If you have set the start address for RAM to low, you will see the following output in the Debug terminal:
You can then adjust the Section Placement Macros as demonstrated in Section 4, to have the correct values.
If you have set the start address for RAM to high, you will see the following output in the Debug terminal:
You can then adjust the Section Placement Macros as demonstrated in Section 4, to have the correct values.
These outputs can also be viewed in J-Link RTT Viewer if you wish to use for example Keil 5 when developing your project.
9. Find the RAM start address by debugging
The RAM start address can also be read out during debugging, by doing the following:
- Open the project in your preferred IDE.
- Open the file nrf_sdh_ble.c
- Add a breakpoint on the following line in the function nrf_sdk_ble_enable:
ret_code_t ret_code = sd_ble_enable(p_app_ram_start);
This can be done by pressing F9 when you mark the line in Segger Embedded Studio and Keil 5. - Add the variable p_app_ram_start to Watch by Right-clicking and select Add 'p_app_ram_start' to Watch, or pressing Ctrl+T, Ctrl+W (This step is only needed in Segger Embedded Studio).
- Start Debugging, and jump to the breakpoint.
- Click on the symbol which the arrows point to and read out the value of the RAM start address. The picture on the Right shows Keil 5, and the picture on the Left shows Segger Embedded Studio.
If you have any more questions related to this topic, please create a ticket in DevZone so that all our community members easily can find the question and answer through searching.
Top Comments