Hard fault Bus error nRF52840

Hi, I am using the nRF52840 with the softdevice s140 6.1.1 with the SDK 15.3 with FreeRTOS.

Sometimes after collecting data  for a around a day the device sometimes crashes caused by a hard fault.
The issue is hard to reproduce which makes it harder to debug.
We are not sure what could be the cause of this.
Here are the logs.

HARD FAULT at 0x0002AC12
  R0:  0x000007E0  R1:  0x00000000  R2:  0x0000000D  R3:  0x20784708
  R12: 0x00020000  LR:  0x0002ACB5  PSR: 0x01000000
Cause: Data bus error (PC value stacked for the exception return points to the instruction that caused the fault).
Bus Fault Address: 0x20784714

The PC does not seem to even be aligned, Here is a screenshot of the disassembly:


The LR register seems to points to nrf_drv_usbd_start:


Now while the USB is enabled, there is no USB events sent to the device since one of our mux never enables data on the USB lines (since the driver is still in development), but just in case it's useful, here is the code managing the USB. Only Usb_init is called in the main task. Also, note that the task size of the Usb handler task is 256. There is some code for the UsbCDC, but I  don't want to add too much code/noise.

// Not available on current electrical implementation
#define USB_POWER_DETECTION 0


static void usbHandler_task(void * context){
   usb_handler_t* usb_handler =  (usb_handler_t*)context;
   while(true){
        while (app_usbd_event_queue_process())
        {
            /* Nothing to do */
        }
        // Change to sleep/wake task
        delayMs(100);
   }
}


static void usbd_user_ev_handler(app_usbd_event_type_t event)
{

    // Note that power events won't be detected since it is not enabled for now
    switch (event){
        case APP_USBD_EVT_DRV_SOF:
            break;
        case APP_USBD_EVT_DRV_RESET:
            break;
        case APP_USBD_EVT_DRV_SUSPEND:
            break;
        case APP_USBD_EVT_DRV_RESUME:
            break;
        case APP_USBD_EVT_STARTED:
            break;
        case APP_USBD_EVT_STOPPED:
            app_usbd_disable();
            break;
        case APP_USBD_EVT_STATE_CHANGED:
            break;
        case APP_USBD_EVT_POWER_DETECTED:
            LOG_INFO("USB power detected");
            if (!nrf_drv_usbd_is_enabled()) {
                app_usbd_enable();
            }
            break;
        case APP_USBD_EVT_POWER_REMOVED:
            LOG_INFO("USB power removed");
            app_usbd_stop();
            break;
        case APP_USBD_EVT_POWER_READY:
            LOG_INFO("USB power ready");
            app_usbd_start();
            break;
        default:
            break;
    }
}

void Usb_init(usb_handler_t* usb_handler){

    /// Basic usb init
    Usb_enable(usb_handler, false);

    static const app_usbd_config_t usbd_config = {
        .ev_state_proc = usbd_user_ev_handler
    };
    app_usbd_serial_num_generate();
    ret_code_t ret = app_usbd_init(&usbd_config);
    HOP_ERROR_CHECK(ret);

    UsbCdc_init(&usb_handler->cdc);

    // Enable power envents
#if USB_POWER_DETECTION
    ret = app_usbd_power_events_enable();
    HOP_ERROR_CHECK(ret);
#else
    app_usbd_enable();
    app_usbd_start();
#endif
    
    usb_handler->task.handle = xTaskCreateStatic(
                      usbHandler_task,
                      "usb",
                      USB_HANDLER_TASK_SIZE,
                      usb_handler,
                      USB_HANDLER_TASK_PRIORITY,
                      usb_handler->task.taskStack,
                      &usb_handler->task.taskBuffer);
}

void Usb_enable(usb_handler_t* usb_handler, bool enable){
    usb_handler->enabled = enable;
    if(enable){
        nrf_gpio_pin_set(USB_EN);
    } else {
        nrf_gpio_pin_clear(USB_EN);
    }
}


Any ideas on the cause of this?
Could the USB actually cause a Bus fault or a stack overflow could have occurred and corrupt the stack?

Any help is appreciated.

Parents
  • Hi, I don't know the answer but wondering how you got the disassembly and source code mixed in like that.  Mind sharing?

    I'm chasing down the source of a bus fault myself, not sure how to read it at all, so looking for what the faulting instruction address is as a starter.

    [00:00:11.934,356] <err> os: bus_fault: ***** BUS FAULT *****
    [00:00:12.037,719] <err> os: bus_fault: Instruction bus error
    [00:00:12.143,280] <err> os: esf_dump: r0/a1: 0x20018954 r1/a2: 0xe000ed00 r2/a3: 0x20005730
    [00:00:12.284,423] <err> os: esf_dump: r3/a4: 0x004770d0 r12/ip: 0x00006c94 r14/lr: 0x0004ee5f
    [00:00:12.425,476] <err> os: esf_dump: xpsr: 0x20000000
    [00:00:12.524,780] <err> os: esf_dump: Faulting instruction address (r15/pc): 0x004770d0
    [00:00:12.656,341] <err> os: z_fatal_error: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
    [00:00:12.792,205] <err> os: z_fatal_error: Current thread: 0x20005838 (main)

    I found the ./build/zephyr/zephyr.lst file, but that doesn't appear to be it.

    I'm building via VSCode plugin notably.

  • Hi, the screenshot are from segger embedded studio, but if you are on linux, you can probably use `addr2line` instead.

Reply Children
No Data
Related