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

NRF_ERROR_RESOURCES occurred when the connection is disconnected

Dear

First of all, I am so sorry because of my english skill.

I got NRF_ERROR_RESOURCES when the connection between NRF Module and mobile device is disconnected  due to the reduced signal strength because of long distance.

However, if I disconnect the connection by sending the disconnection command from mobile device, it works well without any errors.

I used app_timer_start api to send data for notification every 1s as following,

err_code = app_timer_start(m_bms_measurement1_timer_id, BMS_MEASUREMENT1_TIMER_INTERVAL, NULL);
APP_ERROR_CHECK(err_code);

I already set NRF_SDH_BLE_GAP_EVENT_LENGTH as 100 and used BLE_GATTS_EVT_HVN_TX_COMPLETE.

But I had same result as before.

Thanks in advance.

  • Hello,

    I got NRF_ERROR_RESOURCES when the connection between NRF Module and mobile device is disconnected  due to the reduced signal strength because of long distance.

    Exactly which function returns this error?
    Could you also confirm that you have DEBUG defined in your preprocessor defines, like shown in the included image?

    This will make a the logger output a detailed error message whenever a non-NRF_SUCCESS error is passed to an APP_ERROR_CHECK.

    I already set NRF_SDH_BLE_GAP_EVENT_LENGTH as 100 and used BLE_GATTS_EVT_HVN_TX_COMPLETE.

    Could you elaborate on what you mean when you say that you already use BLE_GATTS_EVT_HVN_TX_COMPLETE? What do you do when this event is generated?

    I used app_timer_start api to send data for notification every 1s as following,

    What is your connection interval, and what is your hvn_tx_queue_size? I suppose what might be happening here is that packets does not make it across the link due to the increasing distance, and thus the hvn buffer is filled, so when the next notification then is attempted queued it will return with the NRF_ERROR_RESOURCES.
    To rectify this we could either balance your connection interval, supervision timeout and hvn buffer so this can not happen, or we could implement a local error handling for the NRF_ERROR_RESOURCE right after it is returned.

    Best regards,
    Karl

  • I already got NRF_ERROR_RESOURCES  with DEBUG option. 

    I also did BLE_GATTS_EVT_HVN_TX_COMPLETE as followings,

    ble event handler as following,

    void ble_cus_on_ble_evt( ble_evt_t const * p_ble_evt, void * p_context)
    {
    ble_cus_t * p_cus = (ble_cus_t *) p_context;

    switch (p_ble_evt->header.evt_id)
    {
    case BLE_GATTS_EVT_WRITE:
    on_write(p_cus, p_ble_evt);
    break;

    case BLE_GATTS_EVT_HVN_TX_COMPLETE:
    ble_tx_completed = true;

    default:
    // No implementation needed.
    break;
    }
    }

    following function is sent every 1s

    uint32_t ble_cus_bms_measurement1_update(ble_cus_t * p_cus, struct bms_measurement1_s *m_bms_measurement, uint16_t conn_handle)
    {
    ble_gatts_hvx_params_t params;
    uint16_t len = sizeof(struct bms_measurement1_s);

    memset(&params, 0, sizeof(params));
    params.type = BLE_GATT_HVX_NOTIFICATION;
    params.handle = p_cus->bms_measurement1_char_handles.value_handle;
    params.p_data = m_bms_measurement;
    params.p_len = &len;

    if(ble_tx_completed == true)
    {
    ble_tx_completed = false;
    return sd_ble_gatts_hvx(conn_handle, &params);
    }else return 0;
    //return sd_ble_gatts_hvx(conn_handle, &params);
    }

    connection interval as following,

    #define MIN_CONN_INTERVAL MSEC_TO_UNITS(400, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.1 seconds). */
    #define MAX_CONN_INTERVAL MSEC_TO_UNITS(650, UNIT_1_25_MS) /**< Maximum acceptable connection interval (0.2 second). */
    #define SLAVE_LATENCY 0 /**< Slave latency. */
    #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds). */

    How can I know the hvn_tx_queue_size ? From the web, I got some information about increasing hvn_tx_queue_size as following,

    static void ble_stack_init(void)
    {
    ret_code_t err_code;

    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);

    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    ble_cfg_t ble_cfg;

    memset(&ble_cfg, 0, sizeof(ble_cfg));
    ble_cfg.conn_cfg.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
    ble_cfg.conn_cfg.params.gattc_conn_cfg.write_cmd_tx_queue_size = 7;

    err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTC, &ble_cfg, ram_start);
    APP_ERROR_CHECK(err_code);

    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);

    // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }

    But I got NRF_ERROR_NO_MEM as following,

    <warning> nrf_sdh_ble: Insufficient RAM allocated for the SoftDevice.

    <warning> nrf_sdh_ble: Change the RAM start location from 0x20002260 to 0x20002308.

    <warning> nrf_sdh_ble: Maximum RAM size for application is 0xDCF8.

    <error> nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.

    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at C:\nrf_sdk\examples\my projects\ble_app_bms_vn4_0912_1227\main.c:1302

    PC at: 0x000320F3

    <error> app: End of error report

    My section Placement is following

    FLASH_PH_START=0x0

    FLASH_PH_SIZE=0x80000

    RAM_PH_START=0x20000000

    RAM_PH_SIZE=0x10000

    FLASH_START=0x26000

    FLASH_SIZE=0x5a000

    RAM_START=0x20002260

    RAM_SIZE=0xdda0

    Thanks in advance,

  • Hello,

    Please use the Insert -> Code option when sharing code here on DevZone.

    EarlBread said:
    if(ble_tx_completed == true)
    {
    ble_tx_completed = false;
    return sd_ble_gatts_hvx(conn_handle, &params);
    }else return 0;
    //return sd_ble_gatts_hvx(conn_handle, &params);
    }

    This will return 'as a success', since NRF_SUCCESS has the value 0, while actually having failed to queue the notification for sending. Your current way of using the boolean ble_tx_completed variable also limits you to having queued 1 notification for transfer. This might be sub-optimal, since multiple notifications may be queued and sent per connection event.

    EarlBread said:
    How can I know the hvn_tx_queue_size ? From the web, I got some information about increasing hvn_tx_queue_size as following,

    As written in the documentation you reference the default queue size if configured by the BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT in the sdk_config.h file. Increase this define to increase the number of notifications you may have queued at any one time.

    EarlBread said:

    <warning> nrf_sdh_ble: Change the RAM start location from 0x20002260 to 0x20002308.

    <warning> nrf_sdh_ble: Maximum RAM size for application is 0xDCF8.

    EarlBread said:

    RAM_START=0x20002260

    RAM_SIZE=0xdda0

    Please change your RAM_START and RAM_SIZE to the values indicated by the error message.
    Please do this, and see if it resolves your issues.

    Best regards,
    Karl

  • Thanks for quick response.

    I solved NRF_ERROR_NO_MEM problem with your recommend.

    I did the implementation as followings,

    increasing hvn_tx_queue_size = 27 with code in ble_stack_init function.

    increasing NRF_SDH_BLE_GAP_EVENT_LENGTH 235 in sdk_config.h

    didn't use  boolean ble_tx_completed in notification function for testing.

    uint32_t ble_cus_bms_measurement1_update(ble_cus_t * p_cus, struct bms_measurement1_s *m_bms_measurement, uint16_t conn_handle)
    {
        ble_gatts_hvx_params_t params;
        uint16_t len = sizeof(struct bms_measurement1_s);
    
        memset(&params, 0, sizeof(params));
        params.type   = BLE_GATT_HVX_NOTIFICATION;
        params.handle = p_cus->bms_measurement1_char_handles.value_handle;
        params.p_data = m_bms_measurement;
        params.p_len  = &len;
    
        //if(ble_tx_completed == true)
        //{
        //  ble_tx_completed = false;
        //  return sd_ble_gatts_hvx(conn_handle, &params);
        //}else return 0;
        return sd_ble_gatts_hvx(conn_handle, &params);
    }

    But I still have NRF_ERROR_RESOURCES.

    Thanks.

  • Hello,

    EarlBread said:
    Thanks for quick response.

    No problem at all, I am happy to help!

    EarlBread said:
    I solved NRF_ERROR_NO_MEM problem with your recommend.

    Great, I am glad to hear that it resolved your issue.

    EarlBread said:

    I did the implementation as followings,

    increasing hvn_tx_queue_size = 27 with code in ble_stack_init function.

    increasing NRF_SDH_BLE_GAP_EVENT_LENGTH 235 in sdk_config.h

    didn't use  boolean ble_tx_completed in notification function for testing.

    EarlBread said:
    But I still have NRF_ERROR_RESOURCES.

    Thank you for clarifying. If you are still getting NRF_ERROR_RESOURCES with a queue size of 27 we will need to take a look at how often notifications are queued for sending.
    How many notifications do you intend to send each connection event? You're current connection interval is between 400 and 650 ms - how many notifications do you expect to send in this period, and how often is the ble_cus_bms_measurement1_update function called in your program?

    Best regards,
    Karl

Related