I have a system where the BLE stack occasionally gets stuck inside of CyBle_GattsWriteRsp(). I've managed to trace the execution until it enters this function and confirmed that it doesn't return until the system watchdog resets after a few hundred milliseconds.
Here's how the project is structured:
- Main loop performs operations such as I2C and CyBle_ProcessEvents().
- SysTick performs short periodic actions every 1ms. (Priority: 2)
- DMA interrupt performs a few milliseconds of buffer processing around every ~10ms. (Priority: 3)
- BLE BLESS interrupt has priority 2.
There are three watchdogs active,
- Main Loop (256ms timeout)
- SysTick (4ms)
- DMA Interrupt (32ms)
All watchdogs trigger the general watchdog interrupt when they expire. My handler prints which timer expired and then loops. The watchdogs trigger a hardware reset if the watchdog interrupt isn't handled three times, I cause this by never exiting the handler once triggered. (nearly same as a direct watchdog triggered reset, but allows me to print out system state)
The BLE minimum connection interval I'm using is 30ms. I verified that CyBle_ProcessEvents() gets called multiple times within the connection interval, even when pending I2C actions and interrupts queue up together. It typically gets called around every 5-10ms at the longest.
I traced through the system and found that CyBle_ProcessEvents() calls the registered BLE event handler passed on stack init. The issue seems to be fairly rare, but occasionally when I process a CYBLE_EVT_GATTS_WRITE_REQ event, program execution enters the CyBle_GattsWriteRsp() call and remains there until the 256ms main loop watchdog resets the system. Note that interrupts are operating correctly since their watchdogs aren't what resets the system.
I can't check error flags returned from the BLE stack since the function never returns. My SysTick interrupt does occasionally call CyBle_GattsWriteAttributeValue() and CyBle_GattsNotification() and I thought that one of these occurring when main is in CyBle_ProcessEvents() could be causing the lockup. I instrumented the system so I could see when these calls occur and it doesn't appear that the lockup is triggered by one of these functions being called from an interrupt during CyBle_GattsWriteRsp().
I think that the lockup is a symptom of a larger issue with how I am handling the BLE stack. Sometimes the device momentarily delays or stops responding to BLE connections even though CyBle_ProcessEvents() is still being called regularly.
If anyone has any ideas to try I would be really grateful, I can't post the actual project here but I'm providing a stripped version of my BLE handler C file.
ble_ops_stripped.c.zip 2.1 K