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):

  • I have now tried SEGGER Embedded Studio (3.10f) on macOS, and I experience the same issue as @syntroniks when I import an example project from the SDK (12.1.0). It seems SES for some reason is not able to find the nRF52832_xxAA as target processor and because of that wrong files and settings are added to the project. There's an underlying problem with project imports on macOs in there somewhere causing this, so if someone has figured out what it is and how to fix it, please comment.

    Here is what I did to get the examples working after the unsuccessful import, in addition to what is described in this tutorial:

    • Install the nRF CPU Support Package (along with the already installed CMSIS-CORE support package) Tools -> Package manager -> Install nRF CPU Support Package

    • Import the project. Remove crt0.s and ARM_Startup.s from Internal files folder in project explorer.

    • Add <your SES folder>/source/thumb_crt0.s to Internal files.

    • Go to Project -> Edit options... -> (General tab) Build -> Property Groups File and add the path $(PackagesDir)/nRF/XML/property_groups.xml

    • Click Ok for the previous step to take effect

    • Go to Project -> Edit options... -> (General tab) Build -> Target Processor and select nRF52832_xxAA as target

    • Go to Project -> Edit options... -> (Linker tab) Linker -> Section Placement File and add $(StudioDir)/targets/Cortex_M/flash_placement.xml

    The project should now build. To flash it to the DevKit, confirm the following:

    • Project -> Edit options... -> (Debugging tab) J-Link -> Target Interface Type should be set to SWD
  • Hi, If you're having trouble getting the blinky (or other examples) to work, you can try to set the SRAM start value slightly higher. For the experimental blinky example in SDK v12.1, the following works for me: SRAM_START=0x20002600

  • Has anyone tried blinky example using this method, when i dump into the nRF52-DK it is not advertising. what may be the reason?

  • Thanks for a great tutorial, Michael! Programming the ble_app_beacon works for me. However, when I try to program another project, the ble_app_uart, using this same tutorial, I can't make it work. I've commented out FILE stdout and FILE stdin in retarget.c. I'm able to build, run, and go through debugging without any errors, but the LED on my dev kit is not flashing, nor can I discover a bluetooth device with the nRF Toolbox app. How do I make it work?

  • Seems like a really nice IDE. It was really easy to jump into business. Keil (and IAR) should pay heed... :) Not that I've had problems running things with Keil, but the clarity and usability feels much better with SES. Also the absence of limitations for non-commercial projects will do wonders for gaining traction methinks.

    Random quick note: If you have a file selected in Project Explorer and select Project -> Edit Options... from the toolbar, the options will be opened for the selected file, not the project. Of course this is apparent since it will read File '<filename>' Options instead of Project '<prjname>' Options in the menu, but it managed to throw me off for a little while since I fully expected **Project** -> Edit Options... to always open the entire Project's settings.