mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 19:45:09 +00:00
feat(tx): тихий детектор голодания очереди TX
Всплеск, рождённый нашим трактом, невозможен без одного события: очередь DUC
простаивает дольше подушки отправителя (DUC_FIFO_THROTTLE = 2000 отсчётов при
192 кГц = 10.42 мс). Съём 2026-08-21 это показал прямо: шесть всплесков — шесть
простоев 10.3-23.5 мс, а паузы 8 мс и короче не дали ни одного. Значит счётчик
таких простоев — полный детектор «наш/не наш», и оператору больше не нужно
называть интервал на глаз.
Новый юнит TxHealth.pas. Включён всегда: переменной окружения нет намеренно —
прибор, который надо не забыть включить, к моменту дефекта выключен.
* поток отправителя DUC мерит каждый простой очереди на передаче — одно чтение
монотонных часов на ПЕРЕХОД, ни файлов, ни локов (обе ветки, win и unix);
* планировщик TCI публикует рядом состояние пейсинга (аванс, долг, в полёте,
квант, шаг, период пачек клиента) — простыми записями, без лока: числа
диагностические, а лок в потоке отправителя DUC недопустим для тайминга;
* сетевой поток считает бит HPS_FIFO_EMPTY из HP-статуса радио — поле ГЛУБИНЫ
FIFO на этой прошивке статично (256) и веры ему нет, а бит мы не читали вовсе;
* ★журнал пишет ТОЛЬКО потребитель — таймер UI (100 мс) и цикл демона через
TxHealthService. В тракте передачи диска нет по построению.
Последнее — правило, оплаченное регрессом: прошлый прибор (TxTrace) сбрасывал
дамп синхронно в хвосте SetMOX, и эти десятки миллисекунд закрывали гонку в
пейсинге TCI (лечение — fa38fa7). Инструмент чинил дефект собой.
Журнал ~/.config/ewsdr/txhealth.log, строка на передачу: «чисто» либо «ОПАСНО
(первое на N мс)» плюс подробности с контекстом пейсинга. В статусной строке
UI — «·сухо N» за сеанс, чтобы не помнить, какая посылка была плохой.
Стенд: секция G в test/tci (порог подушки, сводка, момент от фронта PTT,
контекст рядом с событием, молчание вне передачи) — 276/276. Диск стенд не
трогает намеренно: берёт сводки через TxHealthTake/TxHealthDetail, мимо
TxHealthService, иначе писал бы в настоящий журнал пользователя.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bkwwyj7xVRrqnSVEseTRfV
This commit is contained in:
+17
-5
@@ -40,7 +40,7 @@ uses
|
||||
PanZoomBar, PanafallPanel, PanDisplayPopup, PureSignalPopup, FlatPopupMenu,
|
||||
WidebandView,
|
||||
StatusBar,
|
||||
PlatformUtils,
|
||||
PlatformUtils, TxHealth,
|
||||
RadioModes,
|
||||
WinFirewall,
|
||||
BoardUtils, WisdomBuilder, UISync,
|
||||
@@ -3822,9 +3822,14 @@ var
|
||||
PeakTarget, MinTarget: Double;
|
||||
PeakDiff, MinDiff: Double;
|
||||
PeakAlpha, MinAlpha: Double;
|
||||
TxhSuffix: string;
|
||||
begin
|
||||
// Затухание спотов не зависит от того, крутится ли приём.
|
||||
ServiceDXCluster;
|
||||
// Детектор голодания очереди TX: сводки за прошедшие передачи → журнал.
|
||||
// ★Это ЕДИНСТВЕННОЕ место, где прибор трогает диск, и оно намеренно вынесено
|
||||
// из тракта передачи в таймер UI (см. TxHealth.pas).
|
||||
TxHealthService;
|
||||
|
||||
if not FController.FRunning then
|
||||
begin
|
||||
@@ -3877,17 +3882,24 @@ begin
|
||||
|
||||
if FController.FWDSPReady then
|
||||
begin
|
||||
// Опасные простои очереди TX за сеанс: столько раз очередь пустела дольше
|
||||
// подушки отправителя, то есть столько раз в эфир могла уйти голая несущая.
|
||||
// Ноль — значит всплеск, если он был виден, родился НЕ в нашем тракте.
|
||||
if TxHealthDangerTotal > 0 then
|
||||
TxhSuffix := Format(' ·сухо %d', [TxHealthDangerTotal])
|
||||
else
|
||||
TxhSuffix := '';
|
||||
if FController.FTransmitting then
|
||||
begin
|
||||
case FController.FDSPEngine.TXMicSource of
|
||||
txmsSoundCard: SetStatusText(5, 'TX sound card');
|
||||
txmsWeb: SetStatusText(5, 'TX web mic');
|
||||
txmsSoundCard: SetStatusText(5, 'TX sound card' + TxhSuffix);
|
||||
txmsWeb: SetStatusText(5, 'TX web mic' + TxhSuffix);
|
||||
else
|
||||
SetStatusText(5, 'TX radio mic');
|
||||
SetStatusText(5, 'TX radio mic' + TxhSuffix);
|
||||
end;
|
||||
end
|
||||
else
|
||||
SetStatusText(5, 'TX idle');
|
||||
SetStatusText(5, 'TX idle' + TxhSuffix);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user