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

Queued Write without Response questions

Hello Nordic team,

I'm using nrf52840 DK with SDK 15.3.0.

So I had an example sending data similarely to the ble_app_uart_c example that worked OK. 

Basically I have a TX_FIFO with about 1KB data in it and I'm processing the data 20 bytes a time as Write without Response every time I received a BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event. 

I needed to speed up the process so I looked into the documentation and saw that the Write without Response that can be queued : https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s140.api.v6.1.1%2Fgroup___b_l_e___g_a_t_t_c___f_u_n_c_t_i_o_n_s.html&anchor=ga90298b8dcd8bbe7bbe69d362d1133378

I followed the described procedure from the documentation:

  • Store initial queue element count in a variable.
  • Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns NRF_SUCCESS.
  • Increment the variable, which stores the current available queue element count, by the count variable in BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event.

And tests showed that I have 4 buffers availables (I can call sd_ble_gattc_write 4 times before NRF_ERROR_RESOURCES) whereas ble_gattc.h shows : 

/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults
 * @{ */
#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */

But this variable doesn't seem to affect the number of buffers in my example, so I guess it is overwritten somewhere but I can't find where. 

So here are my questions: 

How to find where  BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT overwritten in my example ? 

Do you have an example using the procedure describe in the documentation ? (If not I have a working example but some questions about how to optimize it)

Thanks in advance,

Aloïs KYROU.

  • Thanks Vidar your remarks made me realise something :) 

    In fact the problem wasn't in  an overlap on the process FIFO function but that it was too fast causing the other side device to lose packets ...

    I'm indeed using another BLE device as peer. 

    I tried sending continuously send from your main loop and ignore the return value. This way it took me 43 msec to send 1KB of data. 

    When I wait for at least 4 buffers to be released, it takes 86 msecs to send 1KB of data.

    The clean implementation is to call the send function when a BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE arrive to tell that a buffer is available. What I'm afraid of is that two events like this may overlap. 

    Are successive BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE and other BLE events stacking in some sort of FIFO to be dispatch one after the other (Which means i can synchronously execute my function to avoid overlaps). Or does the SoftDevice implementation could send an event while the execution of another one isn't terminated yet ? 

    What I mean is, is this case possible ? 

  • Glad to hear it was of some help:)

    In fact the problem wasn't in  an overlap on the process FIFO function but that it was too fast causing the other side device to lose packets ...

    I'm not that familiar with your implementation, but just want to point out that packets that are successfully added to the output buffer (hvx function returns NRF_SUCCESS), will be re-transmitted on-air until they're acked by the peer device. And the link will be considered lost if a packet is not acked withing the supervision timeout. My point is that you may want to find what causes the packet loss on the receiving device. 

    The clean implementation is to call the send function when a BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE arrive to tell that a buffer is available. What I'm afraid of is that two events like this may overlap. 

    They should not overlap as long as you are not using a preemptive scheduler for SD event processing. The ble callback is called in an interrupt context in most of our examples. 

  • I can't have access to the receiving device implementation so only supositions here :) But it is using an Uart protocol tu proceed Write without Response datas. 

    But ins't acking the transmition of data the point of Write with Response ? Since I'm using Write without Response I thought the packets weren't acknowledged ? 

  • All packets are acked at the link layer, but write with response will also need to be acknowledged by the application layer running on top.  

Related