Обновить логгер УМП и исправить запуск UART и EEPROM

Перейти на компактные 12-словные записи v4 и сохранять 10 процентов банка после отключения. Добавить трёхсекундное ожидание роста ЗПТ и настраиваемый лимит пусков. Явно инициализировать состояние UART и гарантировать публикацию параметров EEPROM перед запуском Timer2. Сохранить воспроизводимые сборки, регрессионные проверки, документацию и обновлённые результаты сборки; исключить временные артефакты.
This commit is contained in:
2026-10-12 12:25:41 +03:00
parent f741741cf8
commit 1e911e5250
38 changed files with 2089 additions and 1485 deletions
+117 -89
View File
@@ -3,29 +3,33 @@
## Назначение и работа оператора
В SetGUI открыть ПМ35 → Настройки, выбрать COM, скорость (обычно 115200)
и адрес контроллера (обычно 16). Затем открыть вкладку **Логгер УМП**.
и адрес контроллера (для рассматриваемого УМП — 5). Затем открыть вкладку **Логгер УМП**.
Подключение используется существующее: прямой RS232/RS485 Modbus RTU.
CAN-команды от управляющего контроллера фиксируются самой платой нагрузки.
1. **Начать запись** включает только регистратор, не пуск УМП.
Период снимков по умолчанию 20 мс, диапазон 1–1000 мс.
2. Флажки выбирают отображаемые сигналы. Аналоги рисуются линиями,
2. Левые флажки выбирают отображаемые сигналы. Аналоги рисуются линиями,
дискретные сигналы — отдельными дорожками. Выбор не меняет состав
записи на плате: скрытую кривую можно включить после захвата.
3. **Онлайн** подключает график к уже идущей записи, в том числе после
восстановления соединения. Тайм-аут не посылает плате команду останова.
4. Фронт `cUMPreset` (бит 6 команды 0x7F) или спад `cUMPstart` (бит 7)
запускает фиксацию отключения. Ещё через 1000 тиков таймера / 1 секунду
банк становится архивом. Повторные команды внутри этой секунды
не продлевают интервал. Другие изменения команд не служат триггером.
4. Фактическое включение STOP при переходе работающей нагрузки к снятому
разрешению запускает фиксацию отключения. Постинтервал содержит 10%
банка — 76 последующих точек, включая события CAN и I/O. Повторные
STOP при уже остановленной нагрузке архив не заменяют.
5. **Прочитать отключение** загружает архив, не останавливая запись на плате.
На время чтения и просмотра архива онлайн-график приостанавливается;
вернуться к нему можно кнопкой **Онлайн**.
6. **Остановить и прочитать** останавливает только регистратор и читает
текущий банк. При этом существующий архив отключения остаётся доступным.
7. **Сохранить CSV** сохраняет все поля загруженного/онлайн-буфера,
включая невидимые кривые, время и код события. История GUI ограничена
800 последними точками; это не непрерывная запись на диск.
7. **Сохранить CSV** сохраняет поля загруженного/онлайн-буфера, выбранные
правыми флажками «Запись в лог», а также время и код события. Выбор
не зависит от видимости кривой. Множители графика не изменяют значения CSV.
**Буфер GUI** задаёт число последних точек: от 800 до 100000, по умолчанию
10000. Это отдельный буфер ПК, не ёмкость банка платы и не непрерывная
запись на диск. **Сохранить график из GUI** позволяет выгрузить накопленную
онлайн-историю после чтения архива платы.
При разрыве связи журнал на плате продолжает работать. Архив хранится в ОЗУ
до следующей фиксации отключения либо перезагрузки/пропадания питания.
@@ -35,23 +39,21 @@ EEPROM не используется: под отключением в этой
## Память и точность
Использована существующая секция `.logg` по адресу 0x200000: 64000
16-битных слов. Два банка по 760 записей × 42 слова занимают 63840 слов (160 слов свободны).
Текущий банк кольцевой. При триггере сохраняются последние до 379 записей,
добавляется событие отключения, оставшаяся половина банка отведена
постинтервалу. При 20 мс это до примерно 7.6 секунды до отключения и 1 секунды
после. Дополнительные события CAN и дискретов сокращают временную глубину.
При интенсивном потоке событий или периоде 1 мс постинтервал может заполнить
свои места раньше секунды. Последнее место зарезервировано под конечный
снимок; он помечается `event & 0x200`, и GUI сообщает об усечении.
Событие отключения и предыстория при этом не вытесняются.
16-битных слов. Два банка по 760 записей × 12 слов занимают 18240 слов.
Ёмкость в точках сохранена; сокращённая запись освобождает оставшуюся часть
выделенного массива. При триггере сохраняются до 683 предыдущих точек,
событие отключения и 76 последующих точек. При периоде 20 мс и отсутствии
дополнительных событий постинтервал составляет примерно 1,52 секунды.
События CAN и дискретов сокращают его временную длительность, но не число
зарезервированных точек. Архив после заполнения постинтервала фиксируется,
а запись продолжается в другом банке.
Время — 32-битный счётчик миллисекунд записи. Он идёт только при включённом
регистраторе и не является абсолютным временем. События в одном тике имеют
одинаковую отметку; порядок сохраняется порядком записей. На перезапуске
регистратора счётчик продолжает прежнюю шкалу, при перезагрузке платы — 0.
Онлайн-опрос возвращает две последние записи каждые 40 мс. Он не гарантирует
Онлайн-опрос возвращает до десяти последних записей каждые 40 мс. Он не гарантирует
передачу каждого события при высоком CAN-трафике, медленном UART или паузах
GUI. Номера записей позволяют убрать дубликаты и явно показать пропуски.
Полный сохранившийся фрагмент следует читать кнопкой архива. Частота 20 мс
@@ -63,55 +65,55 @@ GUI. Номера записей позволяют убрать дублика
EEPROM, выделения памяти или копирования целого банка. Реальную задержку
прерываний и длительность критических секций нужно измерить на F28335.
## Состав записи v3: 42 слова
## Состав записи v4: 12 слов
Из прошивки и списка графиков удалены 32 неотмеченных канала с двух
скриншотов: остатки импульса/инициализации, код и калибровки ЦАП,
измерения, ошибки, сырые CAN-слова/счётчики, маска команд, параметры
разгона и каналы АЦП. Рабочие калибровочные регистры и сами измерения
для управления платой продолжают использоваться по назначению.
В интерфейсе осталось 15 каналов:
| Группа | Каналы |
|---|---|
| Ток и уставки | Расчётное задание тока, начальная уставка, конечная уставка — мА |
| Напряжения | ЗПТ1: U1 + U2 (ПМ67, рег. 306); ЗПТ2: U3 + U4 (ПМ67, рег. 9) — В |
| Команды | Пуск УМП, сброс УМП |
| Входы | OMEGA, Start_1, Res_in |
| Выходы | START_DPTB, STOP_DPTB, RES_OUT_2 |
| События | Событие отключения, усечение постинтервала |
«Усечение постинтервала» оставлено для чтения прежних журналов; текущая
прошивка v4 бит 9 события не устанавливает. Расчётное задание тока —
команда аналоговому выходу, а не измеренный физический ток петли.
Для отображения физических единиц у пяти аналоговых каналов нужен
множитель ×1,000. Сохранённые пользовательские множители восстанавливаются
при запуске GUI; например, ×94,000 меняет только высоту кривой, не ток платы.
| Слова | Данные | Единицы/смысл |
|---|---|---|
| 0–1 | Время, младшее/старшее слово | мс записи |
| 2 | Событие | 1 период, 2 CAN RX, 3 изменение I/O, 4 RS-команда, 5 конец постинтервала |
| 2, бит 8 | Триггер отключения | флаг поверх причины события |
| 2, бит 9 | Усечён постинтервал | установлен в конечном снимке |
| 3 | Commands / modbus[0x7F] | все 16 бит, в том числе пуск, сброс, инициализация и калибровка ЦАП |
| 4 | Входы OMEGA, Start_1, Res_in | биты 0,1,2, активный уровень приведён к 1 |
| 5 | START_DPTB, STOP_DPTB, RES_OUT_2 | биты 0,1,2, активный уровень приведён к 1 |
| 6 | IMPowse | остаток импульса, мс |
| 7 | WAKEpowse | остаток инициализации, тики DAC_FREQ |
| 8 | modbus[0x7B] | 12-битный код, переданный функцией dSEND в ЦАП |
| 9 | modbus[0x1C] | расчётное задание в 0.1 мА; GUI/CSV переводит в мА |
| 10–13 | sens_data[0..3] | измеренные сигналы, знаковое 16-битное значение в исходном масштабе |
| 14–17 | modbus[0..3] | маски ошибок измерений |
| 18 | CAN заголовок | адрес регистра в младших 13 битах и маска трёх слов в старших |
| 19–21 | Три слова последнего принятого CAN-кадра | без преобразования |
| 22 | Счётчик записанных CAN RX | младшие 16 бит |
| 23 | CanTimeOutErrorTR | младшие 16 бит счётчика тайм-аутов CAN TX |
| 24–25 | DAC_go, DAC_stop | исходные начальная/конечная уставки, мА |
| 26–28 | DAC_min(), DAC_max(), DAC_cal() | коды калибровки и ручного задания ЦАП |
| 29–30 | DAC_04, DAC_20 | значения соответствующих регистров |
| 31–32 | count_load, time_dac | положение и длительность разгона в тиках |
| 33–34 | эффективные dac_go/dac_stop + 4 | 0.1 мА после ограничений алгоритма; GUI переводит в мА |
| 35 | kod | целочисленное положение, используемое Anal_output |
| 36–39 | ADC_table[0..3] | значения таблицы АЦП в исходном масштабе прошивки |
| 40 | ЗПТ1: U1 + U2, ПМ67 регистр 306 / индекс 305 | исходное 16-битное слово без пересчёта |
| 41 | ЗПТ2: U3 + U4, ПМ67 регистр 9 / индекс 8 | исходное 16-битное слово без пересчёта |
| 2 | Событие | 1 — период, 2 — CAN, 3 — I/O, 4 — RS, 5 — конец постинтервала |
| 2, бит 8 | Событие отключения | флаг поверх причины |
| 2, бит 9 | Усечение постинтервала | совместимость со старыми журналами; в текущем v4 равен 0 |
| 3 | Команды пуска и сброса | только биты 7 и 6; отдельной кривой маски команд больше нет |
| 4 | Входы OMEGA, Start_1, Res_in | биты 0, 1, 2 |
| 5 | Выходы START_DPTB, STOP_DPTB, RES_OUT_2 | биты 0, 1, 2 |
| 6 | Расчётное задание тока | 0,1 мА; GUI/CSV показывает мА |
| 7–8 | Начальная/конечная уставки | целые мА |
| 9–10 | ЗПТ1/ЗПТ2 | беззнаковые слова, масштаб 1 В/ед. |
| 11 | Нулевой резерв | чётная длина для передачи CAN парами слов |
Напряжения принимаются из технологических CAN-кадров с нулевыми индексами
305 и 8. Учитываются все три позиции и биты маски 0x8000/0x4000/0x2000.
Они хранятся отдельно от массива modbus[0..127], обновляются и при выключенном
логгере. Запись содержит последние принятые значения; до первого приёма — 0.
При потере связи остаётся последнее значение: отдельного признака свежести нет.
Масштаб и знаковость физического напряжения не заданы исходной таблицей;
SetGUI показывает исходное беззнаковое слово, коэффициент задаётся в интерфейсе.
**Отправленный код ЦАП не является измеренным током выхода.** В этом проекте
не установлено, какой вход аппаратно измеряет ток ЦАП. При включённом
`cCalibrDac` отправляется `DAC_cal()`, а расчётное задание 0x1C остаётся
результатом алгоритма разгона. Для диагностики это различие сохранено.
ADC_table также уже обрабатывается существующим измерительным кодом;
это не обязательно необработанный регистр ADCRESULT.
Управляющая логика не исправлялась. Например, существующая строка
`if(dac_stop>16) dac_go=16;` в Load_runner сохранена; журнал показывает
фактически получившиеся эффективные уставки, чтобы выявить такое поведение.
Клиент не преобразует напряжения в знаковые измерения. Свежесть выбранного
ЗПТ и защита роста напряжения описаны отдельно в `UMP_VOLTAGE_PROTECTION.md`.
При штатных 6 мА пуск сначала передаёт это задание и получает 3 секунды
на рост ЗПТ до 30 В; после этого работает прежняя защита и лимит попыток.
## Протокол расширения Modbus
@@ -126,16 +128,16 @@ FC03, 0x1000, 16 слов:
| Смещение | Значение |
|---|---|
| 0,1 | 0x554D, версия 3 |
| 0,1 | 0x554D, версия 4 |
| 2,3 | состояние и число записей выбранного источника |
| 4,5 | 42 слова в записи, 760 записей в банке |
| 4,5 | 12 слов в записи, 760 записей в банке |
| 6 | период периодических снимков, мс |
| 7,8 | счётчик времени, младшее/старшее слово |
| 9,10 | Desk (требуется 6 / dsk_LOAD), Mode |
| 11 | частота временной базы, 1000 Гц |
| 12 | поколение архива, mod 65536 |
| 13 | число записей архива |
| 14 | оставшиеся миллисекунды постинтервала |
| 14 | верхняя оценка оставшихся миллисекунд: число точек × период, до 65535 |
| 15 | состояние текущего регистратора независимо от выбора источника |
Состояния: 0 — ещё не запущен, 1 — запись, 3 — остановлен/архив.
@@ -146,40 +148,45 @@ FC06:
- 0x1002: хронологический индекс первой записи окна 0..759;
- 0x1003: источник окна, 0 — текущий остановленный банк, 1 — архив отключения.
FC03, 0x1010, до 120 слов: окно от установленного индекса; для целых записей v3 читать 42 или 84 слова.
CAN допускает 42/84 и прежние размеры 40/80/120; RTU допускает 1..120 слов.
FC03, 0x1010, до 120 слов: окно от установленного индекса; для целых записей v4 читать 12, 24, …, 120 слов.
CAN допускает кратные 12 до 120 слов и прежние размеры v2/v3; RTU допускает 1..120 слов.
Чтение текущего банка этим окном во время записи не выдаёт изменяющиеся
данные. GUI сначала останавливает его; архив можно читать при работающем
текущем банке. После всех блоков GUI повторно проверяет поколение архива;
при замене во время чтения результат не подменяет предыдущий график.
FC03, 0x1100, ровно 124 слова: онлайн-блок. Слова 0,1 — 32-битный номер
первой записи, 2 — число записей 0..2, 3 — поколение архива, далее до двух
записей по 42 слова. Неиспользованные слова равны нулю. Окно онлайн не
первой записи, 2 — число записей 0..10, 3 — поколение архива, далее до десяти
записей по 12 слов. Неиспользованные слова равны нулю. Окно онлайн не
зависит от курсора/выбора архива. Разделение 0x1010 и 0x1100 предотвращает
пересечение двух окон.
Недопустимые диапазоны и значения возвращают исключения Modbus 2/3.
CRC и разбор стандартного ответа GUI используют существующее общее ядро.
SetGUI распознаёт v2 (40 слов, 800 записей) и v3 (42 слова, 760 записей).
Для v2 новые напряжения недоступны (NaN), для v3 доступны графики и CSV.
CAN-валидация общей библиотеки расширена размерами 42/84 слова.
SetGUI распознаёт v2 (40 слов, 800 записей), v3 (42 слова, 760 записей)
и v4 (12 слов, 760 записей). Для v2 ЗПТ недоступны (NaN). Старые архивы
декодируются по прежним индексам, но удалённые каналы в панели и CSV больше
не создаются. Валидаторы RTU/CAN поддерживают компактные размеры записи.
Исходники протокола подключаются к прошивке из templates/c/set-protocol.
## Проверка и запуск
Полная сборка исправления: `./build_logger.ps1`. По умолчанию используется
`../newProject/SETGUI/third_party/templates`; другую копию можно указать
параметром `-TemplatesRoot`. В ней нужны `c/set-protocol/src/ump_protocol.c`
и `c/set-protocol/ports/tms320f28335/ump_tms28335.c` (порт УМП v3).
Само наличие папки templates не гарантирует наличие этого порта.
Результат — `Bin/LoggerFix/UKSSTMS320F28335_logger_fix.bin` (SCI8 boot),
рядом OUT и MAP. Старые образы в Bin не заменяются.
Скрипт использует TI C2000 22.6 COFF, оптимизацию размера и секции функций;
таблица `.cinit` размещена в RAML4 вместе с константами, код — в RAML0.
Для сборки из CCS добавьте `Source/Internal/shared_ump.c` в проект и каталоги
`<templates>/c/set-protocol`, `<templates>/c/set-protocol/ports/tms320f28335`
в include path; используйте параметры оптимизации из скрипта.
Текущая проверенная сборка с пуском 3 секунды и сокращённым журналом:
`Bin/StartupWait3s/UKSSTMS320F28335_startup_3s_378e06a+.bin`.
Размер — 32180 байт; для AT25256B допустимы 32508 байт, запас — 328 байт.
Рядом находятся OUT, MAP, манифест и SHA-256. Для чтения v4 используйте
обновлённый SETGUI и перезапустите приложение после изменения исходников.
Воспроизводимая сборка из корня проекта: `python Bin/StartupWait3s/rebuild.py`.
Скрипт использует установленный TI C2000 22.6, ABI COFF, `-O2`,
`--opt_for_speed=0` и секции функций. Все модули пересобираются в отдельный
каталог; до формирования готового BIN проверяются профиль AT25256B,
граница 32508 байт, блоки RAM и точка входа SCI8. Сохраняются паспорт и SHA-256.
Из CCS используется та же карта памяти и настройки проекта. В include-path
нужны каталоги общего `c/set-protocol`, его порта `ports/tms320f28335`
и сгенерированного паспорта. Обе используемые копии библиотеки поддерживают v4:
`../newProject/templates` и `../newProject/SETGUI/third_party/templates`.
При загрузке `main()` вызывает `ump_log_init()` до включения прерываний.
Это обязательно для TI COFF: стартовый код не обнуляет неинициализированные
@@ -191,29 +198,31 @@ FC06 не вызывает загрузочную инициализацию и
запуск с ненулевой RAM и отрицательный контроль без инициализации;
внешняя библиотека `templates/c/set-protocol` для этого теста не нужна.
Изменены исходники прошивки и SetGUI. Готовый образ в Bin не обновлялся.
Для платы необходима сборка штатным TI C2000/CCS, проверка размещения .text,
.stack, .ebss и .logg по MAP, прошивка и испытание на стенде.
Изменены исходники прошивки и SetGUI; новый образ собран в отдельном каталоге.
Проверены TI-компиляция, линковка и формат SCI8 для AT25256B. Физические
уровни GPIO и ток после загрузки образа проверяются на плате.
Автотест C в tests/ump_logger компилирует непосредственно log_to_mem.c
с подменой GPIO/IRQ. Проверяет кольцо, граничные адреса, обе команды
отключения, защиту триггера от переполнения, переключение банков,
сохранность архива во время дальнейшей записи и контрольные поля CAN/ЦАП.
сохранность архива во время дальнейшей записи, токовое задание и оба ЗПТ.
Это проверка алгоритма на компьютере, не проверка таймингов и 16-битной ABI
TI. Отдельно выполнена синтаксическая проверка изменённых C-файлов Clang
с исходными заголовками и декларациями TI-интринсиков.
Тесты SetGUI: tests/test_ump_logger.py и tests/test_periph28335_tab.py.
Проверенный набор SetGUI: `tests/test_ump_logger.py`,
`tests/test_ump_logger_can.py`, `tests/test_ump_voltage_protection.py` — 93 теста.
Они проверяют единицы мА, битовые сигналы, временные метки, несовместимую
прошивку, порядок команд, архив при активной записи, замену поколения,
дубликаты/пропуски онлайн, потерю связи и флажки графиков.
Проверка на стенде: включить запись → подать CAN-пуск → изменить уставку →
подать откл. → через секунду прочитать архив → сверить код ЦАП, ток внешним
измерителем и физические входы/выходы; затем повторить с разрывом RS.
подать откл. → дождаться заполнения 76 точек постинтервала → прочитать
архив и сверить задание, внешний ток и дискретные уровни; затем повторить
с разрывом RS.
Период 1 мс проверить отдельно под максимальной CAN-нагрузкой.
Для сборки v3 нужен templates/main начиная с коммита c0ee7c4
Исторически для сборки v3 требовался templates/main начиная с коммита c0ee7c4
(поддержка CAN-чтения 42/84 слов и порт TMS320F28335).
## Пересечение образа 34a95bc5 с параметрами EEPROM
@@ -239,3 +248,22 @@ TI. Отдельно выполнена синтаксическая прове
При превышении границы остаётся только файл `.pending`; готовый BIN
не публикуется. Проверка: `python tests/ump_logger/test_firmware_image.py`.
После перепрошивки требуется проверка на плате; проверка на ПК её не заменяет.
## Исправление ожидания EEPROM при запуске через CCS
В сборке CCS с O3 подтверждён перенос записей полей `readData` и `writeData`
за цикл ожидания `spiSe2pFree()`. Указатель `msgPtr` и флаг `csr` были volatile,
но содержимое дескриптора — нет. Timer2 получал запрос с незаполненными
адресом, длиной и указателем буфера, поэтому `Load_params()` мог не завершиться,
хотя UART уже принял команду. Все три поля `SE2P_DATA` теперь volatile.
В дизассемблере исправленного OUT записи всех полей предшествуют флагу запроса.
Для проверки старой AT25256B подготовлен
`Bin/EepromPublishFix/UKSSTMS320F28335_eeprom_fix.out` и одноимённый BIN с build_id.
Сборка `python Bin/EepromPublishFix/rebuild.py` явно задаёт `EEPROM_M95M02=0`
и O3; размер проверенного BIN — 32074 байта, запас до параметров — 434 байта.
Проверка порядка инструкций:
`python tests/eeprom_profiles/check_publication.py Bin/EepromPublishFix/disassembly.txt`.
На листинге прежнего OUT эта проверка падает, на исправленном проходит для чтения
и записи. Пройдены модели обоих профилей EEPROM и UART. Запуск на плате
после загрузки исправленного OUT ещё требует подтверждения.