Segger Embedded Studio - A Cross Platform IDE

Download and Setup

Note: It is recommended, but not necessary, to use the most recent releases of the above software.

Importing a Keil uVision project

Note: From nRF5 SDK v14.1, Segger Embedded studio projects are officially supported. If using v14.1 or newer, please use the native SES-projects instead of the "import" function.

  • Open SEGGER Embedded Studio 3.10e
  • Select Tools -> Package Manager... and install the CMSIS-CORE Support Package

image description

  • Select File -> Import IAR EWARM / Keil MDK Project...
  • Navigate to your local nRF5 SDK and in NRF5_SDK/examples/ble_peripheral/ble_app_beacon/ select pca10040/s132/arm5_no_packs/ble_app_beacon_pca10040_s132.uvprojx
  • The Import Build Configuration window will pop-up. Make sure you select to use Embedded Studio's Internal Toolchain (GCC/Clang) for now...

image description

Nuances

If you've used Keil uVision with Nordic's SDK before, you might remember that each example BLE project contains a dummy project configuration for easy flashing of the SoftDevice. We don't need this in Embedded Studio and it can cause confusion so let's delete it.

  • Select Project -> Build Configurations... and under Public Configurations select flash_s132_nrf52_3.0.0_softdevice and delete it by clicking the - symbol in the upper right-hand corner of the pop-up window.

Your build configurations should look like this now:

image description

And your project explorer:

image description

Adding nRF5 MDK Files

Keil uVision uses Device packs for Startup/System Setup. This pack contains the nRF5 startup assembly files arm_startup_nrf52.s and the system setup files system_nrf52.c along with some header files. We will need to manually add these files to our Embedded Studio project.

  • Download ses_nrf51_startup.s and ses_nrf52_startup.s and save them into NRF5_SDK/components/toolchain/embedded_studio/ (create the folder)
  • Remove Cortex_M_Startup.s from the Internal Files folder in the Project Explorer
  • Right click the Internal Files folder and select Add Existing File...
  • In NRF5_SDK/components/toolchain/ select system_nrf52.c
  • Do the same for NRF5_SDK/components/toolchain/embedded_studio/ses_nrf52_startup.s

Your project explorer should look like this now:

image description

  • Select Project -> Edit Options... and then select the Preprocessor tab
  • Add ../../../../../../components/device to the User Include Directories field to include the device header files in our Embedded Studio project

Your user include directories should look like this now:

image description

Peer Manager/Flash Data Storage

Most of the examples in the SDK use Peer Manager. Peer Manager uses Flash Data Storage and Flash Storage. To indicate where information from Peer Manager (e.g bonding information) should be store page tags in flash (section variables) is used. These page tags need to be written to flash. To do so, flash_placement.xml and thumb_crt0.s have to be added and modified. Thanks to @RK and @Håkon Alseth in this post.

Flash_placement.xml can be located in the project folder, for example: ..\nRF5_SDK_xxx\examples\ble_peripheral\ble_app_gls\pca10040\s132\arm5_no_packs

You have to generate flash_placement.xml using text editor, notepad for example. After that you can import it by right click on the project name and choose "Import Section placement"

==========

For SDK v14 please use these updated files:

flash_placement.xml

thumb_crt0.s

==========

flash_placement.xml should then look like the following (SDK 12):

<!DOCTYPE Linker_Placement_File>
<Root name="Flash Section Placement">
  <MemorySegment name="$(FLASH_NAME:FLASH)">
    <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START:)" />
    <ProgramSection alignment="4" load="Yes" name=".init" />
    <ProgramSection alignment="4" load="Yes" name=".init_rodata" />
    <ProgramSection alignment="4" load="Yes" name=".text" />
    <ProgramSection alignment="4" load="Yes" name=".dtors" />
    <ProgramSection alignment="4" load="Yes" name=".ctors" />
    <ProgramSection alignment="4" load="Yes" name=".rodata" />
    <ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
    <ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
    <ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
    <ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" runin=".fs_data_run" name=".fs_data" />
  </MemorySegment>
  <MemorySegment name="$(RAM_NAME:RAM);SRAM">
    <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START:$(SRAM_START:))" />
    <ProgramSection alignment="4" load="No" name=".fast_run" />
    <ProgramSection alignment="4" load="No" name=".data_run" />
    <ProgramSection alignment="4" load="No" name=".tdata_run" />
    <ProgramSection alignment="4" load="No" keep="Yes" name=".fs_data_run" address_symbol="__start_fs_data" end_symbol="__stop_fs_data" />
    <ProgramSection alignment="4" load="No" name=".bss" />
    <ProgramSection alignment="4" load="No" name=".tbss" />
    <ProgramSection alignment="4" load="No" name=".non_init" />
    <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
    <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack" />
    <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
  </MemorySegment>
  <MemorySegment name="$(FLASH2_NAME:FLASH2)">
    <ProgramSection alignment="4" load="Yes" name=".text2" />
    <ProgramSection alignment="4" load="Yes" name=".rodata2" />
    <ProgramSection alignment="4" load="Yes" runin=".data2_run" name=".data2" />
  </MemorySegment>
  <MemorySegment name="$(RAM2_NAME:RAM2)">
    <ProgramSection alignment="4" load="No" name=".data2_run" />
    <ProgramSection alignment="4" load="No" name=".bss2" />
  </MemorySegment>
