Files
templates/doc/setcan/protocan/OAP.md
T
Andrey f17c124f0e docs: Согласуй документацию ProtoCAN и инструментов сборки
Обнови спецификацию GAS 0x3/0x4, реестр устройств и описание загрузочных сервисов одновременно в Markdown, HTML и XLSX.

Свяжи новые аппаратные порты, глобальное время и сборку C2000/ПЛИС с корневыми инструкциями, чтобы проекты подключались по одному актуальному контракту.
2026-10-23 14:16:22 +03:00

163 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Общее адресное пространство: GAS и GAS SLOT
Дата редакции: **2026-10-23**. Номер типа однозначно определяет единицу адресации:
| MsgType | Имя | MsgBody | Payload |
|---|---|---|---|
| `0x3` | GAS | адрес первого 16-битного регистра | 1…4 последовательных регистра, DLC 2/4/6/8 |
| `0x4` | GAS SLOT | адрес слота | Word0 — маска; Word1…Word3 — три значения; DLC 8 |
В обоих случаях запрос чтения — extended data frame с `DLC=0`, `Route=0`.
Ответ имеет `Route=1`, тот же узел и адрес. Прикладного ACK записи нет;
успех применения уставки проверяется прикладным ответом или последующим чтением.
RTR, error frame, стандартный 11-битный ID и нечётные длины не исполняются.
## GAS 0x3: отдельные регистры
`MsgBody=RegisterAddress[15:0]`. Адреса `0…65535` (`0x0000…0xFFFF`)
обозначают **65 536 отдельных 16-битных регистров**, логически 128 КиБ на узел.
Это адреса протокола, а не указатели RAM MCU; provider подключает только существующие регионы.
Payload содержит значения с адресов `addr`, `addr+1`, `addr+2`, `addr+3`
в порядке little-endian. Количество равно `DLC/2`, допускаются DLC 2, 4, 6, 8.
Для изменения одной уставки по адресу `0x0001` на `0x1234` передаются
`MsgBody=0x0001`, `DLC=2`, Data=`34 12`; соседние слова не изменяются.
Чтение возвращает до четырёх существующих последовательных регистров,
останавливаясь на первом недоступном адресе или границе `0xFFFF`.
Запись, пересекающая `0xFFFF`, отвергается до изменения данных.
Регионы карты, права и значения проверяет `pcan_gas`; callback остаётся
ответственностью приложения. Блочная запись может остановиться на первом отказе provider:
атомарность нескольких регистров не обещается. Связанные `u32/float32` и команды
требуют согласованной прикладной операции. Основной контракт: `c/set-protocol/docs/legacy/GAS.md`.
GAS 167/v1, GAS Logger, GAS_WATCH2, NAND и Altera Logic сохраняют регистровые адреса.
Номер mode задаёт адрес узла; его нельзя автоматически прибавлять к адресу регистра.
## GAS SLOT 0x4: маска в Word0
`MsgBody=SlotAddress[15:0]`. Восемь октетов имеют фиксированное расположение:
| Октеты | Wire-слово | Назначение |
|---|---|---|
| 0…1 | Word0 | 16-битная маска, little-endian |
| 2…3 | Word1 | первое значение |
| 4…5 | Word2 | второе значение |
| 6…7 | Word3 | третье значение |
Биты маски 1, 2, 3 соответствуют Word1, Word2, Word3. Бит 0 и биты 4…15
зарезервированы и должны быть нулевыми. Маска непустая; все допустимые маски:
`0x0002`, `0x0004`, `0x0006`, `0x0008`, `0x000A`, `0x000C`, `0x000E`.
При записи отмеченные значения применяются, неотмеченные позиции игнорируются
и сохраняют текущие значения устройства. Нули не являются специальными маркерами.
При чтении маска ответа отмечает достоверные/доступные значения.
Например, изменить только Word2 на `0x1234`: Data=`04 00 00 00 34 12 00 00`.
Word1 и Word3 сохраняются. Полная запись трёх значений использует маску `0x000E`.
Передаются всегда восемь октетов, кроме пустого запроса чтения. Сжатия или сегментации нет.
Provider проверяет все выбранные права и значения до первого изменения, затем применяет
выбранные слова под общей блокировкой. Невыбранные readonly-поля не записываются.
Ядро не выполняет опасное чтение-изменение-запись слота на стороне клиента.
Полное пространство 0x4 содержит **65 536 слотов × 3 значения = 196 608 слов = 384 КиБ**.
Word0 — метаданные кадра, не четвёртый хранимый регистр. Координата значения —
`(SlotAddress, WordIndex)`, где `WordIndex=1…3`. Любой узел поддерживается общими
`pcan_gas_slot_id()` и `pcan_gas_slot_handle_address()`; адрес слота не ограничен страницами PERIPH.
Тип `0x4 MODBUS_COIL` заменён этим сервисом. Modbus `0x5/0x6/0x7` сохраняет номера.
Старое оборудование с Coil 0x4 требует согласованного обновления; автоопределения формата нет.
## PERIPH: проекция 200 слов на слоты 0x4
`mode=0…31`; `DeviceType=1+mode/16`, `DeviceID=mode mod 16`.
`SlotAddress=(mode<<8)|LocalSlot`. Маски не занимают места в карте значений.
На mode сохранены 200 слов, поэтому используются 67 слотов `LocalSlot=0x00…0x42`:
66 полных слотов и два значения последнего. В последнем разрешена только маска
из битов 1/2 (`0x0002`, `0x0004`, `0x0006`); Word3 не существует.
`LocalSlot=0x43…0xFF` — резерв. Узел и старший октет слота должны совпадать.
Смещение технологического слова: `n=3*LocalSlot+(WordIndex-1)`.
Обратное преобразование: `LocalSlot=n/3`, `WordIndex=1+n mod 3`.
Соседние native-сервисы могут оказаться в одном слоте, поэтому provider проверяет
доступ и наличие каждой отмеченной позиции отдельно.
| mode | Назначение | DeviceType / DeviceID | Слоты 0x4 | Запрос первого слота |
|---:|---|---|---|---|
| 0 | Резерв | `0x01 / 0x00` | `0x0000…0x0042` | `0x11040000` |
| 1 | Трансформатор 1 | `0x01 / 0x01` | `0x0100…0x0142` | `0x11140100` |
| 2 | Трансформатор 2 | `0x01 / 0x02` | `0x0200…0x0242` | `0x11240200` |
| 3 | Силовой узел 1 | `0x01 / 0x03` | `0x0300…0x0342` | `0x11340300` |
| 4 | Силовой узел 2 | `0x01 / 0x04` | `0x0400…0x0442` | `0x11440400` |
| 5 | УМП1 | `0x01 / 0x05` | `0x0500…0x0542` | `0x11540500` |
| 6 | УМП2 | `0x01 / 0x06` | `0x0600…0x0642` | `0x11640600` |
| 7 | ENG1 | `0x01 / 0x07` | `0x0700…0x0742` | `0x11740700` |
| 8 | Задатчик / пульт | `0x01 / 0x08` | `0x0800…0x0842` | `0x11840800` |
| 9 | Шкаф | `0x01 / 0x09` | `0x0900…0x0942` | `0x11940900` |
| 10 | Общий адрес: служебная роль | `0x01 / 0x0A` | `0x0A00…0x0A42` | `0x11A40A00` |
| 11 | Терминал: служебная роль | `0x01 / 0x0B` | `0x0B00…0x0B42` | `0x11B40B00` |
| 12 | Резерв назначения | `0x01 / 0x0C` | `0x0C00…0x0C42` | `0x11C40C00` |
| 13 | Резерв назначения | `0x01 / 0x0D` | `0x0D00…0x0D42` | `0x11D40D00` |
| 14 | Резерв назначения | `0x01 / 0x0E` | `0x0E00…0x0E42` | `0x11E40E00` |
| 15 | Резерв назначения | `0x01 / 0x0F` | `0x0F00…0x0F42` | `0x11F40F00` |
| 16 | Резерв назначения | `0x02 / 0x00` | `0x1000…0x1042` | `0x12041000` |
| 17 | Резерв назначения | `0x02 / 0x01` | `0x1100…0x1142` | `0x12141100` |
| 18 | Резерв назначения | `0x02 / 0x02` | `0x1200…0x1242` | `0x12241200` |
| 19 | Резерв назначения | `0x02 / 0x03` | `0x1300…0x1342` | `0x12341300` |
| 20 | Резерв назначения | `0x02 / 0x04` | `0x1400…0x1442` | `0x12441400` |
| 21 | Резерв назначения | `0x02 / 0x05` | `0x1500…0x1542` | `0x12541500` |
| 22 | Резерв назначения | `0x02 / 0x06` | `0x1600…0x1642` | `0x12641600` |
| 23 | Резерв назначения | `0x02 / 0x07` | `0x1700…0x1742` | `0x12741700` |
| 24 | Резерв назначения | `0x02 / 0x08` | `0x1800…0x1842` | `0x12841800` |
| 25 | Резерв назначения | `0x02 / 0x09` | `0x1900…0x1942` | `0x12941900` |
| 26 | Резерв назначения | `0x02 / 0x0A` | `0x1A00…0x1A42` | `0x12A41A00` |
| 27 | Резерв назначения | `0x02 / 0x0B` | `0x1B00…0x1B42` | `0x12B41B00` |
| 28 | Резерв назначения | `0x02 / 0x0C` | `0x1C00…0x1C42` | `0x12C41C00` |
| 29 | Резерв назначения | `0x02 / 0x0D` | `0x1D00…0x1D42` | `0x12D41D00` |
| 30 | Резерв назначения | `0x02 / 0x0E` | `0x1E00…0x1E42` | `0x12E41E00` |
| 31 | Резерв назначения | `0x02 / 0x0F` | `0x1F00…0x1F42` | `0x12F41F00` |
## Назначения mode из periph_28335
Источники: `28335_periph/Source/Internal/Include/package.h`, `peripher.c:get_Mode()`, `cntrl_adr.c`. Код платы `Desk` не участвует в вычислении адреса.
| mode | Назначение | Исходный символ |
|---:|---|---|
| 0 | Резерв | Перемычками текущей платы не задаётся |
| 1 / 2 | Трансформаторные узлы 1 / 2 | `adr_TRN1 / adr_TRN2` |
| 3 / 4 | Силовые узлы 1 / 2 | `adr_POW1 / adr_POW2` |
| 5 / 6 | УМП1 / УМП2 | `adr_LOA1 / adr_LOA2`, `Desk=dsk_LOAD=6` |
| 7 | ENG1 | `adr_ENG1` |
| 8 | Задатчик / пульт | `adr_PULT`; имя «Задатчик» принято в реестре PERIPH |
| 9 | Шкаф | `adr_SHKF` |
| 10 | Общий адрес, служебная роль | `CNTRL_ADDR_UNIVERSAL`, `ADDR_FOR_ALL`; не отдельная плата |
| 11 | Терминал, служебная роль | `ADDR_TERMINAL`; не доказательство отдельной платы |
| 12…31 | Резерв назначения | Перемычки текущей платы дают только 1…16 |
## Соответствия native-сервисам PERIPH
| Смещение n | Native-адрес | Назначение | Доступ |
|---|---|---|---|
| 0…127 | `0x0000…0x007F` | технологические данные, уставки, команды | по provider |
| 128…143 | `0x1000…0x100F` | статус регистратора УМП | R |
| 144…155 | `0x1200…0x120B` | паспорт прошивки | R |
| 156…163 | `0x1300…0x1307` | защита УМП | W только `0x1302/0x1303` |
| 164…167 | `0x1000…0x1003` | команды регистратора | по операции |
| 168…199 | нет | резерв | отказ |
`pcan_gas_slot_native()` принимает WordIndex=1…3; WordIndex=0 является маской
и не переводится в регистр. Наличие сервиса, права и блокировку проверяет приложение.
GAS 0x3 сохраняет собственные адреса подключённых регионов; эта проекция относится только к 0x4.
Архив УМП, окна 120/124 слова и физическая EEPROM сохраняют native-контракты.
## Реализация и реестр
- GAS 0x3: `pcan_gas.h/.c`, существующие ABI и клиенты.
- GAS SLOT 0x4: `pcan_gas_slot.h/.c`; тонкие Python `GasSlots` и Android/JNI `GasSlots`.
- Формат определяется MsgType, параметр `gas_profile` не используется.
- C28x хранит wire-октеты в `uint_least8_t`; DLC измеряется октетами линии.
- Перенос в другую единицу адресации или fallback после отказа запрещены.
XLSX «Интерфейс протокола» содержит оба типа; «Общее адресное пространство» —
проекцию 0x4 и native-адреса её значений; «ОАП legacy» сохраняет исходный словный реестр 0x3.
Уникальный ключ реестра включает узел, MsgType, адрес и для 0x4 WordIndex.
Права, тип, единица, масштаб и порядок слов u32/float32 задаются явно.
Эталоны: `examples/gas-slot-vectors.json`; регистровые проверки — `test_gas_register.c`.