-
Notifications
You must be signed in to change notification settings - Fork 207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ArduinoBLE fail to restart after BLE.end #158
Comments
Hey @paulvha, do you have any example repos of this working? I've tried implementing this and it works for about 25 cycles and that hard faults. I'm struggling to figure it out, but wondering if you still have a working solution? |
Yes... I know this issue (and the solution to apply) as it took 3 long days of hard debugging in the past weeks to figure it out. The problem is actually NOT ArduinoBLE, but the root cause is in the Mbed / Apollo3 / BLE driver implementation. The Apollo3 is following a standard definition used by other BLE targets. What happens?Each time an When calling Next time a The solutionThe solution is a change in the Apollo3 driver to ONLY ask for a new handle if it does not have one. The one it had requested first time around is retained during deep sleep if you retain the full 384 MB memory. (which you always should on V2.x.x. of Apollo3) Once I figured it out it was not a difficult change and I applied it to a number of Apollo3 variants myself and tested it works.
changed to: // if we start & end BLE more than 16 times (WSF_MAX_HANDLERS)
// we can not start BLE again. There is NO call to undo/free
// the handler as we terminate.
wsfHandlerId_t handlerId = (wsfHandlerId_t) 0;
void AP3CordioHCITransportDriver::initialize()
{
if (!handlerId)
handlerId = WsfOsSetNextHandler(HciDrvHandler);
}
HciDrvHandlerInit(handlerId);
} The only challenge is that you need to know how to create a new MBED pre-compiled library and how to use it. If you do not know that drop me a mail at [email protected] with the board you use. i will send you the pre-compiled library and installation instructions for the Apollo3. |
If you have a solution that communicates with ArduinoBLE using Cordio, and you want to be able to set the solution to sleep for some time to save battery, ArduinoBLE will crash after sleep.
Root cause
Before going to sleep you have to call
BLE.end()
as the connection will disconnect when the lower level is set to deep_sleep and you need to reconnect on return.In
HCICordioTransport.cpp
HCI.end()
, called fromBLE.end()
, will perform ableLoopThread.terminate()
:ArduinoBLE/src/utility/HCICordioTransport.cpp
Line 200 in 3b228dc
This Bleloop is handling the wsf-timing. After sleep
BLE.begin()
is callingHCI.begin()
, where it tries to (re)startbleLoopThread.start(bleLoop)
:ArduinoBLE/src/utility/HCICordioTransport.cpp
Line 189 in 3b228dc
BUT.... AS THIS WAS TERMINATED YOU CAN NOT RESTART. Search on the Internet and you will find more people struggling with similar aspects.
Solution
Do not terminate the thread, but put it to wait. Make the following changes in
HCICordioTransport.cpp
Add a global variable around line 70:
In
bleloop()
change:ArduinoBLE/src/utility/HCICordioTransport.cpp
Lines 123 to 125 in 98ff550
To:
In
HCICordioTransportClass::begin()
change:ArduinoBLE/src/utility/HCICordioTransport.cpp
Lines 115 to 117 in 3b228dc
To:
in
HCICordioTransportClass::end()
changeArduinoBLE/src/utility/HCICordioTransport.cpp
Line 200 in 3b228dc
TO:
Additional context
Additional reports
The text was updated successfully, but these errors were encountered: