arduino-libraries/ArduinoBLE

Intermittent `Unhandled event` and panic in HCIClass::Poll

trylaarsdam opened this issue · 0 comments

I'm working with the ArduinoBLE library on the Portenta H7, and encountering a hard fault occasionally while listening for data. This happens between 5-30min after the device starts, and as such it's a bit of a nightmare to debug.

This is the situation: I am receiving data as a central connected to 1 peripheral device at about 1kB/s, and I am currently not using interrupts to receive data by registering the characteristic with a BLEUpdated event. I had some other issues with threading and memory access, so to make sure I converted my firmware to not use any user mbed threads and managing time slicing myself.

This results in the BLE thread being called extremely quickly (1000Hz) for most of the time, and then every 2 seconds I have a function which computes an FFT and does some math on the data received over BLE (what the BLT_PARSE::rxBuffer ringbuffer handles in the code below). The longest I believe BLE.poll goes without being called is approximately 38ms, which I think should be plenty to not overrun the library's internal RX buffer of 256 bytes (and I am not seeing any buffer overrun errors when I have logging enabled).

The hard fault happens when an [Info] Unhandled event is logged, and then two calls to HCIClass::handleAclDataPkt are made, the second of which creates a hard fault.

I'm a bit stuck here with how to proceed, so any ideas or pointers on what could be happening would be appreciated.

Receive function:

		Central::peripheral.poll();
		if(!Central::peripheral.connected())
		{
			warn("BLE_Central", "Disconnected from device, reconnecting");
			Central::scanAndConnect();
		}
		else
		{
			if(Central::peripheral.characteristic(BLE_RX_UUID).valueUpdated())
			{
				// read the data
				uint8_t* head = BLT_PARSE::rxBuffer.getHead();
				uint16_t packetLength = Central::peripheral.characteristic(BLE_RX_UUID).valueLength();

				// log data from characteristic
				if(packetLength > 256) {
					warn("BLE_Central", "Packet length > 256 : " + String(packetLength) + ", truncating to 256");
					packetLength = 256;
				}
				Central::peripheral.characteristic(BLE_RX_UUID).readValue(Central::packet, packetLength);

				for(int i = 0; i < packetLength; i++)
				{
					// slice full, increment and continue
					if(Central::bufferSlicePosition >= DEVICE_BUFFER_SLICE_SIZE) 
					{
						Central::bufferSlicePosition = 0;
						BLT_PARSE::rxBuffer.incrementHead();
						head = BLT_PARSE::rxBuffer.getHead();
					}

					// write to buffer
					head[Central::bufferSlicePosition] = Central::packet[i];
					Central::bufferSlicePosition++;
				}

				// Central::peripheral.characteristic(BLE_RX_UUID).valueUpdated();
			}
		}

BLE library logging:

HCI event: FF
[Info] Unhandled event
Don't have full packet yet
Handle: 0x41, 0x20
dlen: 0xF3, 0x0
len: 0xF2, 0x0
cid: 0x4, 0x0
Don't have full packet yet
Handle: 0x41, 0x20
dlen: 0xFF, 0x0
len: 0xF2, 0x0
cid: 0x4, 0x0

Mbed crash log:

Crash Info:
	Crash location = HCIClass::poll(unsigned long) [0x08049FD8] (based on PC value)
	Caller location = HCIClass::handleAclDataPkt(unsigned char, unsigned char*) [0x0804A145] (based on LR value)
	Stack Pointer at the time of crash = [24014228]
	Target and Fault Info:
		Processor Arch: ARM-V7M or above
		Processor Variant: C27
		Forced exception, a fault with configurable priority has been escalated to HardFault
		A precise data access error has occurred. Faulting address: 1B940A1A