docs: Согласуй документацию ProtoCAN и инструментов сборки

Обнови спецификацию GAS 0x3/0x4, реестр устройств и описание загрузочных сервисов одновременно в Markdown, HTML и XLSX.

Свяжи новые аппаратные порты, глобальное время и сборку C2000/ПЛИС с корневыми инструкциями, чтобы проекты подключались по одному актуальному контракту.
This commit is contained in:
2026-10-23 14:16:22 +03:00
parent 2da7e7b525
commit f17c124f0e
14 changed files with 1113 additions and 196 deletions

View File

@@ -84,7 +84,7 @@ STM32F103RC, STM32F103ZE и STM32G474CE объявляют поддержку з
возвращают `PNAND_ERROR_WRITE_PROTECTED`, пока плата и порт не доработаны.
Рабочий пример полноценного G474-порта находится в соседнем проекте
`candleLight_fw`: `src/device/device_g4.c` отвечает за clock/GPIO,
`CANdle_stm32` (candleLight): `src/device/device_g4.c` отвечает за clock/GPIO,
`src/can/m_can.c` — за FDCAN, а `include/config.h` — за привязку платы
STM32G474VET6. Эти файлы остаются в прошивке, поскольку зависят от STM32 HAL,
USB gs_usb и конкретной разводки адаптера; переносимая логика протоколов

View File

@@ -40,9 +40,10 @@ templates/
| [`c/set-protocol/ports/stm32f407-devboard-v1`](c/set-protocol/ports/stm32f407-devboard-v1) | доступ SETGUI к Modbus-регистрам F407 через CAN485 DevBoard_V1 | `pcan_modbus_server`, STM32 HAL CAN | bxCAN FIFO0 и callbacks карты регистров |
| [`c/set-protocol/ports/stm32-bxcan`](c/set-protocol/ports/stm32-bxcan) | порт прикладного ProtoCAN для STM32, бывший SETCAN; сохранён API `PROTOCAN_*` | STM32 HAL CAN/RTC/TIM + общее ядро `pcan_id` | classic bxCAN; настройки платы предоставляет прошивка |
| [`c/set-protocol/ports/tms320f2812`](c/set-protocol/ports/tms320f2812) | SETProtocol v2 firmware service по segmented classic CAN | `set_protocol`, `set_can`, `set_firmware` | CAN TX, Flash erase/write/read, optional signature policy и reboot |
| [`c/protocan-boot`](c/protocan-boot) | адресная прошивка по ProtoCAN: A/B-слоты, сессия, CRC32, verify и rollback-контракт | C99 | CAN TX, erase/write Flash, boot metadata, проверка образа и reboot |
| [`c/protocan-boot`](c/protocan-boot) | адресная прошивка по ProtoCAN: A/B-слоты, сессия, CRC32, verify и rollback-контракт | C99 | **STM32F103C8/F407VE/G474VE и TMS320F2812/F28335-порты в комплекте**; проекты STM32 подключены через templates, есть boot main и вход из приложения |
| [`c/rs485-boot`](c/rs485-boot) | прошивка по RS-485 в формате SETGUI v1: потоковый parser, CRC32 и resume | C99 | UART TX/RX, DE, Flash — **порты STM32F103 и STM32G474VET в комплекте** |
| [`c/rtc-service`](c/rtc-service) | RTC с резервированным backup-томом | `stdint.h` | доступ к RTC и backup-памяти — **порт K1921VK028 в комплекте** |
| [`c/global-time`](c/global-time) | программные часы 1 мс, ProtoCAN RTCSETUP, готовность платы и атомарная метка логгера | C99 | IRQ lock, CAN TX, такт 1 мс — **порт TMS320F28335 eCAN-A / CPU Timer2 в комплекте** |
| [`c/firmware-info`](c/firmware-info) | SemVer, build stamp и git build ID работающего образа | C99 | config-порты STM32F1/F4/G4 и К1921ВК028; упаковка для Modbus/SETGUI |
| [`c/parallel-nand`](c/parallel-nand) | parallel NAND x8: raw read/program/erase, профили Micron MT29F1G08 и Hynix HY27UF084G2M, bad-block marker и банковое окно GAS для SETGUI | C99, опционально `set-protocol/pcan_gas` | **порты TMS320F2812, STM32F103RC/ZE, STM32F407VE и STM32G474CEU6; запись требует управляемого WP#** |
@@ -64,6 +65,7 @@ templates/
| Инструмент | Что делает |
|---|---|
| [`tools/firmware-build/fpga`](tools/firmware-build/fpga/README.md) | общий итератор версии и HDL-паспорт для Xilinx ISE, Vivado и Altera/Intel Quartus; контроль `.bit`/`.sof`, manifest, SHA-256 и архив |
| [`tools/firmware-publish`](tools/firmware-publish) | единый BAT и конфигурации для проверки и публикации `.hex` Keil / `.bin` CCS 12 в каталоге SETGUI |
Общие тренды для Android GUI и SETGUI: [формат JSON, C99-ядро и адаптеры](c/set-protocol/docs/GUI_TRENDS.md).
@@ -118,7 +120,7 @@ git subtree pull --prefix lib/templates https://git.rd12.ru/Andrey/templates.git
| `KONOR_ds18b20` | st7789, keypad, menu, eeprom-ft24c256, can-sensor, ds18b20, firmware-info |
| `OpticalTester` | st7789, keypad, menu, eeprom-ft24c256 |
| `CAN_to_RS485` | set-protocol legacy transport, python/protocan |
| `candleLight_fw` | эталон разделения общей логики и G431/G474 FDCAN-порта; общий ProtoCAN Boot переносится по контракту `protocan-boot` |
| `CANdle_stm32` (candleLight) | G431/G474 FDCAN board-support; CAN/UART-загрузчик G474 и вход из приложения подключены к `protocan-boot/ports/stm32g474` через templates |
| `SETGUI` | python/protocan |
| `SETGUI`, Android GUI и новые устройства SET | set-protocol |
| `k1921vk028` | rtc-service |

