nRF5340 BLE: the configuration for BLE MTU

Hi Support Team,

I tried the BLE communication with the Nordic UART Service (NUS) and used the code in the 'Bluetooth Low Energy Fundamentals Lesson 4 - Exercise 3' course.

The default MTU size was too small for my application. I preferred not to change the code in the hci_rpmsg on the netCore, so I added the below configuration on the appCore side:

1. In the files \bt-fund-main\lesson4\blefund_less4_exer3_solution\child_image\hci_rpmsg.conf:

#GATT_CLIENT needed for requesting ATT_MTU update
CONFIG_BT_GATT_CLIENT=y
#PHY update needed for updating PHY request
CONFIG_BT_USER_PHY_UPDATE=y
#For data length update
CONFIG_BT_USER_DATA_LEN_UPDATE=y
#This is the maximum data length with Nordic Softdevice controller
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
#These buffers are needed for the data length max. 
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_ACL_RX_SIZE=251
#This is the maximum MTU size with Nordic Softdevice controller
CONFIG_BT_L2CAP_TX_MTU=247

# Maxmum 2 connections are enough
CONFIG_BT_MAX_CONN=2

2. In the \bt-fund-main\lesson4\blefund_less4_exer3_solution\prj.conf:

#
# Copyright (c) 2018 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Enable the UART driver
CONFIG_UART_ASYNC_API=y
CONFIG_NRFX_UARTE0=y
CONFIG_SERIAL=y

CONFIG_GPIO=y

CONFIG_BT_NUS_UART_BUFFER_SIZE=400

# Make sure printk is printing to the UART console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_MAIN_STACK_SIZE=4096

CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="Nordic_UART_Service"
CONFIG_BT_DEVICE_APPEARANCE=833
CONFIG_BT_MAX_CONN=1
CONFIG_BT_MAX_PAIRED=1
CONFIG_BT_RX_STACK_SIZE=2048
# Enable the NUS service
# STEP 1 - Enable the Kconfig symbol of the NUS service
CONFIG_BT_NUS=y
CONFIG_BT_NUS_AUTHEN=n
CONFIG_BT_NUS_SECURITY_ENABLED=n
# Enable bonding
CONFIG_BT_SETTINGS=n
CONFIG_FLASH=n
CONFIG_FLASH_PAGE_LAYOUT=n
CONFIG_FLASH_MAP=n
CONFIG_NVS=n
CONFIG_SETTINGS=n

# Enable DK LED and Buttons library
CONFIG_DK_LIBRARY=y

# This example requires more workqueue stack
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

# Config logger
CONFIG_LOG=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n

CONFIG_ASSERT=y

#########################Added to increase the MTU###############################
CONFIG_BT_GATT_CLIENT=y
# STEP 8 - Enable PHY updates.
CONFIG_BT_USER_PHY_UPDATE=y

# STEP 12 - Update Data Length and MTU
CONFIG_BT_USER_DATA_LEN_UPDATE=y
#CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_L2CAP_TX_MTU=247

But it did not work. Could you help me with the below questions:

(1). Could you help review the above configurations? what was missed for the MTU setting?

(2). I'm a little confused about the configuration alignment on the host and controller sides.  For Data Length, MTU, and PHY_UPDATE, which need to align the configuration on both host and controller? which only needs to change single side configuration? In Lesson 3 – Exercise 2, it sets all in the host's prj.conf file.

Thank you very much,

Best regards,

Yanpeng Wu

