2017-05-24 06:43 AM
Hi All,
I am using ST's BlueNRG-MS SDK on an RTOS and when I try to send aci commands I get timeout status in return for some of them. For example in one application I am getting timeout after calling aci_gatt_add_char(), and in another example I am getting timeout for aci_hal_write_config_data().
Debugging Results:
Please find attached hci.c file for the discussion below:
1. In the
hci_send_req()
function of attached hci.c file, if I suspend the current task for very small time after callinghci_send_cmd()
at line 227 by callingnu_sleep()
in case of my OS, there is no timeout and command completes successfully.2. Similarly, instead of suspending the task as stated above, if I remove
Disable_SPI_IRQ()
call at line 271 in attached hci.c file, there is no timeout and aci command completes successfully.It is requested to please suggest a suitable and reliable solution for this problem as the above two workarounds are not reliable.
PS: I have tested the applications on firmware versions
7.1e, 7.2a and 7.2c
of BlueNRG-MS but the results are same.Regards,
Waseem Abbas
CC:
Vilei.Antonio
‌,Palmieri.Andrea
‌,Batek.Miroslav
‌,puel.bernard
‌#bluerng-ms #ble2017-05-25 02:16 AM
Dear Waseem Abbas,
the hci.c file that you are using has been implemented as an example for use on bare-metal, without any RTOS.
The logic behind the hci_send_req() function is the following:
1. you send a command by writing to the BlueNRG-MS chip via SPI;
2. You wait until you either find an event (in this case a response message) in the hciReadPktRxQueue event queue or timeout.
Events (including response messages) are stored in the queue by the IRQ handler, which reads from BlueNRG-MS via SPI. The Disable_SPI_IRQ() call at line #271 is used to prevent race conditions between the producer of events (i.e. the IRQ handler) and the consumer (i.e. the hci_send_req() function).
In your case, you have to adapt the code to your RTOS, in order to guarantee that there is a task being able to read the events and place them into the event queue. Otherwise, when hci_send_req() checks if there are any responses in the event queue, it will find none and you'll get a timeout.
Hope that helps,
Antonio
2017-05-25 04:55 AM
Hi
Vilei.Antonio
,In my case I have another task running at the same time which checks if an interrupt arrives from SPI_IRQ and calls HCI_ISR() function of hci.c file to read the events and place them into the event queue. If that task wasn't working right, all of the ACI calls would have timed out but in my case some of them succeed while others timeout, but applying the workarounds of points 1 and 2 in my post above solves this problem but removing theDisable_SPI_IRQ()call would be problematic due to race conditions and using sleep doesn't seem suitable as we don't know for how much time we should suspend the current task to allow the other task to read the events beforehand. Any solution or suggestion will be appreciated.
2017-05-25 04:59 AM
And one more thing.
Increasing the default timeout in to = DEFAULT_TIMEOUT at line 222 does not solve the problem no matter for how long we wait for the event to arrive but suspending the task using sleep() after line 227 in hci.c solves it and event is received successfully. This is a bit confusing behavior.
2017-05-25 08:21 AM
From your description, when the command times out, it seems like the RTOS scheduler is not able to run the event queue task. Adding the delay or keeping the BlueNRG-MS IRQ enabled allows the scheduler to suspend execution of the current task and start running the event queue task. When execution resumes on the first task, the queue is not empty and everything works as expected.
I guess that when commands don't time out, it may happen because other interrupts are suspending the execution of your task and this has the effect of allowing the event queue task to run.
Without knowing more details of your software architecture, it's not easy for me to understand where the problem is.
Ideally you could take advantage of your RTOS to wait until the event queue is not empty. In this way, the task would be suspended, and the event queue task will wake it up when it has read something.
As an alternative (not very elegant), you could try calling HCI_Isr() in a loop (with a counter to avoid looping forever) right after the Disable_SPI_IRQ() call at line &sharp271. In this way, everything would run in the same execution context and you should have no problems.
2017-06-21 07:36 AM
It would be really great if ST provided FreeRTOS sample code for BlueNRG-MS.