View File

@@ -1,5 +1,7 @@
# Altera Logic — ONLINE через SETCAN / GAS / UART
> GAS `0x3` использует адреса отдельных 16-битных регистров. GAS SLOT `0x4` — отдельный сервис с маской в Word0 и тремя значениями Word1…Word3. Спецификация: `doc/setcan/protocan/OAP.md`; адреса этого документа остаются регистровыми.
Версия профиля: **1**. Реализация, порты и тесты принадлежат `templates`.
Это профиль существующего classic SETCAN/ProtoCAN с 29-битным ID;
он не подменяется кадром SETP v2 и не использует старые команды `A5 CMD` FPGA.

View File

@@ -7,10 +7,24 @@ Device Name — отображаемое имя адреса, а не допол
| DeviceType | DeviceID | Device Name | Назначение |
|---|---|---|---|
| `0x0` | существующие | Верхний уровень | Существующие адреса исходной таблицы |
| `0x6` | `0xE` | **Altera Logic** | Онлайн-анализатор 16 цифровых каналов |
| `0x1` | `0x0…0xF` | PERIPH 0–15 | Первая группа периферии по обновлённому листу «Интерфейс протокола» |
| `0x2` | `0x0…0xF` | PERIPH 16–31 | Вторая группа; номер PERIPH = 16 + DeviceID |
| `0x1` | `0x5` | **УМП1** | PERIPH 5, собственный адрес обычного обмена ProtoCAN и загрузчика |
| `0x1` | `0x6` | УМП2 | PERIPH 6, GAS 0x3 — регистры; GAS SLOT 0x4 — слоты 0x0600…0x0642 |
| `0x6` | `0xE` | Altera Logic | Отдельный существующий потоковый профиль FE00/FF00 |
| `0x7` | `0xD` | configurator | Существующий конфигуратор |
| `0x7` | `0xE` | **STM Invertor** | Самостоятельный ПЧ STM32G474VET6; отдельный GAS-профиль на 250 слотов 0x4, 750 значений; Word0 — маска |
| `0x7` | `0xF` | KONOR / SETTINGS | Существующий профиль SETCAN и привязка датчиков |
Источник PERIPH: [Протокол CAN и ОАП.xlsx](Протокол%20CAN%20и%20ОАП.xlsx),
лист «Интерфейс протокола», A44:F79. Формула: Type = 1 + ID PERIPH / 16
(целая часть), DeviceID = ID PERIPH mod 16. Зарезервированные номера не получают
назначений по аналогии со старым Бальзам CAN. Общий Boot-адрес `3/7` отменён.
В ПМ35 приложение использует аппаратный Mode, постоянный загрузчик читает те же
GPIO21/20/22/51; на существующей плате четыре перемычки задают номера 1–16.
Для номеров 0 и 17–31 требуется соответствующий источник аппаратного номера.
Старые CAN ID `0x00BA0007`/`0x00BA0017` задатчика остаются отдельным legacy-форматом.
Для Altera Logic выбран предпоследний тип `0x6` и предпоследний экземпляр `0xE`:
эта пара не была назначена в проверенных локальных таблицах и исходниках.
Тип `0x7` уже используется. Наличие другого физического узла с тем же адресом
@@ -19,3 +33,9 @@ Device Name — отображаемое имя адреса, а не допол
Числовые константы устройства: `c/set-protocol/include/altera_stream.h`.
Отображаемые имена: `python/protocan/protocan.py`.
Контракт потока: [ALTERA_LOGIC_STREAM.md](ALTERA_LOGIC_STREAM.md).
## Mode и два типа GAS
Таблица назначений и правила: [OAP.md](protocan/OAP.md). Mode 1/2 — трансформаторы; 3/4 — силовые узлы; 5/6 — УМП; 7 — ENG1; 8 — задатчик/пульт (`adr_PULT`); 9 — шкаф. 10 и 11 — служебные роли общего адреса и терминала. Остальные назначения не выводятся по аналогии со старым Бальзам CAN.
GAS 0x3 адресует отдельные регистры 0…65535. GAS SLOT 0x4: `Slot=(mode<<8)|LocalSlot`, LocalSlot `0x00…0x42`; Word0 — маска, Word1…Word3 — значения. На mode сохранены 200 значений; последний слот содержит два. Прибор 5 не обслуживает страницу 0x06xx.

View File

@@ -36,3 +36,7 @@
- [Реестр устройств SETCAN](DEVICE_REGISTRY.md).
- [ONLINE-поток Altera Logic через GAS и UART](ALTERA_LOGIC_STREAM.md).
## GAS: регистры 0x3 и слоты 0x4
[Адресация GAS](protocan/OAP.md): `0x3` — отдельные 16-битные регистры `0…65535`, запись 1…4 слов. `0x4` — слот с Word0-маской и тремя значениями; PERIPH сохраняет 200 слов в 67 слотах `0xMM00…0xMM42`. Формат определяется MsgType, без настройки профиля.

