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

SDK 12.3.0 blinky example GCCARM on nrf51822

Hello,

Two years ago I develop a board with a nrf51822. Right now I'm trying to use the same board again. I installed the new SDK 12.3.0, GCC ARM, nrf command line tools and JLink to setup the development environment on OSX.

I got no problems on compile the blinky (I choose PCA10028 board) example and flash it (make flash) to the board however it looks like the CPU is not running.

The blinky example is set up for nrf51422 so I change the makefile for nrf51822 but the problem persist.

Reboot my PC on windows, installed keil 5 and SDK10, that time I build the blinky example for board PCA20006, load it with keil to board and it worked. EDIT: download the SDK12.3.0 on windows open the same blinky example on keil, flashed and it worked. So it is a problem with armgcc. I'm using the following version: gcc-arm-none-eabi-4_9-2015q3

Reboot again into OSX, start the GDB server:

JLinkGDBServer -family nrf51 -device nrf51822 -if SWD

Run the arm gdb:

./arm-none-eabi-gdb
target extended-remote :2331
break main
monitor reset

on the JLink window I can see Starting CPU... but it doesn't stop at main...

What should I do debug the problem?

some gdb output:

(gdb) monitor reset
Resetting target
(gdb) c
Continuing.

Breakpoint 1, 0x00001366 in HardFault_Handler ()
(gdb) bt
#0  0x00001366 in HardFault_Handler ()
#1  <signal handler called>
#2  0x00000000 in __isr_vector ()
#3  0x00000000 in ?? ()
(gdb) info register
r0             0x0	0
r1             0x1540	5440
r2             0x20000000	536870912
r3             0x0	0
r4             0xffffffff	4294967295
r5             0xffffffff	4294967295
r6             0xffffffff	4294967295
r7             0xffffffff	4294967295
r8             0xffffffff	4294967295
r9             0xffffffff	4294967295
r10            0xffffffff	4294967295
r11            0xffffffff	4294967295
r12            0xffffffff	4294967295
sp             0x20007fe0	0x20007fe0
lr             0xfffffff9	4294967289
pc             0x1366	0x1366 <HardFault_Handler>
xpsr           0x61000003	1627389955
msp            0x20007fe0	536903648
psp            0xfffffffc	4294967292
primask        0x0	0
basepri        0x0	0
---Type <return> to continue, or q <return> to quit---
faultmask      0x0	0
control        0x0	0
(gdb) 
  • It looks like you are using the xxAA or xxAB variant of the 51 which has 16K of RAM, whereas the new SDK examples are configured for the xxAC with 32K of RAM (IC overview). If that's the case you will need to adjust RAM size in your linker configuration .

    Example of a typical memory layout for the nRF51x22_xxAC (256/32) variant:

    MEMORY
    {
     /*FLASH and RAM ORIGIN depends on softdevice series and version. Check SD release                                 notes for appropriate values. Set ORIGIN to 0x0 and 0x20000000 for examples that do not run on top of softdevice stack or similar */
      FLASH (rx) : ORIGIN = 0x1B000, LENGTH = 0x25000 
      RAM (rwx) :  ORIGIN = 0x20002000, LENGTH = 0x6000
    }
    

    And the same for nRF51x22_xxAA (256/16). Note that RAM ORIGIN + LENGTH must not exceed 0x20004000:

    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x1B000, LENGTH = 0x25000
      RAM (rwx) :  ORIGIN = 0x20002000, LENGTH = 0x2000
    }
    
  • A pretty good hint in the register dump that that's the case is

    msp            0x20007fe0   536903648
    

    That probably means the MSP was set to 0x20008000. The first attempted push onto the stack would have failed as it wouldn't be able to write, so the hardfault has been called which has then attempted to push the register on the stack and so the MSP now says 0x20007fe0.

    If you actually go and look at the contents of memory at the MSP, which you'd usually do to work out where you came from, you'll probably find it's either unreadable or all 0xffffffff

  • I'm indeed using a xxAA variant. I'll try it tonight, thank you :)

  • Change the the RAM lenght to RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x4000 instead of 0x8000. For some reason I thought the error will only happen if I use enough RAM to exceed the value 0x20004000 during execution.

    So the uC start using the RAM from the higher address?

  • The gcc linker file puts the stack at the top of RAM so it grows down, this gives you the best chance of not corrupting your program memory if the stack gets too big. So if you give it the wrong amount of RAM, it puts the stack where there's no memory.

Related