This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Getting NRF_ERROR_BUSY when sending Indicate at high rate

Hi,

I'm working on NRF52840 DK , S140 and I'm trying to send large data (around ~64KBytes) from a peripheral device. I'm using the following functions:
- sd_ble_gatts_hvx: to send the data (after setting the type to BLE_GATT_HVX_INDICATION)

- Waiting for BLE_GATTS_EVT_HVC event before sending the next packet

My connection interval is set to 7.5 msec in order to maximize the throughput. I have modified the code for the Nordic UART Service (TX characteristic) to send the data. So far I managed to send all the data. However, I noticed that "sd_ble_gatts_hvx" returns NRF_ERROR_BUSY  very frequently when I try to send the packets back to back. I keep retrying calling the function sd_ble_gatts_hvx until the returned error  is 0. It takes around 9 ms before the error returns 0 which is relatively long. This reduces the throughput significantly. So my questions are:

- Is there an event or status I can check for NRF_ERROR_BUSY  instead of calling sd_ble_gatts_hvx ?

- Do I need to add a delay after receiving the BLE_GATTS_EVT_HVC  event?

- Is there anything I need to configure to avoid this error all together?

Thanks in advance

  • - Is there an event or status I can check for NRF_ERROR_BUSY  instead of calling sd_ble_gatts_hvx ?

    There are no events to tract this other than the BLE_GATTS_EVT_HVC. If you want to avoid getting the ERROR_BUSY when calling the hvx, you can try to keep track of your free tx buffers in your application itself.  That is decrement your tx buffer count every time your HVX call is successful and increment it every time you get a BLE_GATTS_EVT_HVC event.  Since these two operations happen most likely in different context, you need to makes the increment and decrement operations either atomic or fence them with the critical section region .

    - Do I need to add a delay after receiving the BLE_GATTS_EVT_HVC  event?

    You do not need to, If you got the event from the softdevice, that means that softdevice have freed the tx buffer long ago. So no delays should be necessary here. Try keeping track of free tx buffers like I mentioned above.

    - Is there anything I need to configure to avoid this error all together?

    No, This error tells the application that it is calling hvx way too often than the softdevice is able to transmit. Understanding fine tuning of connection interval and throughput in reference to data size is explained well in this answer from Petter Myhre

  • Thanks a lot Susheel. 

    Just on tracking the tx buffers, which functions I should call. It'd be good if you send me a link for that.

    Also, is there a way to flush/free these buffers for example? I'm thinking if I receive the BLE_GATTS_EVT_HVC event, why would the buffers still be occupied? If there is a way to free them, I may be able to improve the throughput even further.

    Thanks

  • EAkeila said:
    Just on tracking the tx buffers, which functions I should call. It'd be good if you send me a link for that.

    Unfortunately, there is not API to query the size of free tx buffers. The application needs to initialize the count that is set in using sd_ble_cfg_set (defaults to 1 if not set). And then need to track the free tx buffers itself just the way I mentioned in my previous reply.

    EAkeila said:
    Also, is there a way to flush/free these buffers for example? I'm thinking if I receive the BLE_GATTS_EVT_HVC event, why would the buffers still be occupied? If there is a way to free them, I may be able to improve the throughput even further.

    Hmm, it feels like there is some misunderstanding here. If I understand your problem correctly, the main reason for your application to get NRF_ERROR_BUSY is because your application is calling sd_ble_gatts_hvx little faster than the softdevice is able to send those packets over BLE. And it was also my understanding that you want to avoid the unnecessary processing of getting the NRF_ERROR_BUSY error as it adds latencies to your application. That is the reason I suggested to call sd_ble_gatts_hvx only when your application knows that there is a free tx buffer. The application can with a very minimal logic keep track of these buffer count and then it gets the ability to know when to call sd_ble_gatts_hvx and when not.

    Getting BLE_GATTS_EVT_HVC definitely means that one TX buffer is free and if you are only calling sd_ble_gatts_hvx  when you get this event, then you should not get the busy error. There is not way to flush/reset already queued tx buffer but you should not need to do it of you are only queuing the buffers when you get this event. 

  • Thanks again. Actually I just found an issue with my code that overfills the buffers before I get the BLE_GATTS_EVT_HVC. I no longer see the NRF_ERROR_BUSY  error after fixing it 

Related