File diff suppressed because one or more lines are too long

View File

@@ -5,6 +5,13 @@
## [Unreleased]
### Changed — 2026-10-23
- GAS 0x3 возвращён к адресации отдельных 16-битных регистров 0…65535, DLC 0/2/4/6/8.
- Слотный GAS перенесён на 0x4 вместо MODBUS_COIL; Word0 содержит маску битов 1…3, Word1…Word3 — значения.
- PERIPH сохраняет 200 значений на mode в 67 слотах; последний содержит два значения.
- Формат выбирается номером MsgType; Python/JNI, STM32, Modbus routing, тесты, XLSX и HTML согласованы.
### Added
- Структурированный комплект документации `doc/setcan/protocan`.

View File

@@ -1,56 +1,162 @@
# Общее адресное пространство
# Общее адресное пространство: GAS и GAS SLOT
Статус: **Stable, данные ведутся в XLSX**<br>
Порядок значений: **16-битные регистры, little-endian в CAN payload**
Дата редакции: **2026-10-23**. Номер типа однозначно определяет единицу адресации:
Редактируемый источник реестра:
[`Протокол CAN и ОАП.xlsx`](../Протокол%20CAN%20и%20ОАП.xlsx).
| MsgType | Имя | MsgBody | Payload |
|---|---|---|---|
| `0x3` | GAS | адрес первого 16-битного регистра | 1…4 последовательных регистра, DLC 2/4/6/8 |
| `0x4` | GAS SLOT | адрес слота | Word0 — маска; Word1…Word3 — три значения; DLC 8 |
Просматриваемая большая таблица находится в
[`Протокол CAN и ОАП.html`](../Протокол%20CAN%20и%20ОАП.html) и
[`Протокол CAN и ОАП.md`](../Протокол%20CAN%20и%20ОАП.md).
В обоих случаях запрос чтения — extended data frame с `DLC=0`, `Route=0`.
Ответ имеет `Route=1`, тот же узел и адрес. Прикладного ACK записи нет;
успех применения уставки проверяется прикладным ответом или последующим чтением.
RTR, error frame, стандартный 11-битный ID и нечётные длины не исполняются.
## Назначение
## GAS 0x3: отдельные регистры
ОАП связывает 16-битный адрес регистра с его типом, назначением, доступом и
масштабом. В ProtoCAN используется `MsgType=0x3`, а `MsgBody` содержит адрес
первого регистра.
`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`, отвергается до изменения данных.
| Поле | Требование |
|---|---|
| AddressHex | `0x0000…0xFFFF`, уникальное значение |
| AddressDec | десятичный эквивалент AddressHex |
| Group | функциональная группа |
| Name | однозначное имя параметра |
| Type | `u16`, `i16`, `u32`, `i32`, `float32`, bitmap или массив |
| Registers | число занятых 16-битных регистров |
| Access | `R`, `W` или `RW` |
| Unit | физическая единица либо `—` |
| Scale | множитель/делитель представления |
| Default | значение после сброса, если применимо |
| Description | семантика, диапазон и особые значения |
Регионы карты, права и значения проверяет `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
- Адрес не переиспользуется с другим смыслом после выпуска стабильной версии.
- Многорегистровое значение занимает непрерывный диапазон.
- Порядок 16-битных слов для 32-битного значения фиксируется в строке типа.
- Резервные диапазоны явно отмечаются и не используются без изменения версии.
- Удалённый параметр помечается deprecated, а не исчезает молча.
- Изменение адреса, типа или масштаба отражается в `CHANGELOG.md`.
`MsgBody=SlotAddress[15:0]`. Восемь октетов имеют фиксированное расположение:
## Экспорт
| Октеты | Wire-слово | Назначение |
|---|---|---|
| 0…1 | Word0 | 16-битная маска, little-endian |
| 2…3 | Word1 | первое значение |
| 4…5 | Word2 | второе значение |
| 6…7 | Word3 | третье значение |
Для программной генерации каталог следует экспортировать из XLSX в CSV с
UTF-8 и фиксированными английскими именами колонок. CSV должен проверяться на:
Биты маски 1, 2, 3 соответствуют Word1, Word2, Word3. Бит 0 и биты 4…15
зарезервированы и должны быть нулевыми. Маска непустая; все допустимые маски:
`0x0002`, `0x0004`, `0x0006`, `0x0008`, `0x000A`, `0x000C`, `0x000E`.
При записи отмеченные значения применяются, неотмеченные позиции игнорируются
и сохраняют текущие значения устройства. Нули не являются специальными маркерами.
При чтении маска ответа отмечает достоверные/доступные значения.
- уникальность адресов;
- пересечение многорегистровых значений;
- допустимые типы и права доступа;
- равенство шестнадцатеричного и десятичного адреса;
- попадание адреса в диапазон `0x0000…0xFFFF`.
Например, изменить только Word2 на `0x1234`: Data=`04 00 00 00 34 12 00 00`.
Word1 и Word3 сохраняются. Полная запись трёх значений использует маску `0x000E`.
Передаются всегда восемь октетов, кроме пустого запроса чтения. Сжатия или сегментации нет.
Provider проверяет все выбранные права и значения до первого изменения, затем применяет
выбранные слова под общей блокировкой. Невыбранные readonly-поля не записываются.
Ядро не выполняет опасное чтение-изменение-запись слота на стороне клиента.
До появления автоматического экспортёра нормативным источником адресов
остаётся XLSX, а HTML/Markdown считаются представлением.
Полное пространство 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`.

