mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-09-18 19:13:58 +00:00
perf(rx): батч-выемка фронтов в tick (IR_RX_TICK_BATCH=16) — приём развязан от частоты loop
Было: 1 сырой фронт за tick() -> RX-пропускная способность привязана к loop; медленный loop (телеметрия/дисплей/КУ-печать) переполнял ISR-буфер 250 фронтов (~120мс эфира) и кадры гибли молча (вероятная составляющая 'КУ отвечает не на каждый пакет'). Стало: до IR_RX_TICK_BATCH фронтов за tick; idle-семантика сохранена (flush пульс-фильтра только при пустом буфере; listenStart/ checkTimeout как раньше). Переопределяемо дефайном до include. Компил-чек: LaserTestCheck (G491) собирается. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -402,11 +402,15 @@ void IR_DecoderRaw::tick()
|
|||||||
|
|
||||||
FrontStorage rawFront;
|
FrontStorage rawFront;
|
||||||
bool processedFront = false;
|
bool processedFront = false;
|
||||||
const bool hasRawFront = subBuffer.pop(rawFront); // B5: копия под одной критсекцией (без торн-рида)
|
// Батч-выемка (IR_RX_TICK_BATCH): раньше 1 фронт/tick — приём был привязан
|
||||||
|
// к частоте loop, буфер 250 фронтов (~120мс эфира) переполнялся на медленном
|
||||||
if (IR_INPUT_MIN_PULSE_US > 0U)
|
// loop и кадры гибли молча. Семантика idle-пути сохранена: flush
|
||||||
|
// пульс-фильтра — только когда буфер пуст (как прежняя else-ветка).
|
||||||
|
uint8_t batchBudget = IR_RX_TICK_BATCH;
|
||||||
|
bool hasRawFront = subBuffer.pop(rawFront); // B5: копия под одной критсекцией (без торн-рида)
|
||||||
|
while (hasRawFront)
|
||||||
{
|
{
|
||||||
if (hasRawFront)
|
if (IR_INPUT_MIN_PULSE_US > 0U)
|
||||||
{
|
{
|
||||||
pulseFilterPushRaw(rawFront);
|
pulseFilterPushRaw(rawFront);
|
||||||
FrontStorage confirmedFront;
|
FrontStorage confirmedFront;
|
||||||
@ -418,19 +422,24 @@ void IR_DecoderRaw::tick()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const uint32_t nowUs = micros();
|
processDecodedFront(rawFront);
|
||||||
FrontStorage confirmedFront;
|
processedFront = true;
|
||||||
while (pulseFilterTryFlushOne(nowUs, confirmedFront))
|
|
||||||
{
|
|
||||||
processDecodedFront(confirmedFront);
|
|
||||||
processedFront = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (--batchBudget == 0U)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hasRawFront = subBuffer.pop(rawFront);
|
||||||
}
|
}
|
||||||
else if (hasRawFront)
|
if (!hasRawFront && IR_INPUT_MIN_PULSE_US > 0U)
|
||||||
{
|
{
|
||||||
processDecodedFront(rawFront);
|
const uint32_t nowUs = micros();
|
||||||
processedFront = true;
|
FrontStorage confirmedFront;
|
||||||
|
while (pulseFilterTryFlushOne(nowUs, confirmedFront))
|
||||||
|
{
|
||||||
|
processDecodedFront(confirmedFront);
|
||||||
|
processedFront = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!processedFront)
|
if (!processedFront)
|
||||||
|
|||||||
@ -179,6 +179,13 @@ typedef uint16_t crc_t;
|
|||||||
#ifndef IR_INPUT_MIN_PULSE_US
|
#ifndef IR_INPUT_MIN_PULSE_US
|
||||||
#define IR_INPUT_MIN_PULSE_US 0
|
#define IR_INPUT_MIN_PULSE_US 0
|
||||||
#endif
|
#endif
|
||||||
|
/** Сколько сырых фронтов забирать из ISR-буфера за один tick() (батч-выемка).
|
||||||
|
* 1 фронт/tick привязывал RX-пропускную способность к частоте loop: медленный
|
||||||
|
* loop (телеметрия/дисплей) переполнял буфер 250 фронтов (~120мс эфира) и
|
||||||
|
* кадры терялись молча. Батч развязывает приём от темпа loop. */
|
||||||
|
#ifndef IR_RX_TICK_BATCH
|
||||||
|
#define IR_RX_TICK_BATCH 16U
|
||||||
|
#endif
|
||||||
/** Сколько подтверждённых фронтов держать перед выпуском в декодер (потоковая задержка). */
|
/** Сколько подтверждённых фронтов держать перед выпуском в декодер (потоковая задержка). */
|
||||||
#ifndef IR_INPUT_FILTER_HOLDBACK_EDGES
|
#ifndef IR_INPUT_FILTER_HOLDBACK_EDGES
|
||||||
#define IR_INPUT_FILTER_HOLDBACK_EDGES 3U
|
#define IR_INPUT_FILTER_HOLDBACK_EDGES 3U
|
||||||
|
|||||||
Reference in New Issue
Block a user