Parents
  • Update: These are some compiled warning

    (SOC_SERIES_STM32WBX || (BT_PHY_UPDATE && BT_CONN && BT_HCI_HOST && BT_RPC_STACK) || (BT_PHY_UPDATE
    && BT_CONN && BT_HCI_HOST && BT_HCI && BT)) (=n). See
    http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_BT_USER_PHY_UPDATE and/or look up
    BT_USER_PHY_UPDATE in the menuconfig/guiconfig interface. The Application Development Primer,
    Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be
    helpful too.
    
    warning: BT_L2CAP_TX_MTU (defined at C:/ncs/v2.5.2/nrf\samples\common\mcumgr_bt_ota_dfu/Kconfig:122,
    C:/ncs/v2.5.2/nrf\subsys\bluetooth\services\fast_pair/Kconfig.fast_pair:80,
    C:/ncs/v2.5.2/zephyr/subsys/bluetooth/host\Kconfig.l2cap:30, subsys/bluetooth\host\Kconfig.l2cap:30)
    was assigned the value '247' but got the value ''. Check these unsatisfied dependencies:
    (NCS_SAMPLE_MCUMGR_BT_OTA_DFU_SPEEDUP || (BT_FAST_PAIR_GATT_SERVICE && BT_FAST_PAIR && BT) ||
    (BT_CONN && BT_HCI_HOST && BT_RPC_STACK) || (BT_CONN && BT_HCI_HOST && BT_HCI && BT)) (=n). See
    http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_BT_L2CAP_TX_MTU and/or look up
    BT_L2CAP_TX_MTU in the menuconfig/guiconfig interface. The Application Development Primer, Setting
    Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be helpful
    too.
    
    warning: BT_USER_DATA_LEN_UPDATE (defined at C:/ncs/v2.5.2/zephyr/subsys/bluetooth/host/Kconfig:341,
    subsys/bluetooth\host/Kconfig:341) was assigned the value 'y' but got the value 'n'. Check these
    unsatisfied dependencies: ((BT_DATA_LEN_UPDATE && BT_CONN && BT_HCI_HOST && BT_RPC_STACK) ||
    (BT_DATA_LEN_UPDATE && BT_CONN && BT_HCI_HOST && BT_HCI && BT)) (=n). See
    http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_BT_USER_DATA_LEN_UPDATE and/or look up
    BT_USER_DATA_LEN_UPDATE in the menuconfig/guiconfig interface. The Application Development Primer,
    Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be
    helpful too.
    
    warning: BT_GATT_CLIENT (defined at C:/ncs/v2.5.2/zephyr/subsys/bluetooth/host\Kconfig.gatt:170,
    subsys/bluetooth\host\Kconfig.gatt:170) was assigned the value 'y' but got the value 'n'. Check
    these unsatisfied dependencies: ((BT_CONN && BT_HCI_HOST && BT_RPC_STACK) || (BT_CONN && BT_HCI_HOST
    && BT_HCI && BT)) (=n). See http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_BT_GATT_CLIENT
    and/or look up BT_GATT_CLIENT in the menuconfig/guiconfig interface. The Application Development
    Primer, Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual
    might be helpful too.

    My Bluetooth is only used for the system configuration and provision, and FOTA, and will not be used for sensor data reporting like that. Could you help give a reference setting for MTU and Data Length for both appCore and netCore? With the default MTU, I can only send length=20 from the nRF mobile APP to the appCore's terminal with NUS. Thank you very much.

  • Hello,

    I believe the DevAcademy course should work. At least it did back when we worked on it, but I can't guarantee that something hasn't changed in more recent NCS versions.

    Can you please zip and upload your application folder, so that I can build it and see for myself?

    Due to Easter Holidays, we have some expected delay in our replys. I am sorry for this inconvenience.

    Best regards,

    Edvin

  • Hi Edvin

    Thanks for your hints. I followed Lesson 3 exercise 2 procedures and can get the new MTU.
    Could you help with the two questions below:

    1. With the callback on_datalen_updated_cb, I found the data length of tx and rx are different, and rx data length is much smaller than tx.
    In my application, the data flow is mainly on rx. There is no item for rx in structure bt_conn_le_data_len_param. Is it possible and how to set the rx data length in the application code?

        static void on_datalen_updated_cb(struct bt_conn *conn, struct bt_conn_le_data_len_info *info)
        {
        	uint16_t tx_len = info->tx_max_len;    	// tx_len = 251 bytes
        	uint16_t tx_time = info->tx_max_time;	// tx_time= 2120 us
        	uint16_t rx_len = info->rx_max_len;	    // rx_len = 27 bytes
        	uint16_t rx_time = info->rx_max_time;	// rx_time= 328 us
        }
        
        static void update_data_length(struct bt_conn *conn)
        {
        	int err;
        	struct bt_conn_le_data_len_param my_data_len = {
        		.tx_max_len = BT_GAP_DATA_LEN_MAX,
        		.tx_max_time = BT_GAP_DATA_TIME_MAX,
        	};
        
        	err = bt_conn_le_data_len_update(conn, &my_data_len);
        	if (err) {
        		LOG_ERR("data_len_update failed (err %d)", err);
        	}
        }

    2. Although the MTU and data length updates are successful, there are still compiling warnings in building the child image hci_rpmsg.
    These warnings are for BT_L2CAP_TX_MTU, BT_USER_DATA_LEN_UPDATE and BT_GATT_CLIENT:

        === child image hci_rpmsg - CPUNET begin ===
        loading initial cache file C:/02_dataLogger/IOTDL/build/hci_rpmsg/child_image_preload.cmake
        ....
        
        warning: BT_L2CAP_TX_MTU was assigned the value '247' but got the value ''. Check these unsatisfied dependencies:
        (NCS_SAMPLE_MCUMGR_BT_OTA_DFU_SPEEDUP || (BT_FAST_PAIR_GATT_SERVICE && BT_FAST_PAIR && BT) ||
        (BT_CONN && BT_HCI_HOST && BT_RPC_STACK) || (BT_CONN && BT_HCI_HOST && BT_HCI && BT)) (=n). 
        
        warning: BT_USER_DATA_LEN_UPDATE was assigned the value 'y' but got the value 'n'. Check these
        unsatisfied dependencies: ((BT_DATA_LEN_UPDATE && BT_CONN && BT_HCI_HOST && BT_RPC_STACK) ||
        (BT_DATA_LEN_UPDATE && BT_CONN && BT_HCI_HOST && BT_HCI && BT)) (=n). 
        
        warning: BT_GATT_CLIENT was assigned the value 'y' but got the value 'n'. Check
        these unsatisfied dependencies: ((BT_CONN && BT_HCI_HOST && BT_RPC_STACK) || (BT_CONN && BT_HCI_HOST
        && BT_HCI && BT)) (=n). 
        
        .......
        === child image hci_rpmsg - CPUNET end ===

    my setting in prj.conf is:

        CONFIG_BT_GATT_CLIENT=y
        CONFIG_BT_USER_PHY_UPDATE=n
        CONFIG_BT_USER_DATA_LEN_UPDATE=y
        CONFIG_BT_BUF_ACL_TX_SIZE=251
        CONFIG_BT_BUF_ACL_RX_SIZE=251
        CONFIG_BT_L2CAP_TX_MTU=247

    my settting in /child_image/hci_rpmsg.conf is:

        CONFIG_BT_GATT_CLIENT=y
        CONFIG_BT_USER_PHY_UPDATE=n
        CONFIG_BT_USER_DATA_LEN_UPDATE=y
        CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
        CONFIG_BT_BUF_ACL_TX_SIZE=251
        CONFIG_BT_BUF_ACL_RX_SIZE=251
        CONFIG_BT_L2CAP_TX_MTU=247
        CONFIG_BT_MAX_CONN=1

    Could you help give guidance for removing these warnings? Thank you very much.

    Best regards,
    Yanpeng Wu

  • Hello Yanpeng,

    I see that there are currently some errors in the github repository (unfortunately). I have reported it, so it will be fixed shortly. But if you go to this tag of the github repository:

    https://github.com/NordicDeveloperAcademy/bt-fund/tree/9c0ed920d5fc10dc92fd8480008c3fd26d83b0f5/lesson3/blefund_less3_exer2_solution

    You can see how the prj.conf and child_image/hci_rpmsg.conf should be.

    Basically, the child_image/hci_rpmsg.conf should be:

    CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
    CONFIG_BT_BUF_ACL_RX_SIZE=251
    CONFIG_BT_BUF_ACL_TX_SIZE=251
    
    CONFIG_BT_MAX_CONN=2

    and the prj.conf should be:

    #
    # Copyright (c) 2018 Nordic Semiconductor
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    
    # Logger module
    CONFIG_LOG=y
    
    # Button and LED library   
    CONFIG_DK_LIBRARY=y
    
    # Floating Point Unit
    CONFIG_FPU=y
    
    # Bluetooth LE
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DEVICE_NAME="Nordic_Peripheral"
    CONFIG_BT_LBS=y
    CONFIG_BT_LBS_POLL_BUTTON=y
    CONFIG_BT_GATT_CLIENT=y
    
    # STEP 5 - Configure your preferred connection parameters
    CONFIG_BT_PERIPHERAL_PREF_MIN_INT=800
    CONFIG_BT_PERIPHERAL_PREF_MAX_INT=800
    CONFIG_BT_PERIPHERAL_PREF_LATENCY=0
    CONFIG_BT_PERIPHERAL_PREF_TIMEOUT=400
    CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=y
    
    # STEP 8 - Enable PHY updates.
    CONFIG_BT_USER_PHY_UPDATE=y
    
    # STEP 12 - Update Data Length and MTU
    CONFIG_BT_USER_DATA_LEN_UPDATE=y
    #CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
    CONFIG_BT_BUF_ACL_RX_SIZE=251
    CONFIG_BT_BUF_ACL_TX_SIZE=251
    CONFIG_BT_L2CAP_TX_MTU=247

    (note that this is the prj_nrf5340dk_nrf5340_cpuapp.conf. You can either call it that, and it will be used instead of the prj.conf if you build for the nRF5340dk, or you can just delete the original prj.conf, and replace it with this one).

    Try that, and see if it works. Particularly, the missing "CONFIG_BT=y" causes some issues for you, I can see from your build log.

    Best regards,

    Edvin

  • oh, and if you are using ncs v2.6.0, then the hci_rpmsg.conf has been renamed to hci_ipc.conf, so you need to rename it in the child_image folder for the compiler to pick it up. But that is only if you are using v2.6.0. 2.5.x and earlier it should be "hci_rpmsg.conf"

  • Hi Edvin,

    I revised my .conf files and the warnings disappeared, thank you so much:).

    For my other question, "the data length of tx and rx are different, and rx data length is much smaller than tx" mentioned previously, could you help give some comments?
    My data flow is mainly on rx direction for system provision and firmware updating, so I hope the rx_len also can be tuned and optimized.

    Thank you very much.

    Best regards,
    Yanpeng Wu

  • Hello Yanpeng,

    While it is possible to have different RX and TX MTUs, it is not very common. What device are you connected to? A phone? Another nRF? Could it be the case that it only allows for a large MTU on the TX (it's RX)?

    BR,

    Edvin

Reply Children
  • Hi Edvin,

    I'm now connecting the nRF5340 to a mobile phone with the 'nRF Connect Mobile APP'.
    Is the rx_data_length the result of the negotiation by both sides and can not be set in the application code?

    I just tried to connect with a laptop, and I can see the data length in both tx and rx are 251. But BLE disconnected immediately(reason =19 = 0x13  #define BT_HCI_ERR_REMOTE_USER_TERM_CONN        0x13):

    1. MTU negotiation failed.
    <wrn> ble_host: [Ble Connected]: addr = 68:7A:64:AF:0A:09 (public)
    <wrn> ble_host: [Data len Update]: Updated. Length 251/251 bytes, time 2120/2120 us
    <wrn> ble_host: [Mtu negotiation]: MTU Exchange failed: err 14  //EFAULT 14, Bad address 
    <wrn> ble_host: [Ble Disconnected] - current_conn, 68:7A:64:AF:0A:09 (public) (reason 19)
    The error info was printed in callback mtu_exchange_notify_cb(struct bt_conn *conn, uint8_t err, struct bt_gatt_exchange_params *params). 
    
    2. MTU negotiation succeed, but BLE also disconnected.
    <wrn> ble_host: [Ble Connected]: addr = 68:7A:64:AF:0A:09 (public)
    <wrn> ble_host: [Mtu negotiation]: New MTU = 247 bytes, payload_mtu = 244
    <wrn> ble_host: [Data len Update]: Updated. Length 251/251 bytes, time 328/2120 us
    <wrn> ble_host: [Ble Disconnected] - current_conn, 68:7A:64:AF:0A:09 (public) (reason 19)

    But with 'nRF Connect Mobile APP' the connection is always successful. Need to do some setting when connecting to a laptop?


    Best regards,
    Yanpeng Wu

  • I am not sure about the laptop. Do you know if it is the laptop or the nRF that initiates the disconnect? Can you please try to capture a sniffer trace? You can use the nRF Sniffer for Bluetooth LE.

    What kind of phone are you using? You can initiate the MTU exchange from any of the devices, both for TX and RX. In fact, it already does that (if you are using the pfj.conf and hci_rpmsg.conf that we have discussed. And the fact that the laptop gives you max MTU both ways suggests that it is set up correctly from the nRF side. 

    What I suspect (a sniffer trace of the connection between the phone and the nRF could give a clear answer) is that the phone doesn't support MTU TX larger than the default. Do you have another phone that you can test on?

    What does your mtu_exchange_notify_cb() look like? And what does your MTU request function look like?

    Best regards,

    Edvin

  • Hi Edvin,

    I found that the MTU exchange failure and the different tx/rx data length are caused by the mobile phone. When I used two laptops to connect to nRF5340, both MTU exchange and data length negotiation were successful.

    I will use a laptop connection for future tests.
    One strange is that the connection will be disconnected in a short time with reason=19, that means the connection was terminated by the laptop.
    the trace likes:

        <wrn> ble_host: [Ble Connected]: addr = 74:70:FD:53:85:C6 (public)
        <wrn> ble_host: [Mtu negotiation]: New MTU = 247 bytes, payload_mtu = 244
        <wrn> ble_host: [Data len Update]: Updated. Length 251/251 bytes, time 2120/2120 us
        <wrn> ble_host: [Ble Disconnected] - current_conn, 74:70:FD:53:85:C6 (public) (reason 19)
        <wrn> ble_host: [Ble Connected]: addr = 74:70:FD:53:85:C6 (public)
        <wrn> ble_host: [Data len Update]: Updated. Length 251/251 bytes, time 2120/2120 us
        <wrn> ble_host: [Ble Disconnected] - current_conn, 74:70:FD:53:85:C6 (public) (reason 19)

    I will use the Sniffer and debug trace to see more details. If you have any hint for this, which is appreciated.

    Best regards,
    Yanpeng Wu

  • Please see the instructions on how to install the sniffer. Then you need to select the advertising device from the dropdown list near the top while sniffing. After that it should follow the peripheral into the connection. If you use encryption (other than "just works" pairing), you need to enter the passkey in the top before you pair. 

    You can also compare connecting to the laptop with connecting to the laptop running nRF Connect for Desktop ->Bluetooth Low Energy (which uses a DK/dongle for the BLE operations). Does it disconnect in both cases?

    After capturing a sniffer trace, you can save it as a .pcapng file, and upload it  here. 

    BR,
    Edvin

  • Hi Edvin

    The initial question of MTU configuration has been solved in this ticket. I closed it.
    For the connection problem with laptops, I will try it with your suggestions later.
    Thank you very much.

    Best regards,
    Yanpeng Wu

Related