adding Softdevice BLE (S140) with GPIO attached coprocessor to project without softdevice. hardfault calling existing code after Softdevice active

I am extending one of Qorvo's UWB platforms.. adding Softdevice BLE functions..  (which work ok) (this is on sdk 17_1_0)


the coprocessor uses a GPIO connected signaling mechanism,  using interrupts..

calling the existing code after BLE is active causes a hardfault.. 

this is running freetos,  we are in a freetos task. 

I've debugged (using ozone) it to  attempting to setup the interrupt handler for the GPIO pins. 

the existing code calls the nrfx libs 

       return qgpio_pin_irq_configure(&qm33_irq, QGPIO_IRQ_DISABLED);  //according to the doc, a gpio interrupt disable shouldn't impact softdevice.. 

```

enum qerr qgpio_pin_irq_configure(const struct qgpio *qgpio_pin, uint32_t flags)
{
nrfx_err_t r;
enum qerr err;
struct qgpio_cb_data *cb_data;
nrfx_gpiote_in_config_t trigger_config;
uint32_t abs_pin = NRF_GPIO_PIN_MAP(qgpio_pin->port, qgpio_pin->pin_number);  // this sets abs_pin = 25 

/* Init GPIOTE at least once. */
if (!nrfx_gpiote_is_init()) {   // this causes the hardfault.   
   r = nrfx_gpiote_init();
   if (r)
   return QERR_EBUSY;
}

if (flags & QGPIO_IRQ_DISABLED) {
   nrfx_gpiote_in_event_disable(abs_pin);
   nrfx_gpiote_in_uninit(abs_pin);
   return QERR_SUCCESS;
}
```
hardfault window
```
The target stopped in HardFault exception state.

Reason: A fault with configurable priority has been escalated to a HardFault exception at 0x00000000.
```

I don't see any mechanism to cause hardfault on a GPIO pin  with SD active. 
if SD is not active this code works as written 

what am I missing

if I run this code BEFORE setup of softdevice, it works, but softdevice init fails. 

Parents
  • Hi Sam, 
    So it seems that it didn't crash in nrfx_gpiote_is_init() ? 
    But it has something with the SPI transfer/IRQ handler instead ? 
    Could you check what's the context (interrupt priority) when this function is called ? 
    Also could you check how flash is handled in the code ? Note that when the softdevice is enabled, flash operation has to be handled by Softdevice's flash API

  • the title  is more correct.. 

    oh, spim relates to flash.. ??

    I can only assume that the project I built on does not have FDS enabled, and checking the sdk_config.h that is true. 

    a lot of knowledge needed. 

    they have a project that has SD peripheral mode, and put the FDS segments at 7D000-800000

    but that is in the middle of the large 52840 flash space.. 

    on the non-SD project, they don't have any space for FDS so I'll have to figure out  all that and how to indicate to use the SD apis for it.  part of my extensions need small amount of persistent storage

  • Hi Sam, 
    Could you explain more why SPIM related to flash ? Maybe check the interrupt priority of SPI interrupt?

    Note that the requirement is only about internal flash. The reason I mentioned that is that I noticed "nrfx_nvmc_page_erase " call in your log. 

    Note that FDS uses fstorage under the hood and you can choose between fstorage and fstorage_sd when you use it without or with Softdevice. 

    I will be a away for vacation until the end of the year. So there will be delay in the answer unfortunately.
    Wish you a Merry Xmas ! 

Reply
  • Hi Sam, 
    Could you explain more why SPIM related to flash ? Maybe check the interrupt priority of SPI interrupt?

    Note that the requirement is only about internal flash. The reason I mentioned that is that I noticed "nrfx_nvmc_page_erase " call in your log. 

    Note that FDS uses fstorage under the hood and you can choose between fstorage and fstorage_sd when you use it without or with Softdevice. 

    I will be a away for vacation until the end of the year. So there will be delay in the answer unfortunately.
    Wish you a Merry Xmas ! 

