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

  • 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

Related