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

nRF51822 - Exception on Stack Overflow

Using:

  • nRF51822
  • GCC 4.8.4
  • Nordic Sdk 5.2.0
  • pure-gcc setup (Ole Morten)
  • newlib-nano and -flto

See also this question.

I'd defined some stack size within startup_nrf51.s and want to be informed if the stackpointer passes __StackLimit.

Might there be a way to generate something like a hardfault or something else? The stack overflow condition should be detected regardless if the device is in debugging environment or not.

Edit 2014-08-28

BTW: For the heap / malloc issue, I see a different approach using a custom _sbrk() implementation. I'll post it as soon as I got a solution.

Trying out the RLENR0 based approach as suggested by RK.

My ram memory layout is currently like this:

__data_start__ = 20002000
__data_end__   = 20002088
__bss_start__  = 20002090
__bss_end__    = 20002DC4
__HeapBase     = 20002DC8
__HeapLimit    = 200031C8
__StackLimit   = 20003400
__StackTop     = 20004000
__stack        = 20004000

Dump of current RLENR0 and CLENR0 values:

NRF_MPU->RLENR0  = 00002000
NRF_UICR->CLENR0 = 00014000
NRF_FICR->CLENR0 = FFFFFFFF

I'm using the Sdk 5.2 bootloader which performs a check to NRF_UICR->CLENR0

// This check ensures that the defined fields in the bootloader corresponds with actual setting in the nRF51 chip.
APP_ERROR_CHECK_BOOL(NRF_UICR->CLENR0 == CODE_REGION_1_START);

so I'm a bit afraid from changing CLENR0 register.

Now I stuck for finding the correct RLENR0 value and write that into NRF_MPU->RLENR0. I'd try it from within code (tried both startup asm and very start of main). By trying out some random values:

  • Info: At the time when changing NRF_MPU->RLENR0 within main, my stackpointer is at 0x20003EF0 (determined by calling __get_MSP()).
  • For values like 0x20003400, my application stops immediately. Don't know if my hardfault handler was called - if so, then he was unable to write something via uart.
  • For values above 0x2140, I earn a immediate hardfault however.
  • All values from 0x0000 up to 0x2140, my application runs like before.

For the last case, I see my changed value in NRF_MPU->RLENR0, but when calling softdevice_handler_init() the value will be restored to 0x2000. When I now try to change NRF_MPU->RLENR0 again, a hardfault is raised - regardless which value I try to set.

Could you help me to find the right value for NRF_MPU->RLENR0 and how to write it into?

Parents
  • If you were feeling particularly clever you could try getting your linker map to organise your code so it looks like this ...

    FLASH: [ Softdevice.. ][Your code ][ empty flash + pstorage ]

    RAM: [ Softdevice RAM ][ Thread Stack ][ ... empty ...][ Process Stack ][Heap]

    Then you set RLENR0 in the memory module to just before the Process Stack and make sure CLENR0 is set correctly too.

    Malloc - assuming you find out why yours appears not to be working properly, will then fail if you over allocate heap and return 0 and I believe that any code running in region 1 (above CLENR0, i.e. your code) will fail if it tries to write into R0 RAM, that should include pushing too much on the stack and descending it below RLENR0. According to section 8.1.2 of the manual, that should cause a hard fault. ( don't know why nothing seems to generate MemManage faults on this chip but there you go).

    That also nicely decouples your stack from the softdevice one.

    I keep meaning to set CrosssWorks up to do this, it has all the symbols in the thumb_crt0.s file to set up the second stack pointer but just sort of can't quite be bothered.

Reply
  • If you were feeling particularly clever you could try getting your linker map to organise your code so it looks like this ...

    FLASH: [ Softdevice.. ][Your code ][ empty flash + pstorage ]

    RAM: [ Softdevice RAM ][ Thread Stack ][ ... empty ...][ Process Stack ][Heap]

    Then you set RLENR0 in the memory module to just before the Process Stack and make sure CLENR0 is set correctly too.

    Malloc - assuming you find out why yours appears not to be working properly, will then fail if you over allocate heap and return 0 and I believe that any code running in region 1 (above CLENR0, i.e. your code) will fail if it tries to write into R0 RAM, that should include pushing too much on the stack and descending it below RLENR0. According to section 8.1.2 of the manual, that should cause a hard fault. ( don't know why nothing seems to generate MemManage faults on this chip but there you go).

    That also nicely decouples your stack from the softdevice one.

    I keep meaning to set CrosssWorks up to do this, it has all the symbols in the thumb_crt0.s file to set up the second stack pointer but just sort of can't quite be bothered.

Children
Related