Children
  • after thinking about it overnight, I don't think FDS is involved..  I am debugging again now.. I think there might be another address optimization problem.. cause we fault in the SPIM interrupt handler

    I WILL need FDS and have adjusted the ld file to reserve the space when I get there..

    and I understand about using the fstorage api and letting the backend handle it.. 

    happy holidays. 

  • Hi Sam,
    Let's us know if you find out something wrong with the SPIM interrupt handler. Again, check the interrupt priority level and check if there is anything not expected calling inside that handler. 

    To narrow down the root cause I would suggest to try turning off SPIM to see if you can start the softdevice and do BLE correctly first. 

    Happy holidays ! 

  • BLE thru softdevice works great. Pair w phone, scan and connect downstream peripherals, send/receive data, notifications

    now I want to execute other code, unchanged from the Qorvo distribution. have found two code optimization problems, and this crash in the interrupt handler looks similar , if I stop in ozone there the pointer looks good,

    course sd is unhappy with the delay 

    if I don’t stop I get an access fault trying to write to the flash in code space.  Makes no sense. Tried different compiler versions, optimization settings.  Weird

    also, if I do this setup BEFORE SD init, then SD fails, BUT the other code does NOT..

    I don't see any shared resources.. interrupts, levels, ...

  • so, more investigation

    i'm pretty sure this is an interrupt priority problem, but I can't find id. 

    if U run the routine that fails after SD init,  BEFORE Sd init, it starts, no problem.

    when I get to the next step on using the backend chip

    I still get the same nrf_spim_event_clear write protection crash. 

    in the nrfx_spim.c , in the irq_handler

    the call stack in Ozone doesn't tell me where the code was before.. I can see it thru the pc address

    but I can't tell which interrupt invoked the handler. 

    init_log: Backends initialized
    create_log_processing_task: init_log completed
    create_log_processing_task: Stack allocated
    create_log_processing_task: Task created
    TEST RTT OUTPUT
    board_interface_init: START
    board_interface_init: About to init BLE
    Role: RoleController
    WARNING: UWB MAC initialization skipped - incompatible with SoftDevice
    Calling ble_stack_manager_init...


    [BLE] === SCANNING ALL INTERRUPTS FOR CONFLICTS ===
    [BLE] IRQ 0: priority=6, enabled=1
    [BLE] IRQ 9: priority=7, enabled=1

    [Fira Init] qplatform_init ok  <--- this is the code that failed AFTER sd was started
    [Fira Init] l1_config_init ok
    [Fira Init] llhw_init ok
    [Fira Init] done rc=0


    [BLE] ble_stack_manager_init: 1-nrf_sdh_enable_request
    [BLE] ble_stack_manager_init: 2-Configuring SoftDevice for concurrent connections
    [BLE] nrf_sdh_ble_default_cfg_set returned: 0, ram_start=0x20013000
    [BLE] sd_ble_cfg_set(CONN_CFG_GAP) returned: 0, ram_start=0x20013000 (conn_count=8)
    [BLE] ble_stack_manager_init: 3-nrf_sdh_ble_enable
    [BLE] Enabling central role: 1 peripheral + 7 central = 8 total connections
    [BLE] sd_ble_cfg_set(ROLE_COUNT) returned: 0, ram_start=0x20013000
    [BLE] nrf_sdh_ble_enable returned: 0 (0x0)
    [BLE] gap_params_init: COMPLETE
    [BLE] BLE stack initialized successfully - observer priority=3
    ble_stack_manager_init returned: TRUE
    BLE init SUCCESS - starting advertising
    [BLE] Using manual advertising data encoding...
    [BLE] *** BUILDING SCAN RESPONSE: role=1, name='CN_Controller', len=13 ***
    [BLE] Advertising data: 3 bytes, Scan response: 15 bytes (type=0x09, name='CN_Controller')
    [BLE] sd_ble_gap_adv_start returned: 0 (handle=0x00)
    [BLE] BLE advertising started successfully!

    advertising_start called  <--- I can see the BLE device in nrf_connect app 

    now start up the UWB device 


    Initializing UCI BLE commands...
    [UCI_BLE] uci_ble_commands_init() CALLED
    [UCI_BLE] CONTROLLER: Creating UCI manager task...
    [UCI_BLE] CONTROLLER: UCI manager task created successfully
    UCI BLE commands initialized successfully
    === BLE Init Complete ===
    [CTRL_TASK] *** TASK STARTED ***
    [CTRL_TASK] Mutex initialized
    [CTRL_TASK] Entering main loop, signal=2002C510
    [TASK_UCI] calling uci_open_backends
    in open_backends
    in open_backends uwbmac init ok
    in open_backends uci_init ok
    in open_backends init coordinator

    [00:00:00.021,847] <debug> nrf_sdh: State request: 0x00000000
    [00:00:00.021,854] <debug> nrf_sdh: State change: 0x00000000
    [00:00:00.279,301] <debug> nrf_sdh: State change: 0x00000001


    if the app_error_handler goes all the way thru 

    [00:01:01.659,109] <error> app: Fatal error

    if I don't execute that open_backends

    I see this from SD (and can connect thru NRF_Connect) 

    [CTRL_TASK] Entering main loop, signal=2002C4C0
    [TASK UCI] on entry
    [UCI_BLE] *** UCI MANAGER TASK STARTED (CONTROLLER MODE) ***
    [UCI_BLE] Performing late initialization in UCI manager task...
    [UCI_BLE] Late initialization: Creating UCI BLE queues and tasks...
    [UCI_BLE] Notification task started
    [UCI_BLE] Ranging continuation task created successfully
    [UCI_BLE] Ranging queue and task initialization complete
    [UCI_BLE] Ranging continuation task started - will process queued ranging requests
    log_processing_task: Started
    [UCI_BLE] Beacon notification semaphore created
    [UCI_BLE] UCI execution queue created successfully at 20030E58
    [UCI_BLE] CONTROLLER: UCI execution task already running (created in init)
    [UCI_BLE] Task handle: 2002BE30
    [UCI_BLE] Free heap: 14704 bytes
    [UCI_BLE] ***** UCI execution queue initialization COMPLETE *****
    [UCI_BLE] Late initialization complete - queue=20030E58
    [UCI_BLE] *** UCI_EXEC task ready to process messages from queue ***
    [UCI_BLE] Delaying 50ms before entering main loop...
    [UCI_BLE] *** ENTERING MAIN LOOP - will check queue and flags every 100ms ***
    [BLE] scan_evt_handler called! evt_id=6
    [BLE] QWR module assigned to connection handle 0x0007
    [BLE] BEACON: Initializing system attributes (for QWR)
    [BLE] BEACON: System attributes initialized successfully
    [BLE] CONTROLLER: Connection accepted from phone app
    [BLE] Conn handle: 0x0007, Peer address: 7B:D3:06:09:B6:4E (type 2)
    [BLE] Connection allowed - waiting for commands from phone
    [BLE] WRITE EVENT: handle=0x000D, op=1, len=2
    [BLE] Command char value=0x0010, CCCD=0x0011

    so, SD is up and running, and the IRQ setup BEFORE sd worked. 
    but turning it on , causes the fault in spim. 

    I added an u=interrupt enabled checker before and after the one call

    ```

    for (int irq = 0; irq < 48; irq++) { // nRF52840 has 48 interrupts
    uint32_t priority = NVIC_GetPriority((IRQn_Type)irq);
    uint32_t enabled1 = NVIC_GetEnableIRQ((IRQn_Type)irq);
    // Only report enabled interrupts or those with problematic priorities
    if (enabled1){ //} (priority == 0 || priority == 1 || priority == 4)) {
    SEGGER_RTT_printf(0,"IRQ %d: priority=%d, enabled=%d %s\r\n",
    //QLOGD("IRQ %d: priority=%d, enabled=%d %s",
    irq, priority, enabled1,
    (priority == 0 || priority == 1 || priority == 4) ? "*** CONFLICT ***" : "");
    }
    }
    ```


    [BLE] before 1 === SCANNING ALL INTERRUPTS FOR CONFLICTS ===
    IRQ 0: priority=6, enabled=1
    IRQ 9: priority=7, enabled=1


    [Fira Init] qplatform_init ok
    [Fira Init] l1_config_init ok
    [Fira Init] llhw_init ok
    [Fira Init] done rc=0


    [BLE] after === SCANNING ALL INTERRUPTS FOR CONFLICTS ===
    IRQ 0: priority=6, enabled=1


    IRQ 9: priority=7, enabled=1

    all these are newly enabled, but very low priority


    IRQ 6: priority=7, enabled=1

    IRQ 10: priority=7, enabled=1

    IRQ 27: priority=7, enabled=1
    IRQ 36: priority=7, enabled=1
    IRQ 39: priority=5, enabled=1

Related