mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-09-18 19:13:58 +00:00
fix(ir-dma): volatile active + errorCount() observability; live poll() in longData example
- IrDmaTxStm32.h: TxStream::active -> volatile (делится поток<->ISR: busy()/poll()/колбэки/спин applyCarrierMultiply) - IrDmaTxStm32.h: + volatile errors_ и errorCount(), инкремент в dmaErrorCb (наблюдаемость Transfer-Error) - test_examples/longData: dmaBackend.poll() в loop, иначе watchdog завершения DMA мёртв в эталонном примере Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -160,6 +160,8 @@ public:
|
|||||||
void setStallTimeoutMs(uint32_t ms) { if (ms != 0U) stallTimeoutMs_ = ms; }
|
void setStallTimeoutMs(uint32_t ms) { if (ms != 0U) stallTimeoutMs_ = ms; }
|
||||||
/** Сколько раз watchdog аварийно восстановил залипший поток (наблюдаемость/логи). */
|
/** Сколько раз watchdog аварийно восстановил залипший поток (наблюдаемость/логи). */
|
||||||
uint32_t recoveryCount() const { return recoveries_; }
|
uint32_t recoveryCount() const { return recoveries_; }
|
||||||
|
/** Сколько раз DMA-передача завершилась по Transfer-Error (наблюдаемость/логи). */
|
||||||
|
uint32_t errorCount() const { return errors_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TxStream {
|
struct TxStream {
|
||||||
@ -191,7 +193,7 @@ private:
|
|||||||
uint32_t lastTicks = 0;
|
uint32_t lastTicks = 0;
|
||||||
uint32_t lastProgressMs = 0;
|
uint32_t lastProgressMs = 0;
|
||||||
|
|
||||||
bool active = false;
|
volatile bool active = false; // Fix: делится поток<->ISR (busy()/poll()/колбэки/спин applyCarrierMultiply) — запрет кэширования компилятором
|
||||||
|
|
||||||
void resetWave() {
|
void resetWave() {
|
||||||
wave.configure(setWord, resetWord, nullptr, 0, 2, 1);
|
wave.configure(setWord, resetWord, nullptr, 0, 2, 1);
|
||||||
@ -228,6 +230,7 @@ private:
|
|||||||
// Fix C: разделяемый activeCount_ удалён — он и был источником гонки поток↔ISR.
|
// Fix C: разделяемый activeCount_ удалён — он и был источником гонки поток↔ISR.
|
||||||
uint32_t stallTimeoutMs_ = 100; // Fix D
|
uint32_t stallTimeoutMs_ = 100; // Fix D
|
||||||
uint32_t recoveries_ = 0; // Fix D (только контекст потока)
|
uint32_t recoveries_ = 0; // Fix D (только контекст потока)
|
||||||
|
volatile uint32_t errors_ = 0; // Fix #5: счётчик Transfer-Error (пишется в ISR dmaErrorCb, читается из потока)
|
||||||
|
|
||||||
static uint32_t u32ptr(const volatile void* p) {
|
static uint32_t u32ptr(const volatile void* p) {
|
||||||
return (uint32_t)(uintptr_t)p;
|
return (uint32_t)(uintptr_t)p;
|
||||||
@ -292,6 +295,7 @@ private:
|
|||||||
if (s == nullptr || !s->active) return; // симметрично HT/CPLT: одиночный stop, без двойного finish
|
if (s == nullptr || !s->active) return; // симметрично HT/CPLT: одиночный stop, без двойного finish
|
||||||
s->onError();
|
s->onError();
|
||||||
if (s_instance != nullptr) {
|
if (s_instance != nullptr) {
|
||||||
|
s_instance->errors_++; // Fix #5: наблюдаемость аварийных завершений по Transfer-Error
|
||||||
s_instance->stopStream(*s);
|
s_instance->stopStream(*s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -132,6 +132,7 @@ void setup() {
|
|||||||
void loop() {
|
void loop() {
|
||||||
#if LONGDATA_USE_DMA
|
#if LONGDATA_USE_DMA
|
||||||
IR_Encoder::tick();
|
IR_Encoder::tick();
|
||||||
|
dmaBackend.poll(); // Fix D: watchdog завершения DMA-передачи (как в Car/src/IR/IR.cpp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const uint32_t now = millis();
|
const uint32_t now = millis();
|
||||||
|
|||||||
Reference in New Issue
Block a user