mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-09-18 19:13:58 +00:00
B5 (MEDIUM): RingBuffer::pop(T&) копирует под одной критсекцией; tick() перешёл на неё → нет торн-рида (внутренний interrupts() в T* pop снимал внешнюю защиту до чтения *ptr). T* pop() оставлен (не используется). B6 (MEDIUM): убрана лишняя noInterrupts/interrupts вокруг micros() в EXTI-ISR (снимала PRIMASK посреди ISR). std::function-диспетчеризация attachInterrupt — структурна, не трогаю. B7 (LOW): скобки в crcCheck (== & 0xFF по приоритету). B10 (LOW): guard деления на 0 в ceil_div (актуально только при freeFrec — НЕ включаю). send: sendDataFULL — валидация полного packSize<=31 (было len>bytePerPack=31, packSize=7+len оборачивался → тихая потеря Data payload 25..31). B8 (isSubBufferOverflow) — уже volatile, потеря флага безвредна (диагностика), не трогаю. B9 (prevRise==0 при micros()==0) — уже обработан веткой в preambleProcessEdge, намеренно. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
57 lines
1.6 KiB
C++
57 lines
1.6 KiB
C++
#pragma once
|
||
#include "Arduino.h"
|
||
template <typename T, unsigned int BufferSize>
|
||
class RingBuffer {
|
||
public:
|
||
RingBuffer() : start(0), end(0) {}
|
||
|
||
bool isFull() const {
|
||
return ((end + 1) % BufferSize) == start;
|
||
}
|
||
|
||
bool isEmpty() const {
|
||
return start == end;
|
||
}
|
||
|
||
bool push(T element) {
|
||
bool pushed = false;
|
||
noInterrupts();
|
||
if (!isFull()) {
|
||
data[end] = element;
|
||
end = (end + 1) % BufferSize;
|
||
pushed = true;
|
||
}
|
||
interrupts();
|
||
return pushed;
|
||
}
|
||
|
||
T* pop() {
|
||
noInterrupts();
|
||
T* value = nullptr;
|
||
if (!isEmpty()) {
|
||
value = &data[start];
|
||
start = (start + 1) % BufferSize;
|
||
}
|
||
interrupts();
|
||
return value;
|
||
}
|
||
|
||
// B5: безопасный pop — копирует элемент под ОДНОЙ критсекцией и отдаёт по значению.
|
||
// (T* pop() отдаёт указатель во внутренний слот; его внутренний interrupts() снимает внешнюю
|
||
// защиту вызывающего ДО чтения *ptr → торн-рид, если кольцо переполнится в этом окне.)
|
||
bool pop(T &out) {
|
||
bool popped = false;
|
||
noInterrupts();
|
||
if (!isEmpty()) {
|
||
out = data[start];
|
||
start = (start + 1) % BufferSize;
|
||
popped = true;
|
||
}
|
||
interrupts();
|
||
return popped;
|
||
}
|
||
|
||
private:
|
||
T data[BufferSize];
|
||
unsigned int start, end;
|
||
}; |