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

Softdevice Task crash on disconnection

Hi,

I am developing a product based on nrf52832 using FreeRTOS and the softdevice.

I use sdk 15 and I based my softdevice configuration on the ble_app_hrs_freertos example. My problem is that on a disconnection event the device does not start to advertising as it should. The application is still responsive except for the softdevice task. 
I managed to make it work by changing the size of the buffer I use to store data I received from NUS service. This fact made me think I had a memory issue but I was not able to find an error on this side.

I did not find any topic related to this issue in the forum so I wonder if anyone experienced this kind of issue or if you have an idea of what could be the cause.

Thank you!

  • In the SDK15 known issues we have listed a new issue found that sounds like what you are facing. Please take a look at the workaround here

  • Thanks for the reply. Unfortunately it did not solve my problem. I added the hardfault implementation provided in the SDK to my project. Here are the logs I get :

    <error> hardfault: HARD FAULT at 0x0000715A
    <error> hardfault: R0: 0x20000404 R1: 0x00000000 R2: 0x00000000 R3: 0x00000000
    <error> hardfault: R12: 0x00000000 LR: 0x00008E49 PSR: 0x01000000
    <error> hardfault: Cause: Data bus error (PC value stacked for the exception return points to the instruction that caused the fault).
    <error> hardfault: Bus Fault Address: 0x002C0010

    This bug is very strange to me because it disappears and reappears depending on the size of my code without visible cause.

    I will continue investigate, please tell me if you need more information in order to help me.

  • can you please tell me more on the below line you mentioned

    it disappears and reappears depending on the size of my code without visible cause.

    What is the size of your code when the bug happens? have you checked to see if your code size is in conflict with your linker scripts? It sounds that way.

  • Ok so I found the origin of the hardfaut. It is a call to handler. The pointer to this handler is stored in a static variable. At initialization the value is being set without problem but one it is somehow erased after that and on BLE event i call this handler. The value being corrupted i get a Hardfault : 

    Value of rx handler is 2D88D, addr of handler is 20004D70
    Value of tx handler is 2D871, addr of handler is 20004D74
    Value of event handler is 2D875, addr of handler is 20004D78
    <21> Join or create
    <12> Start sniffing
    Value of handler is D875, addr of handler is 20004D78
    <error> hardfault: HARD FAULT at 0x0000D886
    <error> hardfault:   R0:  0x00000001  R1:  0x00000005  R2:  0x0FBC34A9  R3:  0x00000201
    <error> hardfault:   R12: 0x20006670  LR:  0x0002D1FD  PSR: 0x01000000
    <error> hardfault: Cause: Data bus error (PC value stacked for the exception return points to the instruction that caused the fault).
    <error> hardfault: Bus Fault Address: 0x0FBC34B1

    As you can see in this log the value of the event handler (pointer to actual function) is 2D875 at init and is D875 when I call it in ble_evt_handler. A byte has been erased.

    I will come back with some info on my linker script and code size

  • So here is my linker script and infos on size of my code. But when I say it disappears depending on size of code I mean it can disappear either if I add code or if I remove code without any rule.

    arm-none-eabi-size _build/app_sdk15_s132.elf
       text	   data	    bss	    dec	    hex	filename
     108856	   2732	  20028	 131616	  20220	_build/app_sdk15_s132.elf

     

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) :  ORIGIN = 0x26000, LENGTH = 512K - 0x26000 - 4K
      CONFIG (rw) : ORIGIN = 512K - 4K, LENGTH = 4K
      RAM (rwx) :   ORIGIN = 0x20002A98, LENGTH = 0xD568
    }
    
    SECTIONS
    {
    }
    
    SECTIONS
    {
      . = ALIGN(4);
      .mem_section_dummy_ram :
      {
      }
      .cli_sorted_cmd_ptrs :
      {
        PROVIDE(__start_cli_sorted_cmd_ptrs = .);
        KEEP(*(.cli_sorted_cmd_ptrs))
        PROVIDE(__stop_cli_sorted_cmd_ptrs = .);
      } > RAM
      .fs_data :
      {
        PROVIDE(__start_fs_data = .);
        KEEP(*(.fs_data))
        PROVIDE(__stop_fs_data = .);
      } > RAM
      .log_dynamic_data :
      {
        PROVIDE(__start_log_dynamic_data = .);
        KEEP(*(SORT(.log_dynamic_data*)))
        PROVIDE(__stop_log_dynamic_data = .);
      } > RAM
      .log_filter_data :
      {
        PROVIDE(__start_log_filter_data = .);
        KEEP(*(SORT(.log_filter_data*)))
        PROVIDE(__stop_log_filter_data = .);
      } > RAM
    
    } INSERT AFTER .data;
    
    SECTIONS
    {
      .mem_section_dummy_rom :
      {
      }
      .sdh_soc_observers :
      {
        PROVIDE(__start_sdh_soc_observers = .);
        KEEP(*(SORT(.sdh_soc_observers*)))
        PROVIDE(__stop_sdh_soc_observers = .);
      } > FLASH
      .sdh_ble_observers :
      {
        PROVIDE(__start_sdh_ble_observers = .);
        KEEP(*(SORT(.sdh_ble_observers*)))
        PROVIDE(__stop_sdh_ble_observers = .);
      } > FLASH
      .sdh_stack_observers :
      {
        PROVIDE(__start_sdh_stack_observers = .);
        KEEP(*(SORT(.sdh_stack_observers*)))
        PROVIDE(__stop_sdh_stack_observers = .);
      } > FLASH
      .sdh_req_observers :
      {
        PROVIDE(__start_sdh_req_observers = .);
        KEEP(*(SORT(.sdh_req_observers*)))
        PROVIDE(__stop_sdh_req_observers = .);
      } > FLASH
      .sdh_state_observers :
      {
        PROVIDE(__start_sdh_state_observers = .);
        KEEP(*(SORT(.sdh_state_observers*)))
        PROVIDE(__stop_sdh_state_observers = .);
      } > FLASH
        .nrf_queue :
      {
        PROVIDE(__start_nrf_queue = .);
        KEEP(*(.nrf_queue))
        PROVIDE(__stop_nrf_queue = .);
      } > FLASH
        .nrf_balloc :
      {
        PROVIDE(__start_nrf_balloc = .);
        KEEP(*(.nrf_balloc))
        PROVIDE(__stop_nrf_balloc = .);
      } > FLASH
        .cli_command :
      {
        PROVIDE(__start_cli_command = .);
        KEEP(*(.cli_command))
        PROVIDE(__stop_cli_command = .);
      } > FLASH
      .crypto_data :
      {
        PROVIDE(__start_crypto_data = .);
        KEEP(*(SORT(.crypto_data*)))
        PROVIDE(__stop_crypto_data = .);
      } > FLASH
      .pwr_mgmt_data :
      {
        PROVIDE(__start_pwr_mgmt_data = .);
        KEEP(*(SORT(.pwr_mgmt_data*)))
        PROVIDE(__stop_pwr_mgmt_data = .);
      } > FLASH
      .log_const_data :
      {
        PROVIDE(__start_log_const_data = .);
        KEEP(*(SORT(.log_const_data*)))
        PROVIDE(__stop_log_const_data = .);
      } > FLASH
      .log_backends :
      {
        PROVIDE(__start_log_backends = .);
        KEEP(*(SORT(.log_backends*)))
        PROVIDE(__stop_log_backends = .);
      } > FLASH
    
    } INSERT AFTER .text
    
    SECTIONS
    {
      . = ALIGN(4);
      .device_config(NOLOAD) :
      {
        PROVIDE(__start_config = .);
        KEEP(*(SORT(.device_config*)))
        PROVIDE(__stop_config = .);
      } > CONFIG
    }
    
    INCLUDE "nrf_common.ld"
    

Related