Hello All,
I am trying to set up a device on an IoT Nano that uses the following libraries:
- Adafruit NeoPixels / NeoPixelBus
- Arduino BLE
- RTCZero
- SD
- Servo
- WiFiNINA
However, while doing some testing I have been experiencing sporadic crashes where the board completely freezes and requires resetting. After painfully tracking where the crash was happening by having the code print its location frequently I managed to pinpoint the crash to the BLE.poll() function. I then took a look at the HCI.poll() function and found that most of them were occurring at the end of the while (HCITransport.available()) loop but before the end of the poll function which doesn’t have anything. I have added the edited function below with my debug edits. The IoT seems to freeze after “WE” but doesn’t send the “A” which I added to the HCITransport.available() function or the “WS” from the start of the while.
void HCIClass::poll(unsigned long timeout)
{
//Edit
if (_debug) {
_debug->print("PS ");
}
//
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
digitalWrite(NINA_RTS, LOW);
#endif
if (timeout) {
//Edit
if (_debug) {
_debug->print("T ");
}
//
HCITransport.wait(timeout);
}
while (HCITransport.available()) {
//Edit
if (_debug) {
_debug->print("WS ");
}
//
byte b = HCITransport.read();
//Edit
/* if (_debug) {
_debug->print("R: ");
_debug->print(b);
_debug->print(" ");
}*/
//
_recvBuffer[_recvIndex++] = b;
//Edit
if (_debug) {
_debug->print("I:");
_debug->print(_recvIndex);
_debug->print(" ");
}
//
if (_recvBuffer[0] == HCI_ACLDATA_PKT) {
if (_recvIndex > 5 && _recvIndex >= (5 + (_recvBuffer[3] + (_recvBuffer[4] << 8)))) {
if (_debug) {
dumpPkt("HCI ACLDATA RX <- ", _recvIndex, _recvBuffer);
}
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
digitalWrite(NINA_RTS, HIGH);
#endif
int pktLen = _recvIndex - 1;
_recvIndex = 0;
handleAclDataPkt(pktLen, &_recvBuffer[1]);
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
digitalWrite(NINA_RTS, LOW);
#endif
}
} else if (_recvBuffer[0] == HCI_EVENT_PKT) {
if (_recvIndex > 3 && _recvIndex >= (3 + _recvBuffer[2])) {
if (_debug) {
dumpPkt("HCI EVENT RX <- ", _recvIndex, _recvBuffer);
}
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
digitalWrite(NINA_RTS, HIGH);
#endif
// received full event
int pktLen = _recvIndex - 1;
_recvIndex = 0;
handleEventPkt(pktLen, &_recvBuffer[1]);
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
digitalWrite(NINA_RTS, LOW);
#endif
}
} else {
_recvIndex = 0;
if (_debug) {
_debug->println(b, HEX);
}
}
//Edit
if (_debug) {
_debug->print("WE ");
}
//
}
#ifdef ARDUINO_AVR_UNO_WIFI_REV2
digitalWrite(NINA_RTS, HIGH);
#endif
//Edit
if (_debug) {
_debug->print("PE ");
}
//
}
My first suspicion was the Neopixel libraries I am using as the code “seemed” to fare better when it wasn’t included. So I began tracking when the NeoPixelBus lib would update and I found that during the while loops it wouldn’t update. Most of the time the pixels aren’t updated during the while loop, however, on occasion, the while loop will activate and read data but not trigger an HCI Event and the Neopixel update is triggered. Furthermore, once I started tracking the _recvIndex I noticed that there are occasions of outbounds/overflow cases where the _recvIndex goes above the 258 length of _recvBuffer. I am not sure if this is caused by the use of the NeoPixelBus or similar library but I suspect that this is the cause of the crash. I have no idea how this happens but I am assuming that somehow it passes into one the if criteria such as:
if (_recvBuffer[0] == HCI_ACLDATA_PKT) {
or
_recvBuffer[0] == HCI_EVENT_PKT
But doesn’t fulfill the subsequent if cases and the hops back out, skipping the _recvIndex = 0. Then _recvIndex++ just stacks up and up and crashes at 533.
So I added a small if statement to catch this:
if(_recvIndex > 257){
_recvIndex = 0;
}
Is there anything I missed that might be causing this? I have added an extract of my logs showing where the error starts and ends as well as my code for trying to cause the crash. Also, should I raise this on the GitHub?
Thank you for your time.
Matt
Error_Log.txt (246 KB)
Crash_Testing.ino (5.15 KB)