mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
chore(tx): сняты зонды трассировки — пейсинг проверен на железе
Всплесков на передаче нет, инструмент своё отработал и больше не нужен в горячем пути. Снято ровно то, что ставилd209697, и ничего сверх: * удалён юнит TxTrace.pas (кольцо + сброс дампа + TraceInit); * TCIAdapter: точки съёма маркеров и TX-аудио, поля FTxTraceLast/FTxTraceAudio; * HPSDRNetwork: DUC-DRY/DUC-RUN и переменная DryFrom (жила только для них), вместе с ними ушли из uses TxTrace и PlatformUtils — их добавлял тот же коммит, MonotonicUs в этом файле больше нигде не встречается; * RadioController: PTT-метка в SetMOX и сброс дампа на снятии PTT; * TraceInit из ewsdr.lpr и ewsdrd.lpr. Каждая удалённая строка стояла под `if TraceOn` — вычислений, от которых зависит тракт, в них не было. ★PlatformUtils.MonotonicUs НЕ тронут: на нём абсолютные дедлайны планировщика TX, это не отладка. Скрипт разбора test/hpsdr/txtrace_scan.py оставлен, формат дампа не менялся; в README стенда записан рецепт возврата зондов изd209697. Проверено: lazbuild --ws=qt6 и build-ewsdrd.sh собираются, test/tci 260/260, test/cat 50/50 — те же числа, что и с зондами. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bkwwyj7xVRrqnSVEseTRfV
This commit is contained in:
+1
-15
@@ -19,7 +19,7 @@ uses
|
|||||||
{$ELSE}
|
{$ELSE}
|
||||||
Sockets, BaseUnix,
|
Sockets, BaseUnix,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
HPSDRProtocol, SyncObjs, Settings, RadioBackend, TxTrace, PlatformUtils;
|
HPSDRProtocol, SyncObjs, Settings, RadioBackend;
|
||||||
|
|
||||||
const
|
const
|
||||||
DUC_TX_QUEUE_SIZE = 256; // power of two, bounded latency on TX underrun/overrun
|
DUC_TX_QUEUE_SIZE = 256; // power of two, bounded latency on TX underrun/overrun
|
||||||
@@ -509,7 +509,6 @@ var
|
|||||||
NowTick: QWord;
|
NowTick: QWord;
|
||||||
ElapsedMs: QWord;
|
ElapsedMs: QWord;
|
||||||
WaitMs: Integer;
|
WaitMs: Integer;
|
||||||
DryFrom: Int64; // приборы: начало простоя очереди, мкс
|
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
{$IFDEF WINDOWS}
|
{$IFDEF WINDOWS}
|
||||||
@@ -581,18 +580,12 @@ begin
|
|||||||
{$ELSE}
|
{$ELSE}
|
||||||
VirtualSamples := 0;
|
VirtualSamples := 0;
|
||||||
LastTick := GetTickCount64;
|
LastTick := GetTickCount64;
|
||||||
DryFrom := 0;
|
|
||||||
|
|
||||||
while not Terminated do
|
while not Terminated do
|
||||||
begin
|
begin
|
||||||
if not FNet.DequeueDUCIQ(Pkt) then
|
if not FNet.DequeueDUCIQ(Pkt) then
|
||||||
begin
|
begin
|
||||||
DrainVirtualFIFO;
|
DrainVirtualFIFO;
|
||||||
if TraceOn and FNet.FIsTransmitting and (DryFrom = 0) then
|
|
||||||
begin
|
|
||||||
DryFrom := MonotonicUs;
|
|
||||||
TR(trkDucDry, VirtualSamples, FNet.FDUCIQCount);
|
|
||||||
end;
|
|
||||||
// Очередь пуста. НЕ инжектируем нулевые пакеты — 1.25мс тишины прямо
|
// Очередь пуста. НЕ инжектируем нулевые пакеты — 1.25мс тишины прямо
|
||||||
// в поток сэмплов = разрыв данных = всплеск на водопаде/в эфире. Как
|
// в поток сэмплов = разрыв данных = всплеск на водопаде/в эфире. Как
|
||||||
// dl1ycf pihpsdr (txiq_thread: пустая очередь → просто sem_wait): ждём
|
// dl1ycf pihpsdr (txiq_thread: пустая очередь → просто sem_wait): ждём
|
||||||
@@ -611,13 +604,6 @@ begin
|
|||||||
if not FNet.FIsTransmitting then
|
if not FNet.FIsTransmitting then
|
||||||
Continue;
|
Continue;
|
||||||
|
|
||||||
if TraceOn and (DryFrom <> 0) then
|
|
||||||
begin
|
|
||||||
TR(trkDucRun, Integer(MonotonicUs - DryFrom), VirtualSamples,
|
|
||||||
FNet.FDUCIQCount);
|
|
||||||
DryFrom := 0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
FNet.PackSeqBytes(Pkt.Seq, FNet.NextSeq(FNet.FSeqDUCIQ));
|
FNet.PackSeqBytes(Pkt.Seq, FNet.NextSeq(FNet.FSeqDUCIQ));
|
||||||
FNet.DoSendTo(FNet.FSocket, Pkt, SizeOf(Pkt), FNet.FDevice.IPAddress,
|
FNet.DoSendTo(FNet.FSocket, Pkt, SizeOf(Pkt), FNet.FDevice.IPAddress,
|
||||||
FNet.FPortDUCIQ);
|
FNet.FPortDUCIQ);
|
||||||
|
|||||||
+1
-5
@@ -51,7 +51,7 @@ uses
|
|||||||
HPSDRProtocol, HPSDRNetwork, RadioBackend, PlutoBackend, IIOBindings,
|
HPSDRProtocol, HPSDRNetwork, RadioBackend, PlutoBackend, IIOBindings,
|
||||||
WDSPEngine, AudioOutput, AudioInput, BeaconDecoder, BeaconFEC, DMRDecoder,
|
WDSPEngine, AudioOutput, AudioInput, BeaconDecoder, BeaconFEC, DMRDecoder,
|
||||||
Settings, ChannelStore, FMRepeater, BoardUtils, DeviceStore, CWMorse, CWKeyer,
|
Settings, ChannelStore, FMRepeater, BoardUtils, DeviceStore, CWMorse, CWKeyer,
|
||||||
CWDecoder, TxTrace;
|
CWDecoder;
|
||||||
|
|
||||||
// Панадаптеры (этап 3): потолок MAX_PANS живёт в WDSPEngine (общий для
|
// Панадаптеры (этап 3): потолок MAX_PANS живёт в WDSPEngine (общий для
|
||||||
// движка/контроллера/UI). Фактический лимит бэкенда — Caps.MaxPans (Pluto=1).
|
// движка/контроллера/UI). Фактический лимит бэкенда — Caps.MaxPans (Pluto=1).
|
||||||
@@ -6303,9 +6303,6 @@ begin
|
|||||||
// прекратить — ключ обязан отпуститься немедленно.
|
// прекратить — ключ обязан отпуститься немедленно.
|
||||||
if (not On_) and CWXBusy then CWXAbort;
|
if (not On_) and CWXBusy then CWXAbort;
|
||||||
FTransmitting := On_;
|
FTransmitting := On_;
|
||||||
if TraceOn and (On_ <> WasTransmitting) then
|
|
||||||
if Assigned(FDSPEngine) then TR(trkPtt, Ord(On_), Ord(FDSPEngine.TXMicSource))
|
|
||||||
else TR(trkPtt, Ord(On_), -1);
|
|
||||||
// 2TON: прямое снятие MOX (кнопкой/CAT/web) гасит и двухтональник.
|
// 2TON: прямое снятие MOX (кнопкой/CAT/web) гасит и двухтональник.
|
||||||
if (not On_) and FTwoTone then
|
if (not On_) and FTwoTone then
|
||||||
begin
|
begin
|
||||||
@@ -6446,7 +6443,6 @@ begin
|
|||||||
// (оператор держит T/R руками) — вооружение обязано пойти за этой кнопкой.
|
// (оператор держит T/R руками) — вооружение обязано пойти за этой кнопкой.
|
||||||
SyncCWKeyer;
|
SyncCWKeyer;
|
||||||
Changed(rfTransmitting);
|
Changed(rfTransmitting);
|
||||||
if TraceOn and WasTransmitting and (not On_) then TraceDump('tx');
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TRadioController.SetTune(On_: Boolean);
|
procedure TRadioController.SetTune(On_: Boolean);
|
||||||
|
|||||||
+1
-21
@@ -44,7 +44,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, DateUtils, Math, SyncObjs,
|
Classes, SysUtils, DateUtils, Math, SyncObjs,
|
||||||
RadioController, RadioBackend, WDSPEngine, Settings, PlatformUtils,
|
RadioController, RadioBackend, WDSPEngine, Settings, PlatformUtils,
|
||||||
DXSpotStore, TCIProtocol, TCIServer, TCIStreams, TxTrace;
|
DXSpotStore, TCIProtocol, TCIServer, TCIStreams;
|
||||||
|
|
||||||
const
|
const
|
||||||
// ★Приёмник TCI: 0 — главный тракт (каналы A/B = VFO A/B), N — слайс СЛОТА
|
// ★Приёмник TCI: 0 — главный тракт (каналы A/B = VFO A/B), N — слайс СЛОТА
|
||||||
@@ -242,8 +242,6 @@ type
|
|||||||
FTxLeadKeep: Integer; // ★он же, но ПЕРЕЖИВАЮЩИЙ конец передачи
|
FTxLeadKeep: Integer; // ★он же, но ПЕРЕЖИВАЮЩИЙ конец передачи
|
||||||
FTxLeadRate: Integer; // частота, при которой аванс измерен
|
FTxLeadRate: Integer; // частота, при которой аванс измерен
|
||||||
FTxLeadLowUs: Int64; // с какого момента оценка держится НИЖЕ аванса
|
FTxLeadLowUs: Int64; // с какого момента оценка держится НИЖЕ аванса
|
||||||
FTxTraceLast: Int64; // приборы: время прошлого маркера
|
|
||||||
FTxTraceAudio: Int64; // приборы: время прошлого блока аудио
|
|
||||||
FTxLastRxUs: Int64; // когда пришёл прошлый блок (границы пачек)
|
FTxLastRxUs: Int64; // когда пришёл прошлый блок (границы пачек)
|
||||||
// Рабочие буферы разбора TX-блока. Полем, а не на стеке: развёрнутый в
|
// Рабочие буферы разбора TX-блока. Полем, а не на стеке: развёрнутый в
|
||||||
// 48 кГц блок — это сотни килобайт, и класть их в стек потока клиента
|
// 48 кГц блок — это сотни килобайт, и класть их в стек потока клиента
|
||||||
@@ -3754,7 +3752,6 @@ begin
|
|||||||
|
|
||||||
TCIFillHeader(H, tstTXChrono, Rx, Rate, ST, Q, Chans);
|
TCIFillHeader(H, tstTXChrono, Rx, Rate, ST, Q, Chans);
|
||||||
Client.SendBinNow(H);
|
Client.SendBinNow(H);
|
||||||
if TraceOn then TR(trkNote, -4, Q, Rx);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTCIAdapter.TxPublishLead(Rate: Integer);
|
procedure TTCIAdapter.TxPublishLead(Rate: Integer);
|
||||||
@@ -3843,7 +3840,6 @@ begin
|
|||||||
try
|
try
|
||||||
if not Active then
|
if not Active then
|
||||||
begin
|
begin
|
||||||
if TraceOn and FTxRunning then TR(trkNote, -3, Round(FTxInFlight), 0);
|
|
||||||
FTxRunning := False;
|
FTxRunning := False;
|
||||||
FServer.TxTickPeriodMs := 0;
|
FServer.TxTickPeriodMs := 0;
|
||||||
Exit;
|
Exit;
|
||||||
@@ -3886,7 +3882,6 @@ begin
|
|||||||
(TCI_TX_LEAD_MAX_MS * Rate) div 1000);
|
(TCI_TX_LEAD_MAX_MS * Rate) div 1000);
|
||||||
if LeadWant > FTxLead then
|
if LeadWant > FTxLead then
|
||||||
begin
|
begin
|
||||||
if TraceOn then TR(trkNote, -2, LeadWant, FTxLead);
|
|
||||||
FTxLead := LeadWant;
|
FTxLead := LeadWant;
|
||||||
FTxLeadLowUs := 0;
|
FTxLeadLowUs := 0;
|
||||||
TxPublishLead(Rate);
|
TxPublishLead(Rate);
|
||||||
@@ -3899,7 +3894,6 @@ begin
|
|||||||
if FTxLeadLowUs = 0 then FTxLeadLowUs := NowUs
|
if FTxLeadLowUs = 0 then FTxLeadLowUs := NowUs
|
||||||
else if NowUs - FTxLeadLowUs > TCI_TX_LEAD_DOWN_MS * 1000 then
|
else if NowUs - FTxLeadLowUs > TCI_TX_LEAD_DOWN_MS * 1000 then
|
||||||
begin
|
begin
|
||||||
if TraceOn then TR(trkNote, -2, LeadWant, FTxLead);
|
|
||||||
FTxLead := LeadWant;
|
FTxLead := LeadWant;
|
||||||
FTxLeadLowUs := NowUs;
|
FTxLeadLowUs := NowUs;
|
||||||
TxPublishLead(Rate);
|
TxPublishLead(Rate);
|
||||||
@@ -3946,7 +3940,6 @@ begin
|
|||||||
begin
|
begin
|
||||||
// Прощаем ровно один квант и начинаем выдержку заново: поздний ответ
|
// Прощаем ровно один квант и начинаем выдержку заново: поздний ответ
|
||||||
// безопасен, он уведёт долг в минус и сам притормозит выдачу.
|
// безопасен, он уведёт долг в минус и сам притормозит выдачу.
|
||||||
if TraceOn then TR(trkNote, -1, Round(FTxInFlight), FTxWindowQ);
|
|
||||||
FTxInFlight := Max(0, FTxInFlight - Q);
|
FTxInFlight := Max(0, FTxInFlight - Q);
|
||||||
// ★Срок сдвигаем НА выдержку, а не на «сейчас». Зависших кредитов может
|
// ★Срок сдвигаем НА выдержку, а не на «сейчас». Зависших кредитов может
|
||||||
// быть несколько, и прощение по одному за выдержку живого времени
|
// быть несколько, и прощение по одному за выдержку живого времени
|
||||||
@@ -3984,13 +3977,6 @@ begin
|
|||||||
FTxInFlight := FTxInFlight + Q;
|
FTxInFlight := FTxInFlight + Q;
|
||||||
TxNoteRequest(NowUs);
|
TxNoteRequest(NowUs);
|
||||||
Inc(Sent);
|
Inc(Sent);
|
||||||
if TraceOn then
|
|
||||||
begin
|
|
||||||
if FTxTraceLast = 0 then FTxTraceLast := NowUs;
|
|
||||||
TR(trkChrono, Q, Round(FTxOwed - FTxInFlight),
|
|
||||||
Integer(NowUs - FTxTraceLast));
|
|
||||||
FTxTraceLast := NowUs;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
FTxLock.Leave;
|
FTxLock.Leave;
|
||||||
@@ -4104,12 +4090,6 @@ begin
|
|||||||
FTxProgressUs := NowUs;
|
FTxProgressUs := NowUs;
|
||||||
FTxArmed := True;
|
FTxArmed := True;
|
||||||
TxNoteReply(NowUs);
|
TxNoteReply(NowUs);
|
||||||
if TraceOn then
|
|
||||||
begin
|
|
||||||
if FTxTraceAudio = 0 then FTxTraceAudio := NowUs;
|
|
||||||
TR(trkTxAudio, Integer(NowUs - FTxTraceAudio), Integer(H.DataLength), k);
|
|
||||||
FTxTraceAudio := NowUs;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if (FTxInterp = nil) or (FTxInRate <> Rate) then
|
if (FTxInterp = nil) or (FTxInRate <> Rate) then
|
||||||
begin
|
begin
|
||||||
|
|||||||
-139
@@ -1,139 +0,0 @@
|
|||||||
unit TxTrace;
|
|
||||||
|
|
||||||
{
|
|
||||||
TxTrace.pas — кольцевая трассировка TX-тракта.
|
|
||||||
|
|
||||||
★Временный диагностический юнит. Выключен по умолчанию, включается
|
|
||||||
переменной окружения EWSDR_TXTRACE=1; при выключенной трассировке TR() —
|
|
||||||
одна проверка Boolean. Никакого ввода-вывода в горячем пути: кольцо
|
|
||||||
сбрасывается на диск в конце каждой передачи.
|
|
||||||
|
|
||||||
Зачем он снова здесь: всплески на передаче вернулись после того, как первая
|
|
||||||
редакция зондов была удалена, и без них видно только то, что видит глаз на
|
|
||||||
водопаде. Прибор смотрит ровно на подачу TX-аудио по TCI и на очередь DUC.
|
|
||||||
}
|
|
||||||
|
|
||||||
{$IFDEF FPC}
|
|
||||||
{$MODE Delphi}
|
|
||||||
{$ENDIF}
|
|
||||||
|
|
||||||
interface
|
|
||||||
|
|
||||||
const
|
|
||||||
trkPtt = 0; // A=1 старт передачи / 0 конец; B=источник модуляции
|
|
||||||
trkChrono = 7; // A=запрошено кадров; B=непокрытый долг; C=пауза от прошлого маркера, мкс
|
|
||||||
trkTxAudio = 8; // A=пауза от прошлого блока, мкс; B=length в шапке; C=кадров после интерполяции
|
|
||||||
trkDucDry = 10; // A=виртуальный уровень FIFO радио; B=глубина очереди
|
|
||||||
trkDucRun = 11; // A=длительность простоя очереди, мкс; B=уровень FIFO; C=глубина очереди
|
|
||||||
trkNote = 12; // A=-1 прощение кредита, -2 смена аванса, -3 в полёте на снятии PTT, -4 предварительный маркер
|
|
||||||
|
|
||||||
var
|
|
||||||
TraceOn: Boolean = False;
|
|
||||||
|
|
||||||
procedure TraceInit;
|
|
||||||
procedure TR(Kind: Integer; A: Integer = 0; B: Integer = 0; C: Integer = 0);
|
|
||||||
function TraceDump(const Reason: string): string;
|
|
||||||
|
|
||||||
implementation
|
|
||||||
|
|
||||||
uses
|
|
||||||
SysUtils, Math, PlatformUtils;
|
|
||||||
|
|
||||||
const
|
|
||||||
TRACE_SIZE = 16384;
|
|
||||||
TRACE_MASK = TRACE_SIZE - 1;
|
|
||||||
|
|
||||||
type
|
|
||||||
TTraceRec = record
|
|
||||||
T: Int64;
|
|
||||||
Kind: Integer;
|
|
||||||
A, B, C: Integer;
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
|
||||||
Ring: array[0..TRACE_SIZE - 1] of TTraceRec;
|
|
||||||
RingSeq: LongInt = 0;
|
|
||||||
Epoch: Int64 = 0;
|
|
||||||
|
|
||||||
const
|
|
||||||
TRACE_NAMES: array[0..12] of string = (
|
|
||||||
'PTT', 'RECV-GAP', 'HANDLER', 'HP-SYNC', 'WIDEBAND', 'TX-TICK',
|
|
||||||
'TX-PHASE', 'CHRONO', 'TX-AUDIO', 'PULL-MIC', 'DUC-DRY', 'DUC-RUN', 'NOTE');
|
|
||||||
|
|
||||||
procedure TraceInit;
|
|
||||||
var
|
|
||||||
S: string;
|
|
||||||
begin
|
|
||||||
S := LowerCase(Trim(GetEnvironmentVariable('EWSDR_TXTRACE')));
|
|
||||||
TraceOn := (S = '1') or (S = 'true') or (S = 'yes') or (S = 'on');
|
|
||||||
Epoch := MonotonicUs;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TR(Kind: Integer; A: Integer = 0; B: Integer = 0; C: Integer = 0);
|
|
||||||
var
|
|
||||||
Idx: LongInt;
|
|
||||||
P: ^TTraceRec;
|
|
||||||
begin
|
|
||||||
if not TraceOn then Exit;
|
|
||||||
Idx := InterlockedIncrement(RingSeq) - 1;
|
|
||||||
P := @Ring[Idx and TRACE_MASK];
|
|
||||||
P^.T := MonotonicUs;
|
|
||||||
P^.Kind := Kind;
|
|
||||||
P^.A := A;
|
|
||||||
P^.B := B;
|
|
||||||
P^.C := C;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function Slug(const S: string): string;
|
|
||||||
var i: Integer;
|
|
||||||
begin
|
|
||||||
Result := '';
|
|
||||||
for i := 1 to Length(S) do
|
|
||||||
if S[i] in ['a'..'z', 'A'..'Z', '0'..'9', '-', '_'] then
|
|
||||||
Result := Result + S[i];
|
|
||||||
if Result <> '' then Result := '-' + Copy(Result, 1, 24);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TraceDump(const Reason: string): string;
|
|
||||||
var
|
|
||||||
F: TextFile;
|
|
||||||
i, First: LongInt;
|
|
||||||
Total: LongInt;
|
|
||||||
R: TTraceRec;
|
|
||||||
Name: string;
|
|
||||||
begin
|
|
||||||
Result := '';
|
|
||||||
if not TraceOn then Exit;
|
|
||||||
Total := RingSeq;
|
|
||||||
if Total <= 0 then Exit;
|
|
||||||
|
|
||||||
Result := GetAppCfgDir + 'txtrace-' +
|
|
||||||
FormatDateTime('yyyymmdd-hhnnss', Now) + Slug(Reason) + '.txt';
|
|
||||||
AssignFile(F, Result);
|
|
||||||
try
|
|
||||||
Rewrite(F);
|
|
||||||
try
|
|
||||||
WriteLn(F, '# ewsdr TX trace, повод: ', Reason);
|
|
||||||
WriteLn(F, '# всего событий: ', Total, ', в кольце: ',
|
|
||||||
Min(Total, TRACE_SIZE));
|
|
||||||
WriteLn(F, '# t_ms событие A B C');
|
|
||||||
First := Total - Min(Total, TRACE_SIZE);
|
|
||||||
for i := First to Total - 1 do
|
|
||||||
begin
|
|
||||||
R := Ring[i and TRACE_MASK];
|
|
||||||
if (R.Kind < Low(TRACE_NAMES)) or (R.Kind > High(TRACE_NAMES)) then
|
|
||||||
Name := '?'
|
|
||||||
else
|
|
||||||
Name := TRACE_NAMES[R.Kind];
|
|
||||||
WriteLn(F, Format('%12.3f %-9s %9d %9d %9d',
|
|
||||||
[(R.T - Epoch) / 1000.0, Name, R.A, R.B, R.C]));
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
CloseFile(F);
|
|
||||||
end;
|
|
||||||
except
|
|
||||||
on E: Exception do Result := '';
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
end.
|
|
||||||
@@ -18,12 +18,11 @@ uses
|
|||||||
Forms, LazOpenGLContextEx,
|
Forms, LazOpenGLContextEx,
|
||||||
MainForm, AudioOutput, DeviceForm, FlatButton, FreqDisplay, VfoOverlay,
|
MainForm, AudioOutput, DeviceForm, FlatButton, FreqDisplay, VfoOverlay,
|
||||||
WDSP, WDSPEngine, WebPageHtml, WebServer, WebUtils, WinFirewall, WsClient,
|
WDSP, WDSPEngine, WebPageHtml, WebServer, WebUtils, WinFirewall, WsClient,
|
||||||
Settings, RadioController, TxTrace;
|
Settings, RadioController;
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
|
||||||
begin
|
begin
|
||||||
TraceInit;
|
|
||||||
EnableProcessDpiAwareness;
|
EnableProcessDpiAwareness;
|
||||||
RequireDerivedFormResource := True;
|
RequireDerivedFormResource := True;
|
||||||
Application.Title:='EWSDR';
|
Application.Title:='EWSDR';
|
||||||
|
|||||||
+1
-2
@@ -28,7 +28,7 @@ uses
|
|||||||
{$IFDEF UNIX}cthreads, BaseUnix,{$ENDIF}
|
{$IFDEF UNIX}cthreads, BaseUnix,{$ENDIF}
|
||||||
Classes, SysUtils, Math,
|
Classes, SysUtils, Math,
|
||||||
RadioController, WebServer, WebAdapter, WDSPEngine,
|
RadioController, WebServer, WebAdapter, WDSPEngine,
|
||||||
HPSDRNetwork, Settings, WDSP, PlatformUtils, DeviceStore, BoardUtils, TxTrace;
|
HPSDRNetwork, Settings, WDSP, PlatformUtils, DeviceStore, BoardUtils;
|
||||||
|
|
||||||
const
|
const
|
||||||
PUSH_INTERVAL_MS = 50; // период исходящего web-зеркала (как GUI-таймер)
|
PUSH_INTERVAL_MS = 50; // период исходящего web-зеркала (как GUI-таймер)
|
||||||
@@ -490,7 +490,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
TraceInit;
|
|
||||||
OnGetApplicationName := @DaemonAppName; // ДО создания контроллера/настроек!
|
OnGetApplicationName := @DaemonAppName; // ДО создания контроллера/настроек!
|
||||||
Log('EWSDR daemon starting (headless).');
|
Log('EWSDR daemon starting (headless).');
|
||||||
GHost := THeadlessHost.Create;
|
GHost := THeadlessHost.Create;
|
||||||
|
|||||||
+12
-1
@@ -107,8 +107,19 @@ TX голодала, в эфире дыры. Тут же диапазон глу
|
|||||||
|
|
||||||
## Приборы внутри процесса: кольцевая трассировка TX-тракта
|
## Приборы внутри процесса: кольцевая трассировка TX-тракта
|
||||||
|
|
||||||
|
★**Сняты из кода 2026-08-24** — пейсинг TX проверен на железе, всплесков нет, и
|
||||||
|
инструмент больше не нужен в горячем пути. Последняя редакция зондов лежит в
|
||||||
|
коммите `d209697`; вернуть их целиком:
|
||||||
|
|
||||||
|
git show d209697 -- TxTrace.pas | git apply # сам юнит
|
||||||
|
git show <коммит снятия> | git apply -R # точки съёма и TraceInit
|
||||||
|
|
||||||
|
Скрипт разбора (`txtrace_scan.py`) оставлен: формат дампа не менялся, и при
|
||||||
|
возврате зондов он работает как прежде. Ниже — описание прибора на случай
|
||||||
|
возврата.
|
||||||
|
|
||||||
Дамп на проводе видит ПАУЗУ в потоке DUC, но не видит, кто её сделал. Для этого
|
Дамп на проводе видит ПАУЗУ в потоке DUC, но не видит, кто её сделал. Для этого
|
||||||
в код вписано кольцо трассировки (`TxTrace.pas`), выключенное по умолчанию.
|
в код вписывалось кольцо трассировки (`TxTrace.pas`), выключенное по умолчанию.
|
||||||
|
|
||||||
Включение — переменной окружения, кольцо сбрасывается на диск в конце КАЖДОЙ
|
Включение — переменной окружения, кольцо сбрасывается на диск в конце КАЖДОЙ
|
||||||
передачи (после снятия PTT, чтобы файл не задержал выход из эфира):
|
передачи (после снятия PTT, чтобы файл не задержал выход из эфира):
|
||||||
|
|||||||
Reference in New Issue
Block a user