View File

@@ -1,7 +1,7 @@
# ProtoCAN — базовый протокол
Статус: **Stable с зарезервированным загрузочным расширением**<br>
Версия: **1.0**<br>
Версия: **2.1: GAS 0x3 и масочный GAS SLOT 0x4**<br>
Порядок байтов payload: **little-endian**, если явно не указано иное
## Назначение
@@ -59,8 +59,8 @@ can_id =
| `0x0` | `BROADCAST` | ПМ → все | зависит от команды | stable |
| `0x1` | `DISCRETE` | оба | 0…8 | stable |
| `0x2` | `ANALOG` | оба | 0…8 | stable |
| `0x3` | `GAS` | оба | 0/2/4/6/8 | stable |
| `0x4` | `MODBUS_COIL` | оба | 0…8 | stable |
| `0x3` | `GAS` | оба | 0/2/4/6/8 | регистры 0…65535 |
| `0x4` | `GAS_SLOT` | оба | 0/8 | Word0 — маска, Word1…Word3 — значения |
| `0x5` | `MODBUS_DISCRETE` | оба | 0…8 | stable |
| `0x6` | `MODBUS_HOLDING` | оба | 0…8 | stable |
| `0x7` | `MODBUS_INPUT` | оба | 0…8 | stable |
@@ -82,14 +82,21 @@ can_id =
| broadcast | команда `[15:4]`, параметр `[3:0]` |
| discrete/analog | подтип `[15:12]`, значение/адрес `[11:0]` |
| Modbus | начальный адрес `[15:4]`, количество `[3:0]` |
| GAS | адрес первого 16-битного регистра `[15:0]` |
| GAS 0x3 | адрес первого 16-битного регистра `[15:0]` |
| GAS SLOT 0x4 | адрес слота `[15:0]`; маска — в Word0 payload, значения — Word1…Word3 |
| error | дополнительная информация `[15:8]`, код `[7:0]` |
| settings | номер сборки `[15:8]`, позиция `[7:0]` |
| boot control/status | `SessionID[15:8]`, команда `[7:0]` |
| boot data | `BlockIndex[15:0]` |
Контракт обоих GAS: [OAP.md](OAP.md). Тип 0x3 адресует отдельные слова; тип 0x4 имеет маску битов 1…3 в Word0 и три значения. Для PERIPH 0x4 используются 67 слотов `0xMM00…0xMM42`, последний содержит два значения. Старый Coil 0x4 заменён; формат определяется MsgType.
## Общие правила обмена
Профиль синхронизации часов и сообщения платы о завершении инициализации:
[GLOBAL_TIME.md](GLOBAL_TIME.md). Он сохраняет штатный BROADCAST RTCSETUP
и определяет общий пакет готовности поверх DISCRETE/FLAGS.
- Многобайтовые значения в `DATA` передаются little-endian.
- Узел игнорирует адресованные кадры с чужим `DeviceType/DeviceID`.
- Прибор принимает команды ПМ с `Route=0`; ПМ принимает ответы с `Route=1`.

View File

@@ -1,8 +1,8 @@
# Документация ProtoCAN
Статус комплекта: **Draft**<br>
Версия комплекта: **1.0**<br>
Дата редакции: **2026-08-29**<br>
Версия комплекта: **2.1**<br>
Дата редакции: **2026-10-23**<br>
Транспорт: **Classic CAN 2.0B, Extended ID, DLC 0…8**
Этот каталог разделяет нормативное описание протокола, загрузчик и реестр
@@ -41,3 +41,7 @@
Все документы и тестовые векторы включаются в единый файл
`doc/setcan/index.html`.
Скрипт не изменяет исходные Markdown/XLSX и пригоден для запуска в CI.
## GAS: регистры 0x3 и слоты 0x4
[Адресация GAS](OAP.md): `0x3` — отдельные 16-битные регистры `0…65535`, запись 1…4 слов. `0x4` — слот с Word0-маской и тремя значениями; PERIPH сохраняет 200 слов в 67 слотах `0xMM00…0xMM42`. Формат определяется MsgType, без настройки профиля.

View File

