This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Assertion Fail Using ble_nus_client_send with UART in NRF Connect SDK 1.8.0

Hello,

I am getting the error: ASSERTION FAIL @ WEST_TOPDIR/zephyr/subsys/bluetooth/host/conn.c:1152
E: r0/a1: 0x00000004 r1/a2: 0x00000480 r2/a3: 0x200060d0

I'm using the Fanstel BLG840X which integrates an nrf52840 and nrf9160.  I am using NRF Connect SDK 1.8.0.  At a high level the software:

1) nrf52840 establishes BLE connection with a sensor using nordic uart service

2) receives a message from the sensor

3)52840 uses UART to notify the 9160 to ask for information back 

4) 9160 responds with queried information (uart transfer from 9160 to 52840)

5)the information received from the 9160 over UART is sent out over BLE to the sensor

In trying to narrow the problem I found that sending information to the sensor before step 3 (using UART to communicate between the boards) functions properly.  So I suspect that there may be some interference from the UART module in steps 3/4/5.  I was also getting an MPSL 112,2165 error but that has stopped appearing.  Here is my ble function causing the fault and my prj.conf file:

void send_timestamp(struct uart_data_t *uart_data)
{
    struct bt_nus_client *nus1 = &nus_client;
    int status;
    uint8_t len = 10;
    status = bt_nus_client_send(nus1, uart_data->data, len); // why is this incompatible

    if (status != 0)
    {
        printk("err: %d\n", status);
    }
    else
    {
        printk("successful send \n");
    }
    
}

CONFIG_BT=y
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_CENTRAL=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_GATT_DM=y
CONFIG_BT_L2CAP_TX_BUF_COUNT=10
CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_NUS_CLIENT=y
CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_UUID_CNT=1
CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_NCS_SAMPLES_DEFAULTS=y
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
CONFIG_REBOOT=y
CONFIG_RTT_CONSOLE=y
CONFIG_SERIAL=y
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_UART_1_ASYNC=y
CONFIG_UART_ASYNC_API=y
CONFIG_UART_CONSOLE=n
CONFIG_USE_SEGGER_RTT=y

#ble split, hardfault was being caused by multi-protocol service layer (mpsl), this changes ble controller to zephyr. not sure if needed
#CONFIG_BT_LL_SW_SPLIT=y

Another note is that UART is initialized before steps 1-5 take place, so if there is interference from the UART module it would likely be happening from the actual UART messages sending/receiving.

Another potential issue is that the UART is still busy.  Further testing I tried sending a UART message then immediately after sending a BLE message and that failed as well, so I was wondering if there was any overlap between UART/BLE since it's nordic UART service being used for the BLE, and if there are standardized ways to keep them separated, ie: don't use BLE while UART is active.

Currently receiving information over BLE then sending it over UART works but not receiving information over UART then sending over BLE causes the Assertion.

Thanks for the help and please let me know if you need other information/code.  

Parents
  • Hello,

    Are you sending the data from the UART Interrupt Handler sdk-zephyr/conn.c at v2.7.0-ncs1 · nrfconnect/sdk-zephyr · GitHub? You can use a work thread or similar to send the data instead of calling it directly from the uart_handler. 

    Thanks.

    Best Regards,

    Kazi Afroza Sultana

  • Are you sending the data from the UART Interrupt Handler

    Are you referring to data sent over UART or data send with the Nordic UART Service (for BLE)?  

    I am just calling both directly, could that be an issue?  So you're recommending I generate an interrupt then use that interrupt handler to send the data?

    Also my code for sending over UART is: 

    int uart_send(struct uart_data_t *uart_data)
    {
        int status = uart_tx(device_uart, uart_data->data, uart_data->length, SYS_FOREVER_MS);
    
        if (status != 0)
        {
            printk("uart_tx ( error: %d )\n", status);
    
            // Add to tx queue to try and process / send later ...
            k_fifo_put(&fifo_uart_tx_data, uart_data);
        }
    
        return status;
    }

    Also for more context on the error I've started debugging with Ozone, this is the full error state that I'm still working through:

    The line throwing the error was in: ..\ncs\v1.8.0\zephyr\subsys\bluetooth\host\conn.c line 1152 which is:

    __ASSERT_NO_MSG(!k_is_in_isr());
    It has the associated comment: 
    /*
         * PDU must not be allocated from ISR as we block with 'K_FOREVER'
         * during the allocation
         */
    I wasn't sure what this meant, could you elaborate on what might be causing this error to throw.  ISR is the interrupt service routine but I'm not sure what PDR is or why my code might have caused this assert.  For testing purposes I commented out the line and the send worked properly but I want to solve the issue causing the error.
  • Hi,

    PDU stands for protocol data unit, commonly known as packets. Looks like you can't call bt_nus_client_send() from the UART ISR. Instead, just put the UART data in a FIFO, e.g. with k_fifo_put(), and have a separate thread that sends the data. E.g. as done in peripheral_uart sample.

  • This was it, working with the line in conn.c back in, thanks so much!

Reply Children
No Data
Related