This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Flash SoftDevice and then an app using JLink?

Hello everyone,

Please forgive my continued naive questions. This is my first embedded-systems project.

I have been working with an nRF52 development board and SDK 0.9.1 for several weeks. I have applications talking to the USB interface. My development environment is pure Linux. I am running GCC ARM Embedded, and SEGGER JLink, from the command line. Notice, I don't have access to the Windows-based nrfjprog, so I can't use the parts of the Nordic-supplied makefiles which flash the board.

Now my boss wants me to get the device talking over Bluetooth. I tried compiling the ble_app_beacon and flashing it to the board the way I have done with USB-based apps. I have an Apple laptop scanning for Bluetooth devices. It sees other Bluetooth devices, but it's not seeing my nRF52 board. After doing a little reading, I believe that I skipped a step. I should flash the board with the S132 SoftDevice .hex file first. Then I should flash the board with my app, making sure not to over-write the SoftDevice.

I know how to change the address of the starting flash memory location with JLink, but I have never flashed any memory location other than 0. How do I choose where to flash the SoftDevice, and where to flash my application? I can't imagine that those locations can be arbitrary. There must be a defined execution start address. Without linking the app to the SoftDevice at compile time, the app still must know where the SoftDevice resides in memory in order to call it (which I think it would have to do at least once for setup purposes, even if everything is handled by interrupts after that?).

I am aware of github.com/.../nrf51-pure-gcc-setup. I have learned quite a few things from reading through the files there. But some parts of it are out of date, particularly the parts which refer to a toolchain called ELF (which was apparently succeeded by GCC ARM Embedded). The parts of those makefiles which compute memory locations, flash the SoftDevice, and then flash the app, depend on ELF.

Thanks for your help!

  • The softdevice goes at 0x00000000 and your code is flashed at whatever the correct code address is for the softdevice you're using, which is in the softdevice spec. It's the address you built the code to run at. In the case of the S132 V1 alpha that's 0x1f000. That address is in the ble_app_beacon_gcc_nrf52.ld file you used to build the code.

    And you have it backwards, the softdevice, which is at 0x00000000 is the code the chip starts running on boot, because that's where the default vector table is. When it's set itself up, it reads the vector table at 0x1f000, the defined address for your user code, and jumps to the reset_handler who's address is at 0x1f004. The user code never really calls the softdevice except via SVC calls which are handled by the softdevice's SVC interrupt handler.

  • Thanks for your reply, RK. I believe that I flashed the S132 SoftDevice .hex file to 0x0, and the Beacon app to 0x1F000, but I've seen nothing so far.

    Upon doing some further reading, I can see that a "beacon" means something very specific in Bluetooth terms. I believe that I am only interested in my nRF52 board "advertising" its existence at this stage. I have also tried to compile and flash ble_app_template as above. I am still not seeing anything.

    I am currently seeking to modify ble_app_template to show that it's actually running (adding some blinking LEDs, or SEGGER RTT output to the USB port).

  • Here is a modestly-abbreviated transcript of my JLink session:


    BashPrompt$ JLinkExe -device nRF52

    SEGGER J-Link Commander V5.02c ('?' for help)

    [...]

    Cortex-M4 identified.

    Target interface speed: 100 kHz

    J-Link>loadfile s132_nrf52_softdevice.hex 0 [yes, I shortened the SoftDevice file name]

    [no errors]

    J-Link>loadfile ble_app_template_s132.bin 0x1f000

    [no errors]

    J-Link>r

    [no errors]

    J-Link>go

    [no errors]


    Nothing ever happens.

    I have a modified ble_app_template which includes SEGGER_WriteString statements. They should print to JLinkRTTClient when main() first starts, and when it's about to enter the power management loop. Nothing prints. My other applications which talk to JLinkRTTClient are working fine.

    This makes me think that the SoftDevice is never jumping to my application's own code.

  • As long as you compiled the code for 0x1f000, that's the correct sequence for getting the softdevice and code onto the chip. Do you have a better way of debugging than RTT and JLink, even gdbserver is better than that.

    If not then try ```halt,regs`` to see where you've ended up. Or set a breakpoint in your code using JLink.

  • Hi, RK, thanks for staying with me. I did not modify the Nordic linker files for the applications in any way. Apps which don't use a SoftDevice (at least, the ones I have looked at) are allocated memory as follows:


    SEARCH_DIR(.)

    GROUP(-lgcc -lc -lnosys)

    MEMORY

    {

    FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000

    RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000

    }

    INCLUDE "nrf5x_common.ld"


    And the BLE apps linker files look like this:


    SEARCH_DIR(.)

    GROUP(-lgcc -lc -lnosys)

    MEMORY

    {

    FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000

    RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x5800

    }

    INCLUDE "nrf5x_common.ld"


    Concerning debugging: as I mentioned, I'm new to embedded systems. I haven't even needed a debugger yet, although I planned to use gdb. I will investigate the registers as you suggested.

Related