@@ -1,32 +1,259 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Протокол CAN и ОАП</title>
<style>
body { margin: 24px; color: #111827; background: #ffffff; font: 15px/1.5 Arial, sans-serif; }
h1, h2, h3 { line-height: 1.25; }
a { color: #1155cc; }
code { font-family: Consolas, "Courier New", monospace; }
pre { overflow: auto; padding: 12px; border: 1px solid #d1d5db; background: #f8fafc; }
body > table { border-collapse: collapse; margin: 12px 0 24px; }
body > table th, body > table td { border: 1px solid #9ca3af; padding: 6px 9px; }
body > table th { background: #f3f4f6; }
</style>
</head>
<body><h1 id="can">Протокол CAN и ОАП</h1>
<!doctype html><html lang="ru"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>ProtoCAN — GAS 0x3 и GAS SLOT 0x4</title></head><body><h1 id="can">Протокол CAN и ОАП</h1>
<p>Таблицы перенесены из <code>Протокол CAN и ОАП.xlsx</code>. Цвета, объединённые ячейки и структура листов сохранены средствами HTML внутри Markdown.</p>
<p>Адреса PERIPH обновлены по листу «Интерфейс протокола», A44:F79:
Type <code>0x01</code> содержит PERIPH 0–15, Type <code>0x02</code> — PERIPH 16–31;
Device ID равен младшим четырём битам номера PERIPH.
УМП1 — <code>0x01/0x05</code>, УМП2 — <code>0x01/0x06</code>, задатчик — <code>0x01/0x08</code>.
Назначения остальных mode уточнены по periph_28335: 1/2 — трансформаторы, 3/4 — силовые узлы, 7 — ENG1, 9 — шкаф; 10/11 — служебные роли. Общий Boot-адрес <code>0x03/0x07</code> отменён.
Полный <a href="DEVICE_REGISTRY.md">реестр назначений</a> применяется и к загрузчику, и к GUI.</p>
<ul>
<li><a href="#sheet-protocol">Интерфейс протокола</a></li>
<li><a href="#sheet-oap">Общее адресное пространство</a></li>
<li><a href="#can-firmware">Прошивка приборов по CAN</a></li>
</ul>
<p><a id="can-firmware"></a></p>
<p><a id="can-firmware"></a>
<a id="sheet-oap"></a></p>
<h2 id="gas-0x3-0x4">GAS: регистры 0x3 и масочные слоты 0x4</h2>
<p>Нормативная спецификация: <a href="protocan/OAP.md">OAP.md</a>. GAS 0x3: адрес первого регистра 0…65535, DLC 0/2/4/6/8. GAS SLOT 0x4: Word0 — маска битов 1…3, Word1…Word3 — три значения, DLC 0/8. PERIPH сохраняет 200 значений в 67 слотах; последний содержит два. Словный реестр ниже сохраняет адреса GAS 0x3.</p>
<table>
<thead>
<tr>
<th style="text-align: right;">mode</th>
<th>Назначение</th>
<th>Type / ID</th>
<th>Слоты 0x4</th>
<th>CAN запрос</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: right;">0</td>
<td>Резерв</td>
<td><code>0x01 / 0x00</code></td>
<td><code>0x0000…0x0042</code></td>
<td><code>0x11040000</code></td>
</tr>
<tr>
<td style="text-align: right;">1</td>
<td>Трансформатор 1</td>
<td><code>0x01 / 0x01</code></td>
<td><code>0x0100…0x0142</code></td>
<td><code>0x11140100</code></td>
</tr>
<tr>
<td style="text-align: right;">2</td>
<td>Трансформатор 2</td>
<td><code>0x01 / 0x02</code></td>
<td><code>0x0200…0x0242</code></td>
<td><code>0x11240200</code></td>
</tr>
<tr>
<td style="text-align: right;">3</td>
<td>Силовой узел 1</td>
<td><code>0x01 / 0x03</code></td>
<td><code>0x0300…0x0342</code></td>
<td><code>0x11340300</code></td>
</tr>
<tr>
<td style="text-align: right;">4</td>
<td>Силовой узел 2</td>
<td><code>0x01 / 0x04</code></td>
<td><code>0x0400…0x0442</code></td>
<td><code>0x11440400</code></td>
</tr>
<tr>
<td style="text-align: right;">5</td>
<td>УМП1</td>
<td><code>0x01 / 0x05</code></td>
<td><code>0x0500…0x0542</code></td>
<td><code>0x11540500</code></td>
</tr>
<tr>
<td style="text-align: right;">6</td>
<td>УМП2</td>
<td><code>0x01 / 0x06</code></td>
<td><code>0x0600…0x0642</code></td>
<td><code>0x11640600</code></td>
</tr>
<tr>
<td style="text-align: right;">7</td>
<td>ENG1</td>
<td><code>0x01 / 0x07</code></td>
<td><code>0x0700…0x0742</code></td>
<td><code>0x11740700</code></td>
</tr>
<tr>
<td style="text-align: right;">8</td>
<td>Задатчик / пульт</td>
<td><code>0x01 / 0x08</code></td>
<td><code>0x0800…0x0842</code></td>
<td><code>0x11840800</code></td>
</tr>
<tr>
<td style="text-align: right;">9</td>
<td>Шкаф</td>
<td><code>0x01 / 0x09</code></td>
<td><code>0x0900…0x0942</code></td>
<td><code>0x11940900</code></td>
</tr>
<tr>
<td style="text-align: right;">10</td>
<td>Общий адрес: служебная роль</td>
<td><code>0x01 / 0x0A</code></td>
<td><code>0x0A00…0x0A42</code></td>
<td><code>0x11A40A00</code></td>
</tr>
<tr>
<td style="text-align: right;">11</td>
<td>Терминал: служебная роль</td>
<td><code>0x01 / 0x0B</code></td>
<td><code>0x0B00…0x0B42</code></td>
<td><code>0x11B40B00</code></td>
</tr>
<tr>
<td style="text-align: right;">12</td>
<td>Резерв назначения</td>
<td><code>0x01 / 0x0C</code></td>
<td><code>0x0C00…0x0C42</code></td>
<td><code>0x11C40C00</code></td>
</tr>
<tr>
<td style="text-align: right;">13</td>
<td>Резерв назначения</td>
<td><code>0x01 / 0x0D</code></td>
<td><code>0x0D00…0x0D42</code></td>
<td><code>0x11D40D00</code></td>
</tr>
<tr>
<td style="text-align: right;">14</td>
<td>Резерв назначения</td>
<td><code>0x01 / 0x0E</code></td>
<td><code>0x0E00…0x0E42</code></td>
<td><code>0x11E40E00</code></td>
</tr>
<tr>
<td style="text-align: right;">15</td>
<td>Резерв назначения</td>
<td><code>0x01 / 0x0F</code></td>
<td><code>0x0F00…0x0F42</code></td>
<td><code>0x11F40F00</code></td>
</tr>
<tr>
<td style="text-align: right;">16</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x00</code></td>
<td><code>0x1000…0x1042</code></td>
<td><code>0x12041000</code></td>
</tr>
<tr>
<td style="text-align: right;">17</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x01</code></td>
<td><code>0x1100…0x1142</code></td>
<td><code>0x12141100</code></td>
</tr>
<tr>
<td style="text-align: right;">18</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x02</code></td>
<td><code>0x1200…0x1242</code></td>
<td><code>0x12241200</code></td>
</tr>
<tr>
<td style="text-align: right;">19</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x03</code></td>
<td><code>0x1300…0x1342</code></td>
<td><code>0x12341300</code></td>
</tr>
<tr>
<td style="text-align: right;">20</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x04</code></td>
<td><code>0x1400…0x1442</code></td>
<td><code>0x12441400</code></td>
</tr>
<tr>
<td style="text-align: right;">21</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x05</code></td>
<td><code>0x1500…0x1542</code></td>
<td><code>0x12541500</code></td>
</tr>
<tr>
<td style="text-align: right;">22</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x06</code></td>
<td><code>0x1600…0x1642</code></td>
<td><code>0x12641600</code></td>
</tr>
<tr>
<td style="text-align: right;">23</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x07</code></td>
<td><code>0x1700…0x1742</code></td>
<td><code>0x12741700</code></td>
</tr>
<tr>
<td style="text-align: right;">24</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x08</code></td>
<td><code>0x1800…0x1842</code></td>
<td><code>0x12841800</code></td>
</tr>
<tr>
<td style="text-align: right;">25</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x09</code></td>
<td><code>0x1900…0x1942</code></td>
<td><code>0x12941900</code></td>
</tr>
<tr>
<td style="text-align: right;">26</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x0A</code></td>
<td><code>0x1A00…0x1A42</code></td>
<td><code>0x12A41A00</code></td>
</tr>
<tr>
<td style="text-align: right;">27</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x0B</code></td>
<td><code>0x1B00…0x1B42</code></td>
<td><code>0x12B41B00</code></td>
</tr>
<tr>
<td style="text-align: right;">28</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x0C</code></td>
<td><code>0x1C00…0x1C42</code></td>
<td><code>0x12C41C00</code></td>
</tr>
<tr>
<td style="text-align: right;">29</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x0D</code></td>
<td><code>0x1D00…0x1D42</code></td>
<td><code>0x12D41D00</code></td>
</tr>
<tr>
<td style="text-align: right;">30</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x0E</code></td>
<td><code>0x1E00…0x1E42</code></td>
<td><code>0x12E41E00</code></td>
</tr>
<tr>
<td style="text-align: right;">31</td>
<td>Резерв назначения</td>
<td><code>0x02 / 0x0F</code></td>
<td><code>0x1F00…0x1F42</code></td>
<td><code>0x12F41F00</code></td>
</tr>
</tbody>
</table>
<h2 id="can-1">Прошивка приборов по CAN</h2>
<p>Ниже зафиксирован формат планируемого загрузочного сервиса. Значения
<code>MsgType=0x9..0xD</code> зарезервированы в протоколе, но обработчики загрузчика в
текущих <code>protocan.c/.h</code> ещё не реализованы.</p>
<p>Загрузчик <code>MsgType=0x9…0xD</code> реализован в <code>c/protocan-boot</code>. Актуальные команды, A/B и single-slot: <a href="protocan/BOOTLOADER.md">BOOTLOADER.md</a>. Ниже сохранена историческая таблица; при расхождении применяется актуальная спецификация.</p>
<p>Загрузчик работает поверх classic CAN 2.0B с Extended ID. Управляющий модуль
использует <code>Route=0</code>, прибор отвечает с <code>Route=1</code>. Команды стирания и записи
всегда должны быть адресованы конкретной паре <code>DeviceType/DeviceID</code>;
@@ -704,8 +931,8 @@ DATA[4..7] RunningCRC32, uint32 little-endian
<tr style="height:18px">
<td class="x22">0x1. Стандартный</td>
<td class="x23">0х1. Устройство</td>
<td colspan="3" class="x131">0x1</td>
<td colspan="4" class="x136">0x0 - 0xF устройств</td>
<td colspan="3" class="x131">0x01 PERIPH</td>
<td colspan="4" class="x136">0x0–0xF; PERIPH 0–15<br>0x5: УМП1; 0x6: УМП2; 0x8: Задатчик</td>
<td colspan="12" class="x134">0x1. Запрос на вкл/выкл</td>
<td colspan="4" class="x176">Выбор &quot;страницы&quot; из 64 устройств (Битовые флаги в Data)</td>
<td class="x14">&nbsp;</td>
@@ -716,8 +943,8 @@ DATA[4..7] RunningCRC32, uint32 little-endian
<tr style="height:17px">
<td class="x26">&nbsp;</td>
<td class="x27">&nbsp;</td>
<td colspan="3" class="x131">0x2</td>
<td colspan="4" class="x136">0x0 - 0xF устройств</td>
<td colspan="3" class="x131">0x02 PERIPH</td>
<td colspan="4" class="x136">0x0–0xF; PERIPH 16–31</td>
<td colspan="12" class="x134">0x2. Рестарт устройств</td>
<td colspan="4" class="x176">Выбор &quot;страницы&quot; из 64 устройств (Битовые флаги в Data)</td>
<td class="x14">&nbsp;</td>
@@ -955,14 +1182,14 @@ DATA[4..7] RunningCRC32, uint32 little-endian
<td class="x27">&nbsp;</td>
<td colspan="4" class="x144">&nbsp;</td>
<td colspan="4" class="x147"><a href="#sheet-oap">0x3. Общее адресное пространство</a></td>
<td colspan="16" class="x159">Адрес регистра (Стартовый адрес, если DLC COUNT &gt; 2) (0, 0x0000 - 65535, 0xFFFF)</td>
<td colspan="16" class="x159">GAS: адрес первого 16-битного регистра 0x0000…0xFFFF; до четырёх последовательных значений.</td>
<td class="x14">&nbsp;</td>
<td colspan="4" class="x106">0/2/4/6/8</td>
<td class="x14">&nbsp;</td>
<td colspan="2" class="x106">Четвёртый регистр</td>
<td colspan="2" class="x108">Третий регистр</td>
<td colspan="2" class="x108">Второй регистр</td>
<td colspan="2" class="x108">Первый регистр</td>
<td colspan="2" class="x106">Регистр addr+3</td>
<td colspan="2" class="x108">Регистр addr+2</td>
<td colspan="2" class="x108">Регистр addr+1</td>
<td colspan="2" class="x108">Регистр addr+0</td>
</tr>
<tr style="height:17px">
<td class="x26">&nbsp;</td>
@@ -971,13 +1198,12 @@ DATA[4..7] RunningCRC32, uint32 little-endian
<td class="x27">&nbsp;</td>
<td class="x27">&nbsp;</td>
<td colspan="4" class="x144">&nbsp;</td>
<td colspan="4" class="x148">0x4. Modbus Coil</td>
<td colspan="12" class="x160">Стартовый адрес регистра (0x0 - 0xFFF)</td>
<td colspan="4" class="x161">Кол-во регистров (0-15)</td>
<td colspan="4" class="x148">0x4. GAS SLOT</td>
<td colspan="16" class="x159">Адрес слота 0x0000…0xFFFF</td>
<td class="x14">&nbsp;</td>
<td colspan="4" class="x97">&nbsp;</td>
<td colspan="4" class="x97">0/8</td>
<td class="x14">&nbsp;</td>
<td colspan="8" class="x97">NULL</td>
<td colspan="8" class="x97">Word3 | Word2 | Word1 | Word0: маска битов 1…3</td>
</tr>
<tr style="height:17px">
<td class="x26">&nbsp;</td>
@@ -1421,8 +1647,8 @@ DATA[4..7] RunningCRC32, uint32 little-endian
</tr>
</tbody>
</table></div>
<p><a id="sheet-oap"></a></p>
<h2 id="section-6">Лист «Общее адресное пространство»</h2>
<p><a id="sheet-oap-legacy"></a></p>
<h2 id="legacy">Исторический лист «ОАП legacy»: адреса регистров</h2>
<p class="sheet-note">Таблица прокручивается по горизонтали; длинный лист ограничен по высоте окна.</p>
<div class="table-wrap"><table class="excel-table oap-table">
<colgroup>
@@ -13399,6 +13625,4 @@ DATA[4..7] RunningCRC32, uint32 little-endian
</tr>
</tbody>
</table></div>
</body>
</html>
</body></html>

View File

@@ -2,16 +2,61 @@
Таблицы перенесены из `Протокол CAN и ОАП.xlsx`. Цвета, объединённые ячейки и структура листов сохранены средствами HTML внутри Markdown.
Адреса PERIPH обновлены по листу «Интерфейс протокола», A44:F79:
Type `0x01` содержит PERIPH 0–15, Type `0x02` — PERIPH 16–31;
Device ID равен младшим четырём битам номера PERIPH.
УМП1 — `0x01/0x05`, УМП2 — `0x01/0x06`, задатчик — `0x01/0x08`.
Назначения остальных mode уточнены по periph_28335: 1/2 — трансформаторы, 3/4 — силовые узлы, 7 — ENG1, 9 — шкаф; 10/11 — служебные роли. Общий Boot-адрес `0x03/0x07` отменён.
Полный [реестр назначений](DEVICE_REGISTRY.md) применяется и к загрузчику, и к GUI.
- [Интерфейс протокола](#sheet-protocol)
- [Общее адресное пространство](#sheet-oap)
- [Прошивка приборов по CAN](#can-firmware)
<a id="can-firmware"></a>
<a id="sheet-oap"></a>
## GAS: регистры 0x3 и масочные слоты 0x4
Нормативная спецификация: [OAP.md](protocan/OAP.md). GAS 0x3: адрес первого регистра 0…65535, DLC 0/2/4/6/8. GAS SLOT 0x4: Word0 — маска битов 1…3, Word1…Word3 — три значения, DLC 0/8. PERIPH сохраняет 200 значений в 67 слотах; последний содержит два. Словный реестр ниже сохраняет адреса GAS 0x3.
| mode | Назначение | Type / ID | Слоты 0x4 | CAN запрос |
|---:|---|---|---|---|
| 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` |
## Прошивка приборов по CAN
Ниже зафиксирован формат планируемого загрузочного сервиса. Значения
`MsgType=0x9..0xD` зарезервированы в протоколе, но обработчики загрузчика в
текущих `protocan.c/.h` ещё не реализованы.
Загрузчик `MsgType=0x9…0xD` реализован в `c/protocan-boot`. Актуальные команды, A/B и single-slot: [BOOTLOADER.md](protocan/BOOTLOADER.md). Ниже сохранена историческая таблица; при расхождении применяется актуальная спецификация.
Загрузчик работает поверх classic CAN 2.0B с Extended ID. Управляющий модуль
использует `Route=0`, прибор отвечает с `Route=1`. Команды стирания и записи
@@ -576,8 +621,8 @@ CRC32 обнаруживает случайное повреждение, но
<tr style="height:18px">
<td class="x22">0x1. Стандартный</td>
<td class="x23">0х1. Устройство</td>
<td colspan="3" class="x131">0x1</td>
<td colspan="4" class="x136">0x0 - 0xF устройств</td>
<td colspan="3" class="x131">0x01 PERIPH</td>
<td colspan="4" class="x136">0x0–0xF; PERIPH 0–15<br>0x5: УМП1; 0x6: УМП2; 0x8: Задатчик</td>
<td colspan="12" class="x134">0x1. Запрос на вкл/выкл</td>
<td colspan="4" class="x176">Выбор &quot;страницы&quot; из 64 устройств (Битовые флаги в Data)</td>
<td class="x14">&nbsp;</td>
@@ -588,8 +633,8 @@ CRC32 обнаруживает случайное повреждение, но
<tr style="height:17px">
<td class="x26">&nbsp;</td>
<td class="x27">&nbsp;</td>
<td colspan="3" class="x131">0x2</td>
<td colspan="4" class="x136">0x0 - 0xF устройств</td>
<td colspan="3" class="x131">0x02 PERIPH</td>
<td colspan="4" class="x136">0x0–0xF; PERIPH 16–31</td>
<td colspan="12" class="x134">0x2. Рестарт устройств</td>
<td colspan="4" class="x176">Выбор &quot;страницы&quot; из 64 устройств (Битовые флаги в Data)</td>
<td class="x14">&nbsp;</td>
@@ -827,14 +872,14 @@ CRC32 обнаруживает случайное повреждение, но
<td class="x27">&nbsp;</td>
<td colspan="4" class="x144">&nbsp;</td>
<td colspan="4" class="x147"><a href="#sheet-oap">0x3. Общее адресное пространство</a></td>
<td colspan="16" class="x159">Адрес регистра (Стартовый адрес, если DLC COUNT &gt; 2) (0, 0x0000 - 65535, 0xFFFF)</td>
<td colspan="16" class="x159">GAS: адрес первого 16-битного регистра 0x0000…0xFFFF; до четырёх последовательных значений.</td>
<td class="x14">&nbsp;</td>
<td colspan="4" class="x106">0/2/4/6/8</td>
<td class="x14">&nbsp;</td>
<td colspan="2" class="x106">Четвёртый регистр</td>
<td colspan="2" class="x108">Третий регистр</td>
<td colspan="2" class="x108">Второй регистр</td>
<td colspan="2" class="x108">Первый регистр</td>
<td colspan="2" class="x106">Регистр addr+3</td>
<td colspan="2" class="x108">Регистр addr+2</td>
<td colspan="2" class="x108">Регистр addr+1</td>
<td colspan="2" class="x108">Регистр addr+0</td>
</tr>
<tr style="height:17px">
<td class="x26">&nbsp;</td>
@@ -843,13 +888,12 @@ CRC32 обнаруживает случайное повреждение, но
<td class="x27">&nbsp;</td>
<td class="x27">&nbsp;</td>
<td colspan="4" class="x144">&nbsp;</td>
<td colspan="4" class="x148">0x4. Modbus Coil</td>
<td colspan="12" class="x160">Стартовый адрес регистра (0x0 - 0xFFF)</td>
<td colspan="4" class="x161">Кол-во регистров (0-15)</td>
<td colspan="4" class="x148">0x4. GAS SLOT</td>
<td colspan="16" class="x159">Адрес слота 0x0000…0xFFFF</td>
<td class="x14">&nbsp;</td>
<td colspan="4" class="x97">&nbsp;</td>
<td colspan="4" class="x97">0/8</td>
<td class="x14">&nbsp;</td>
<td colspan="8" class="x97">NULL</td>
<td colspan="8" class="x97">Word3 | Word2 | Word1 | Word0: маска битов 1…3</td>
</tr>
<tr style="height:17px">
<td class="x26">&nbsp;</td>
@@ -1294,8 +1338,8 @@ CRC32 обнаруживает случайное повреждение, но
</tbody>
</table></div>
<a id="sheet-oap"></a>
## Лист «Общее адресное пространство»
<a id="sheet-oap-legacy"></a>
## Исторический лист «ОАП legacy»: адреса регистров
<p class="sheet-note">Таблица прокручивается по горизонтали; длинный лист ограничен по высоте окна.</p>

File diff suppressed because one or more lines are too long