</Root>

Thumb_crt0.s is located in the Segger Embedded studio install folder: ..\SEGGER\SEGGER Embedded Studio <v. xx>\source

In thumb_crt0.s, fs_data should be added, it can be added after tdata (thanks to @RK):

ldr r2, =__tdata_end__
bl memory_copy
# ADD HERE ... 
ldr r0, =__fs_data_load_start__
ldr r1, =__fs_data_start__
ldr r2, =__fs_data_end__
bl memory_copy
# TO HERE ...

Building

Our project should build successfully now:

  • Build the project by selecting Build -> Build ble_app_beacon_pca10040_s132 or by simply hitting F7

image description

Notice that the compiled binary is placed at the beginning of FLASH and SRAM. This project requires a SoftDevice so let's reserve the correct amount of room for it.

  • Select Project -> Edit Options... and then select the Linker tab
  • Paste the following into the Section Placement Macros field (SDKv12):

FLASH_START=0x1F000
SRAM_START=0x20002000

Your Project Options should look like this now:

image description

  • Re-build the project by selecting Build -> Rebuild ble_app_beacon_pca10040_s132 or by simply hitting Alt + F7

Now you should see that space has been reserved in FLASH and SRAM for the SoftDevice:

image description

Fine-Tuning

  • Select Project -> Edit Options... and then select the Preprocessor tab
  • Add the definition NO_VTOR_CONFIG to the Preprocessor Definitions field (this tells Embedded Studio to expect a SoftDevice to be present and that it will forward exceptions/interrupts to the application)

Your Preprocessor Definitions should look like this now:

image description

Flashing the SoftDevice with our application

  • Select Project -> Edit Options... and then select the Loader tab
  • Add the absolute path to the SoftDevice NRF5_SDK/components/softdevice/s132/hex/s132_nrf52_3.0.0_softdevice.hex to the Additional Load File[0] field

Your Loader options should look like this now:

image description

Running

  • Connect your nRF5 Development Kit to your computer and turn it on
  • Run the application by selecting Debug -> Build and Run or hitting Ctrl + F5

Your Output log should look like this now:

image description

The application should be running on your nRF5 DK and LED1 should be blinking. You should be able to scan for and find the beacon using nRF Connect.

Debugging

  • Select Debug -> Go or simply hit F5

You should see that you have entered the debugging interface now:

image description

Notice that our application has ran until the first line in main() and is halted. You should experiment with debugging in Embedded Studio. It has all the debugging features you would expect from a professional IDE and more (makes sense as SEGGER makes the debuggers as well).

Peer manager

To make peer manager (SDK 10(?), SDK 11, SDK 12) work with Segger Embedded Studio the modifications in this post are needed.

Troubleshooting

If you are stuck, previous blog posts (although deprecated) may help you fix your problem (also see the questions section):

  • @Michael: thanks for that. I missed that one line in the instructions. Now it gets past that error and I can build the Beacon project.

    Now I am trying to build the HRS project because that is closer to what I want to start with and I get 8 linker errors. Please advise:

    Output/nrf52832_xxaa/Exe/ble_app_hrs_pca10040_s132.elf section `.fs_data' will not fit in region `UNPLACED_SECTIONS'
    region `UNPLACED_SECTIONS' overflowed by 17 bytes
    Output/ble_app_hrs_pca10040_s132 nrf52832_xxaa/Obj/fstorage.o: In function `check_config':
    undefined reference to `__start_fs_data'
    undefined reference to `__stop_fs_data'
    Output/ble_app_hrs_pca10040_s132 nrf52832_xxaa/Obj/fstorage.o: In function `fs_init':
    undefined reference to `__stop_fs_data'
    undefined reference to `__start_fs_data'
    

    Build failed

  • @Tony: you need to add the system_nrf52.c file to your project. This usually goes under the Internal Files directory in the project explorer.

  • I am trying to get Segger Studio 3.10h going. I have followed the main instructions and the comment instructions.

    I get a linker error: undefined reference to `SystemCoreClock'

  • In case someone want to use SES to build the IoT SDK examples you have to edit the below settings in addition to the steps in the blog post above

    1. Edit MBEDTLS_CONFIG_FILE=<nrf_tls_config.h> under Preprocessor Definitions to `MBEDTLS_CONFIG_FILE="nrf_tls_config.h". (Only applicable to the examples that use TLS, e.g. MQTT)

    2. Add ../../../../../../../../components/iot/ble_6lowpan/lib/ble_6lowpan.a under Linker-> Set Additional Input files

    3.  Set ARM FP ABI Type to Hard under C/C++ -> Code Generation
      
  • It is quite complicated to build a project using peer manager due to flah storage module and section variables. There are some answers to those problems in the devzone forums area, it would be great to improve this tutorial with this, because with SDK12 peer manager is quite mandatory and code size limited environments cannot be used as soon as you have a little bit of code. see this post : devzone.nordicsemi.com/.../