Adjustment of RAM and Flash memory

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:

  1. The Application does not use a SoftDevice.
  2. The Application only uses a Master Boot Record (MBR).
  3. The Application uses a SoftDevice.
  4. Change start addresses in Segger Embedded Studio.
  5. Change start addresses in Keil 5.
  6. Change start addresses for the ARM GCC Compiler.
  7. Change start addresses for IAR.
  8. Correct the RAM start address in Segger Embedded Studio.
  9. 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:

  1. Open your project in Segger Embedded Studio

  2. Right click on the Project folder

  3. Select Edit Options...

  4. Select the Common configuration

  5. Click on Linker

  6. Double click on Section Placement Macros

  7. 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

 Select the Common Configuration Double click on Section Placement Macros

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_SIZE=0x100000
RAM_PH_START=0x20000000
RAM_PH_SIZE=0x40000
FLASH_START=0x26000
FLASH_SIZE=0xda000
RAM_START=0x200022B0
RAM_SIZE=0x3dd50

FLASH_PH_START=0x0
FLASH_PH_SIZE=0x100000
RAM_PH_START=0x20000000
RAM_PH_SIZE=0x40000
FLASH_START=0x0
FLASH_SIZE=0x100000
RAM_START=0x20000000
RAM_SIZE=0x40000

 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:

  1. Open the project in Keil 5

  2. Right click on the folder with the board name, i.e nrf52840_xxaa

  3. Select Edit Options for Target ...

  4. Select the Target tab

  5. IROM1 is for FLASH, and IRAM1 is for RAM.

  6. 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:

  1. Open the <project_name>_gcc_nrf52.ld file found in the armgcc folder in your preferred editor.

  2. 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

  3. Save the file after you have modified it.

 Linker script file for armgcc

 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:

 RAM address to low

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:

 RAM to high

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:

  1. Open the project in your preferred IDE.

  2. Open the file nrf_sdh_ble.c

  3. 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.

  4. 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).

  5. Start Debugging, and jump to the breakpoint.

  6. 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.
    RAM start address from debugging

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.