Fast notifications with nRF5340 and nRF Connect SDK

Board: nRF5340dk

SDK version: v2.1.0

My goal is to transmit 240 bytes of data every 5 ms using GATT notifications and 1 Mb PHY.

In the attached sample, I have my dev kit set up to notify on a characteristic every 5 ms. The connection interval is set to 10 ms, the MTU to 247 bytes, and the data length to 251 bytes. My thought is to fit 240 bytes into a single PDU, and send 2 notification packets per connection interval. I also toggle GPIO P0.04 before and after calling `bt_gatt_notify_cb`.

Looking at a logic analyzer trace of P0.04, I can see that while this setup initially works, eventually `bt_gatt_notify_cb` starts blocking for longer than expected. This happens around 14.5 seconds into the attached capture.

Wireshark capture also attached.

Why is `bt_gatt_notify_cb` blocking this long, and do you have any suggestions to improve the setup?

fast_notifications.zip

  • Thank you very much Benno.

    Are you using the Zephyr Bluetooth Low Energy controller?

    Did you set CONFIG_BT_LL_SPLIT=y in your prj.conf (or any other .conf file that is included in your application)?

    I believe the reason I struggled to find it is that if you use the Nordic Bluetooth Low Energy controller (SoftDevice controller), which is either set by default, or if you use CONFIG_BT_LL_SOFTDEVICE=y, then the implementation of bt_gatt_notify_cb() that will be used is found in bt_rpc_gatt_client.c (ncs\nrf\subsys\bluetooth\rpc\client\bt_rpc_gatt_client.c), and it looks like this:

    int bt_gatt_notify_cb(struct bt_conn *conn,
    		      struct bt_gatt_notify_params *params)
    {
    	struct nrf_rpc_cbor_ctx ctx;
    	int result;
    	size_t scratchpad_size = 0;
    	size_t buffer_size_max = 8;
    
    	buffer_size_max += bt_gatt_notify_params_buf_size(params);
    
    	scratchpad_size += bt_gatt_notify_params_sp_size(params);
    
    	NRF_RPC_CBOR_ALLOC(&bt_rpc_grp, ctx, buffer_size_max);
    	ser_encode_uint(&ctx, scratchpad_size);
    
    	bt_rpc_encode_bt_conn(&ctx, conn);
    	bt_gatt_notify_params_enc(&ctx, params);
    
    	nrf_rpc_cbor_cmd_no_err(&bt_rpc_grp, BT_GATT_NOTIFY_CB_RPC_CMD,
    		&ctx, ser_rsp_decode_i32, &result);
    
    	return result;
    }

    It doesn't call gatt_notify(). Do you see the same blocking behavior if you try to set CONFIG_BT_LL_SOFTDEVICE=y in your prj.conf?

    Best regards,

    Edvin

  • The controller part was not configured by me, so I do not really know what I am talking about. But I was under the impression that I use the Softdevice controller, but via "HCI using RPMsg" (CONFIG_BT_RPMSG=y).

    When I look into the .config file in the app build directory I see no definition of CONFIG_BT_LL_SPLIT nor CONFIG_BT_LL_SOFTDEVICE.

    In the .config file of the hci_rpmsg build directory I see

    # CONFIG_BT_LL_SW_SPLIT is not set

    and

    CONFIG_BT_LL_SOFTDEVICE=y

    Regards,

    Benno

  • Hello Benno,

    I am still struggling to get the same behavior as you do. Can you please send me a project with the configuration you are using that I can use to reproduce the issue? Are you able to reproduce it e.g. with something based on the peripheral_uart sample? 

    BR,
    Edvin

  • Hi Edvin.

    I have no sample code at hand to demonstrate the blocking behavior. At the moment I also have no time to build one.

    Are your tests based on a configuration with the Zephyr Host and the Softdevice Controller as in my case?

    By the way: I use the version 2.1.1 of the Connect SDK.

    Regards,

    Benno

  • Hello Benno, 

    Can you please explain what you mean by "configuration with the Zephyr Host and the Softdevice Controller"? How do you set the Zephyr Host when you are using the SoftDevice Controller?

    BR,
    Edvin

Related