This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Large MTU + DLE Softdevice Crash

Hello,

I have followed a couple of the posts on the devzone on how to increase the MTU and add the DLE support such as this.

However, whenever I send over 20 bytes of data I get an "app_error_fault".

  • I have logging enabled and changed my ram size so my ram should be set correctly.

  • I have set the MTU size in sdk_config.h:

    #define NRF_BLE_MAX_MTU_SIZE 75

  • I set the att size in the setup function

    ble_enable_params.gatt_enable_params.att_mtu = NRF_BLE_MAX_MTU_SIZE;

  • I have set the DLE options

    ble_opt_t opt; memset(&opt, 0, sizeof(opt));

      opt.common_opt.conn_evt_ext.enable = 1;  //DLE
      
      err_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);
      APP_ERROR_CHECK(err_code);
      
      opt.gap_opt.ext_len.rxtx_max_pdu_payload_size = NRF_BLE_MAX_MTU_SIZE+4; //DLE
      
      err_code = sd_ble_opt_set(BLE_GAP_OPT_EXT_LEN, &opt);
      APP_ERROR_CHECK(err_code);
    
  1. I changed ble_nus.h to use the longer MTU size:

    *//#define BLE_NUS_MAX_DATA_LEN (GATT_MTU_SIZE_DEFAULT - 3) /< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ #define BLE_NUS_MAX_DATA_LEN (NRF_BLE_MAX_MTU_SIZE - 3) /< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. /

Any ideas as to why the softdevice would crash on a long write? I get a message saying I have requested the longer MTU by the central as well.

  • I just did this yesterday, can you post your files here? You need to request the MTU from the central upon connection established. You can use a function sd_ble_request_mtu() I believe that is what its called....I can lookup my notes

  • Hey Luke, here are the changes you should make, also how did you know how to set RAM? I know how to do it so that it works but how do you KNOW what the start value is? I read it has to do with the softdevice taking up the first section of bytes so you cant obviously overwrite this....I can test it tonight but these changes should work from quick glance....

    #define NRF_BLE_MAX_MTU_SIZE 247

    static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length) //{ /* for (uint32_t i = 0; i < length; i++) //{ while (app_uart_put(p_data[i]) != NRF_SUCCESS); //} while (app_uart_put('\r') != NRF_SUCCESS); while (app_uart_put('\n') != NRF_SUCCESS); */ printf("%d bytes rcvd!\r\n", length); //outputs to terminal such as PuTTY on COMx from JLINK in windows->system //}

    static void on_ble_evt(ble_evt_t * p_ble_evt) //{ uint32_t err_code;

    switch (p_ble_evt->header.evt_id)
    //{
        case BLE_GAP_EVT_CONNECTED:
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
            sd_ble_gattc_exchange_mtu_request(m_conn_handle, NRF_BLE_MAX_MTU_SIZE);
            break; // BLE_GAP_EVT_CONNECTED
      .......
    //}
    

    //}

        case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
    					printf("Received BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, client_rx_MTU: %d\r\n", p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu);
            err_code = sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                       NRF_BLE_MAX_MTU_SIZE);
            APP_ERROR_CHECK(err_code);
            break; // BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST
    			case BLE_EVT_DATA_LENGTH_CHANGED:
    					printf("Received BLE_EVT_DATA_LENGTH_CHANGED\r\n");
    					printf("The max number of payload octets the LL expects to receive %d \r\n", p_ble_evt->evt.common_evt.params.data_length_changed.max_rx_octets);
    					printf("The max number of payload octets the LL will send %d \r\n", p_ble_evt->evt.common_evt.params.data_length_changed.max_tx_octets);
    					break;
    			case BLE_EVT_TX_COMPLETE:
    					// here you can for example set a flag that the buffer is now free and main() can wait on that flag.
    					printf("Received BLE_EVT_TX_COMPLETE\r\n");
    					break;
    

    and also ensure in ble_nus.h:

    define BLE_NUS_MAX_DATA_LEN (GATT_MTU_SIZE_PKTLEN_EXT - 3)

  • Craig,

    how did you know how to set RAM?

    The program checks it in ble_stack_init(), it is output over the j-link RTT window. This is the code that checks the RAM settings:

    //Check the ram settings against the used number of links
    CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT);
    

    The only difference I see between your code and mine was this link after the GATT Connected callback:

    sd_ble_gattc_exchange_mtu_request(m_conn_handle, NRF_BLE_MAX_MTU_SIZE);
    

    Adding this didn't seem to change anything, it works fine on small sends but breaks on large data transfers. Have you tested your code for the throughput using larger packet sizes?

  • OK what cpu are you using exactly? what hardware are you using? devkit or your own? do you have access to a uart thru jlink? I have not tested it as I cannot until tonight or tomorrow morning.....please let me know and I can help you figure it out im sure...thanks for the advice on the RAM I also saw there is a file called app_ram_base.h which has all ram info for all configs!!!

Related