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:
co-authored by
GitHub
Ben Meadors
parent
a5523b04ef
commit
8feb34e7a8
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
Reference in New Issue
Block a user