Date
1 - 12 of 12
Choosing Tx Buffers in BLE stack
dhguja@gmail.com
Hello,
I am working on a BLE HID keyboard application using zephyr 1.13. I was playing around with Tx buffers (specifically Maximum number of pending TX buffers, Number of Tx buffers). With default buffer settings the characters were transmitted very slowly due to small number of buffers. But as soon as i increased it to 3 pending buffers and 3 Tx buffers i saw significant improvement in the speed of characters transmitted. My question is how to choose the buffer values for this?. The reason is currently i face a compatibility problem with my HID application, where it works fine in Linux, Android, iOS devices with increased number of buffers, but crashes on windows system. When i debugged the HCI log (from btmon) i saw that with increased buffers, characters are sent very quickly on the order of 500 us for each character. This causes the data (of 20 characters) to be transmitted within one or two connection intervals. Maybe this causes some overflow in windows systems. I would like to know what are the implications of choosing a number of Tx buffers and pending buffers. It will be helpful if anyone can tell how to choose the number of Tx buffers? or even point to some direction in the BLE specification? Thank you, Dhananjay G J |
|
Carles Cufi
Copying a few people to this thread. Carles From: devel@... <devel@...> on behalf of dhguja@... <dhguja@...>
Sent: Thursday, September 20, 2018 11:56 AM To: devel@... Subject: [Zephyr-devel] Choosing Tx Buffers in BLE stack Hello,
I am working on a BLE HID keyboard application using zephyr 1.13. I was playing around with Tx buffers (specifically Maximum number of pending TX buffers, Number of Tx buffers). With default buffer settings the characters were transmitted very slowly due to small number of buffers. But as soon as i increased it to 3 pending buffers and 3 Tx buffers i saw significant improvement in the speed of characters transmitted. My question is how to choose the buffer values for this?. The reason is currently i face a compatibility problem with my HID application, where it works fine in Linux, Android, iOS devices with increased number of buffers, but crashes on windows system. When i debugged the HCI log (from btmon) i saw that with increased buffers, characters are sent very quickly on the order of 500 us for each character. This causes the data (of 20 characters) to be transmitted within one or two connection intervals. Maybe this causes some overflow in windows systems. I would like to know what are the implications of choosing a number of Tx buffers and pending buffers. It will be helpful if anyone can tell how to choose the number of Tx buffers? or even point to some direction in the BLE specification? Thank you, Dhananjay G J |
|
Chettimada, Vinayak Kariappa
characters are sent very quickly on the order of 500 us for each characterPlease clarify, minimum BLE connection interval is 7.5 ms. Do you know what is the connection interval used by Window when you see the Window OS crash? you get Blue Screen of Death? Which version of Window OS? As the TX Buffer implies, it’s the number of packets queued locally until a chance to transmit them to the peer. Your TX Buffer count should be based on the rate of generation of packets per BLE connection interval. Usually, 7 Tx Buffers for slave role for a connection interval of 7.5ms should suffice. Actually calculation of optimal buffer count should be based on how fast, and how many bytes per packet is generated when Controller is transmitting the previous packet. - Vinayak -----Original Message----- From: <devel@...> on behalf of Carles Cufi <carles.cufi@...> Date: Friday, 21 September 2018 at 12:58 PM To: "dhguja@..." <dhguja@...>, "devel@..." <devel@...>, "Dunaj, Pawel" <padu@...>, "Gawor, Kamil" <Kamil.Gawor@...>, "Piszczek, Kamil" <Kamil.Piszczek@...>, "Von Dentz, Luiz" <luiz.von.dentz@...> Subject: Re: [Zephyr-devel] Choosing Tx Buffers in BLE stack Hi there, Copying a few people to this thread. Carles ________________________________________ From: devel@... <devel@...> on behalf of dhguja@... <dhguja@...> Sent: Thursday, September 20, 2018 11:56 AM To: devel@... Subject: [Zephyr-devel] Choosing Tx Buffers in BLE stack Hello, I am working on a BLE HID keyboard application using zephyr 1.13. I was playing around with Tx buffers (specifically Maximum number of pending TX buffers, Number of Tx buffers). With default buffer settings the characters were transmitted very slowly due to small number of buffers. But as soon as i increased it to 3 pending buffers and 3 Tx buffers i saw significant improvement in the speed of characters transmitted. My question is how to choose the buffer values for this?. The reason is currently i face a compatibility problem with my HID application, where it works fine in Linux, Android, iOS devices with increased number of buffers, but crashes on windows system. When i debugged the HCI log (from btmon) i saw that with increased buffers, characters are sent very quickly on the order of 500 us for each character. This causes the data (of 20 characters) to be transmitted within one or two connection intervals. Maybe this causes some overflow in windows systems. I would like to know what are the implications of choosing a number of Tx buffers and pending buffers. It will be helpful if anyone can tell how to choose the number of Tx buffers? or even point to some direction in the BLE specification? Thank you, Dhananjay G J |
|
dhguja@gmail.com
Hi, Thanks for the reply. Sorry if there is some confusion regarding the crash on windows. I will explain more elaborately below what i am trying to achieve & what i debugged till now. I am working on BLE based barcode scanner which will send the data via HID over GATT profile. I am using nRF52840 device and Zephyr 1.13 with default connection interval parameters. With the default Tx buffer numbers provided in zephyr the characters are sent to peer devices very slowly. We can literally see that characters are printed one by one. When i checked the HCI timestamps using btmon i see that 1 character is sent every connection interval time(around 45 ms ). To remove the bottleneck on Tx buffers i increased Maximum number of pending TX buffers (3) , Number of Tx buffers(3). I see that characters are sent instantly now (within one connection interval or even less than 10ms). The improvement in speed is seen only when i change both of these parameters from the default values. Now with this new config changes related to Tx buffers my application works fast as expected in Android, iOS, Linux systems. But on windows 10 system after two or three scans 'Windows' HID driver crashes probably due to buffer overflow from sending the data so fast. I checked the windows log and i see that "A command sent to the adapter has timed out. The adapter did not respond". The behavior seen is that characters are not accepted anymore and the last character that is sent to windows is printed continuously until the connection is closed. On the zephyr side, the bt_gatt_notify API is blocked until this time and then returns with error. I also checked the connection interval used with Windows 10 system as 40 ms. I also changed different buffer numbers to know the behavior but this just changes the time when this crash in windows occurs again. I also checked with some commercial devices that have similar application of using HID profile to send data and it also uses buffering to speed up. One thing i noticed in commercial device is for every 10 characters sent there is some delay equal to max connection interval time. But in case of my application using zephyr there is just 1 delay with connection interval for even up to 40 characters that are sent. In order to control the speed of buffering i tried changing different buffer numbers but with no luck or information on how to proceed further. If i know how to calculate or more information on these i can try to control the speed of my application by using buffer numbers or delays like i saw in other commercial devices. It would be helpful even if i had to look for something else in BLE specification or Zephyr. Thanks very much for the help. Regards, Dhananjay G J On Fri, Sep 21, 2018 at 1:20 PM Von Dentz, Luiz <luiz.von.dentz@...> wrote: Hi, |
|
Von Dentz, Luiz <luiz.von.dentz@...>
Hi,
toggle quoted message
Show quoted text
I guess that is because with more buffer one can queue more data and is less affected by the speed in which the controller acknowledge their transmissions, obviously this increase the footprint but it is the usual trade of size for speed. Btw, if the improvement is substantial maybe we should have 3 by default, though we need to figure if the crash on windows is due to some misbehaviour on our side when are operating with more buffers. On Fri, Sep 21, 2018 at 1:58 PM, Cufi, Carles <Carles.Cufi@...> wrote:
|
|
dhguja@gmail.com
Hi All, With regards to my previous problems I have some basic questions to understand this problem. By increasing the Tx Buffers i increased the number packets transmitted per connection interval. Even though this increased my data transfer speed i faced compatibility issue with windows HID driver crashing in the middle of transmission. I read that Android and iOS systems sometimes have a limit on the number of packets transmitted per connection interval time. May be for windows too there may be some limit on this factor. when i checked the HCI logs i see that almost all the HID characters are sent with in one connection interval for my device. Is it possible to configure this factor in zephyr either directly or indirectly? (or) Should application layer handle these delays? Regards, Dhananjay G J On Fri, Sep 21, 2018 at 3:42 PM dhananjay gj <dhguja@...> wrote:
|
|
pawel.dunaj@...
Hi,
Whatever Zephyr is doing I don't think Win should crash. I expect this is a bug in the OS or the driver. You can try MS support, maybe they can help. It should simply reject the data (that will probably not help you much as you may miss an information about key release). At first I expected you are not sending normal HID data but instead put some custom data in the HID report, but you state that you work on a keyboard. Are you using zephyr hid sample? How is your report defined? How much data are you sending with each notification? Zephyr will block when there is no buffer available to add the notification data too. If data is not picked fast enough by the host (i.e. connection is slow) pipeline of data waiting to be served will build up. It is up to your application to ensure the valid data flow. For that you can check optional callback added to Zephyr recently. As for limiting the number of data sent with each connection interval, you are doing that by correctly setting up the report map and sending data according to it. Are you doing that? (Maybe system receives too much data compared to what was stated in the map and crash?) To limit the data sent with each interval you can try changing MTU, however I don't think this is the problem. Thanks, Pawel |
|
dhguja@gmail.com
Hello Pawel, Thank you very much for the reply. Yes i used the zephyr sample as reference(HoG mouse device) but modified for keyboard. The report map i use is directly from Nordic SDK HID keyboard sample. I am also sending standard USB HID report for every character (u8_t modifier, u8_t media, u8_t keys[6] => totally 8 bytes). I think every BLE packet sends one character since I did not change the MTU size (~20 bytes for application) This report map and report along with BLE Tx buffer changes works fine in Android and iOS device without any problems. Even in Windows if i use the default buffer settings where 1 character is sent every connection interval, things works fine. Only when there are more packets sent continuously without a delay windows HID driver crashes in the middle. I also tried to enable some low level logs in zephyr BLE for debugging but apparently logging adds some delay which hides the problem from appearing. Also your comment is true "Zephyr will block when there is no buffer available to add the notification data too" Zephyr did block the notify API when the windows driver crashed and could not receive further characters. I checked the behavior of other existing HID barcode scanner devices where i see that there is at least a delay (almost connection interval time) every 9-10 characters sent. I was just curious if we can config this as setting in Zephyr. These commercial devices also send the data to windows with similar timing per packet (~ 600 microsec) as my Zephyr based device . The only difference is the delay of connection interval for every ~10 packets. Is there something i can further do from zephyr configs? Regards, Dhananjay G J On Mon, Oct 1, 2018 at 3:37 PM <pawel.dunaj@...> wrote: Hi, |
|
Chettimada, Vinayak Kariappa
Hi Dhananjay,
toggle quoted message
Show quoted text
Related PR and its explanation in the commit message: https://github.com/zephyrproject-rtos/zephyr/pull/10332 This does not solve your Windows crash, but will in general reduce data transmission latencies in the cases where in host is trying to continuously transmit packets as fast as it can. Regards, Vinayak -----Original Message-----
From: <devel@...> on behalf of "dhguja@..." <dhguja@...> Date: Monday, 1 October 2018 at 4:20 PM To: "Dunaj, Pawel" <Pawel.Dunaj@...> Cc: "devel@..." <devel@...> Subject: Re: [Zephyr-devel] Choosing Tx Buffers in BLE stack Hello Pawel, Thank you very much for the reply. Yes i used the zephyr sample as reference(HoG mouse device) but modified for keyboard. The report map i use is directly from Nordic SDK HID keyboard sample. I am also sending standard USB HID report for every character (u8_t modifier, u8_t media, u8_t keys[6] => totally 8 bytes). I think every BLE packet sends one character since I did not change the MTU size (~20 bytes for application) This report map and report along with BLE Tx buffer changes works fine in Android and iOS device without any problems. Even in Windows if i use the default buffer settings where 1 character is sent every connection interval, things works fine. Only when there are more packets sent continuously without a delay windows HID driver crashes in the middle. I also tried to enable some low level logs in zephyr BLE for debugging but apparently logging adds some delay which hides the problem from appearing. Also your comment is true "Zephyr will block when there is no buffer available to add the notification data too" Zephyr did block the notify API when the windows driver crashed and could not receive further characters. I checked the behavior of other existing HID barcode scanner devices where i see that there is at least a delay (almost connection interval time) every 9-10 characters sent. I was just curious if we can config this as setting in Zephyr. These commercial devices also send the data to windows with similar timing per packet (~ 600 microsec) as my Zephyr based device . The only difference is the delay of connection interval for every ~10 packets. Is there something i can further do from zephyr configs? Regards, Dhananjay G J On Mon, Oct 1, 2018 at 3:37 PM <pawel.dunaj@...> wrote: Hi, Whatever Zephyr is doing I don't think Win should crash. I expect this is a bug in the OS or the driver. You can try MS support, maybe they can help. It should simply reject the data (that will probably not help you much as you may miss an information about key release). At first I expected you are not sending normal HID data but instead put some custom data in the HID report, but you state that you work on a keyboard. Are you using zephyr hid sample? How is your report defined? How much data are you sending with each notification? Zephyr will block when there is no buffer available to add the notification data too. If data is not picked fast enough by the host (i.e. connection is slow) pipeline of data waiting to be served will build up. It is up to your application to ensure the valid data flow. For that you can check optional callback added to Zephyr recently. As for limiting the number of data sent with each connection interval, you are doing that by correctly setting up the report map and sending data according to it. Are you doing that? (Maybe system receives too much data compared to what was stated in the map and crash?) To limit the data sent with each interval you can try changing MTU, however I don't think this is the problem. Thanks, Pawel |
|
dhguja@gmail.com
Hello All,
I did some more debugging on my problem and i noticed that whenever the characters are stopped receiving by windows host i get a disconnection in my device with either LMP RESPONSE TIMEOUT / LL RESPONSE TIMEOUT (0x22) or CONNECTION TIMEOUT (0x08) always. Is this expected on the zephyr side? Is there anything else i can do from my device perspective? I also posted my queries in MS forums and waiting for some solution there too. Thanks for the help. Dhananjay G J |
|
Chettimada, Vinayak Kariappa
Do you have a sniffer trace you can send to me email?
toggle quoted message
Show quoted text
It appears the peer is not responding to a control procedure. -Vinayak -----Original Message-----
From: <devel@...> on behalf of "dhguja@..." <dhguja@...> Date: Thursday, 4 October 2018 at 11:19 AM To: "devel@..." <devel@...> Subject: Re: [Zephyr-devel] Choosing Tx Buffers in BLE stack Hello All, I did some more debugging on my problem and i noticed that whenever the characters are stopped receiving by windows host i get a disconnection in my device with either LMP RESPONSE TIMEOUT / LL RESPONSE TIMEOUT (0x22) or CONNECTION TIMEOUT (0x08) always. Is this expected on the zephyr side? Is there anything else i can do from my device perspective? I also posted my queries in MS forums and waiting for some solution there too. Thanks for the help. Dhananjay G J |
|
Carles Cufi
Note that if you do not own a BLE sniffer you can still use a Nordic board to sniff traffic over the air:
toggle quoted message
Show quoted text
https://www.nordicsemi.com/eng/Products/Bluetooth-low-energy/nRF-Sniffer Carles -----Original Message----- |
|