RadioLib edge-triggered interrupts robustness (#9658)

* Fix potential race condition (read, ISR write, clear) in NotifiedWorkerThread

* Check for missed edge-triggered interrupts race condition between startReceive and enableInterrupt

* Occasionally poll to catch missed RX_DONE interrupts. (RadioLibInterface::pollMissedIrqs)

* Simplify RadioLibInterface::checkRxDoneIrqFlag()

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
Mike Robbins
2026-02-21 06:14:04 -06:00
committed by GitHub
co-authored by GitHub Ben Meadors
parent a5523b04ef
commit 8feb34e7a8
9 changed files with 41 additions and 3 deletions
+4 -2
View File
@@ -76,8 +76,10 @@ bool NotifiedWorkerThread::notifyLater(uint32_t delay, uint32_t v, bool overwrit
void NotifiedWorkerThread::checkNotification()
{
auto n = notification;
notification = 0; // clear notification
// Atomically read and clear. (This avoids a potential race condition where an interrupt handler could set a new notification
// after checkNotification reads but before it clears, which would cause us to miss that notification until the next one comes
// in.)
auto n = notification.exchange(0); // read+clear atomically: like `n = notification; notification = 0;` but interrupt-safe
if (n) {
onNotify(n);
}
+2 -1
View File
@@ -1,6 +1,7 @@
#pragma once
#include "OSThread.h"
#include <atomic>
namespace concurrency
{
@@ -13,7 +14,7 @@ class NotifiedWorkerThread : public OSThread
/**
* The notification that was most recently used to wake the thread. Read from runOnce()
*/
uint32_t notification = 0;
std::atomic<uint32_t> notification{0};
public:
NotifiedWorkerThread(const char *name) : OSThread(name) {}