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.

Parents
  • 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)

Reply
  • 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)

Children
No Data
Related