Files
templates/c/set-protocol/docs/legacy/PROTOCOL.md
T

146 lines
7.7 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.
# ProtoCAN — базовый протокол
> GAS `0x3` использует адреса отдельных 16-битных регистров. GAS SLOT `0x4` — отдельный сервис с маской в Word0 и тремя значениями Word1…Word3. Полный контракт: [ОАП](../../../../doc/setcan/protocan/OAP.md). Существующие регистровые сервисы сохраняют свои адреса.
Статус: **Stable с зарезервированным загрузочным расширением**
Версия: **2.2: единый Modbus 0x5, функции и количество 1…4**<br>
Порядок байтов payload: **little-endian**, если явно не указано иное
## Назначение
ProtoCAN — прикладной протокол поверх classic CAN 2.0B. Используются только
расширенные 29-битные идентификаторы (`IDE=1`) и payload длиной 0…8 байт.
## Термины
| Термин | Значение |
|---|---|
| ПМ | управляющий модуль |
| прибор | адресуемый узел на шине |
| `DeviceType` | тип прибора, 0…7 |
| `DeviceID` | экземпляр прибора данного типа, 0…15 |
| `MsgType` | класс сообщения или сервис |
| `MsgBody` | 16-битное поле, формат которого зависит от `MsgType` |
Пара `DeviceType/DeviceID` задаёт до `8 × 16 = 128` уникальных адресов.
## Расширенный CAN ID
```text
28 27 26...24 23...20 19...16 15........0
Priority Route DeviceType DeviceID MsgType MsgBody
1 бит 1 бит 3 бита 4 бита 4 бита 16 бит
```
```c
can_id =
((uint32_t)priority << 28) |
((uint32_t)route << 27) |
((uint32_t)device_type << 24) |
((uint32_t)device_id << 20) |
((uint32_t)msg_type << 16) |
msg_body;
```
| Поле | Значения | Назначение |
|---|---|---|
| `Priority` | `0` critical, `1` standard | CAN-арбитраж |
| `Route` | `0` от ПМ, `1` от прибора | логическое направление |
| `DeviceType` | `0…7` | тип прибора |
| `DeviceID` | `0…15` | номер экземпляра |
| `MsgType` | `0…15` | тип сообщения |
| `MsgBody` | `0…65535` | команда, адрес или номер блока |
`Route` не является направлением физического трансивера. Ответ прибора
сохраняет адрес `DeviceType/DeviceID` и устанавливает `Route=1`.
## Реестр `MsgType`
| Код | Имя | Основное направление | DLC | Статус |
|---:|---|---|---:|---|
| `0x0` | `BROADCAST` | ПМ → все | зависит от команды | stable |
| `0x1` | `DISCRETE` | оба | 0…8 | stable |
| `0x2` | `ANALOG` | оба | 0…8 | stable |
| `0x3` | `GAS` | оба | 0/2/4/6/8 | регистры 0…65535 |
| `0x4` | `GAS_SLOT` | оба | 0/8 | Word0 — маска, Word1…Word3 — значения |
| `0x5` | `MODBUS` | оба | 0/1/2/4/6/8 | функции 1…4, количество 1…4 |
| `0x6…0x7` | резерв | — | — | свободны |
| `0x8` | `ERROR` | прибор → ПМ | 0 | stable |
| `0x9` | `BOOT_CONTROL` | ПМ → прибор | 0/8 | draft |
| `0xA` | `BOOT_DATA_A` | ПМ → прибор | 8 | draft |
| `0xB` | `BOOT_DATA_B` | ПМ → прибор | 8 | draft |
| `0xC` | `BOOT_STATUS` | прибор → ПМ | 8 | draft |
| `0xD` | `BOOT_DISCOVERY` | прибор → ПМ | 8 | draft |
| `0xE` | `SETTINGS` | оба | 0/1/8 | stable |
| `0xF` | `PULSE` | прибор → сеть | 1 | stable |
Подробный формат `0x9…0xD` находится в [BOOTLOADER.md](BOOTLOADER.md).
## Разметки `MsgBody`
| `MsgType` | Биты `MsgBody` |
|---|---|
| broadcast | команда `[15:4]`, параметр `[3:0]` |
| discrete/analog | подтип `[15:12]`, значение/адрес `[11:0]` |
| Modbus 0x5 | адрес `[15:4]`, функция − 1 `[3:2]`, количество − 1 `[1: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]` |
## Единый Modbus `0x5`
Все четыре банка используют один `MsgType=0x5`. Коды `0x6` и `0x7` свободны.
Начальный адрес занимает `[15:4]` и лежит в диапазоне `0x000…0xFFF`.
Биты `[3:2]` содержат `Function − 1`, биты `[1:0]` — `RegCount − 1`.
Физические значения функции и количества: **1…4**. Всё окно должно помещаться
в 4096 адресов: `StrAdr + RegCount ≤ 4096`.
| Функция | Банк | Элемент | DLC данных |
|---:|---|---|---|
| 1 | Coil | дискретный выход | 1 байт для 1…4 битов |
| 2 | Discrete | дискретный вход | 1 байт для 1…4 битов |
| 3 | Holding | 16-битный регистр | `2 × RegCount`, 2/4/6/8 байт |
| 4 | Input | 16-битный регистр | `2 × RegCount`, 2/4/6/8 байт |
Это селектор банка в ProtoCAN по нумерации функций Modbus, без RTU-заголовка
и CRC. Сохраняется правило ProtoCAN: `Route=0, DLC=0` читает окно;
непустой payload записывает Coil/Holding, Discrete/Input доступны только
для чтения. Ответ имеет `Route=1`, сохраняет `MsgBody` и содержит значения
либо эхо успешной записи. RTR запрещён. Биты упакованы начиная с младшего,
старшие неиспользуемые биты нулевые. Регистры передаются little-endian.
Пример: адрес `0x123`, функция 3, четыре регистра дают
`MsgBody = (0x123 << 4) | ((3 − 1) << 2) | (4 − 1) = 0x123B`.
Изменение wire-формата несовместимо с прежними отдельными типами
`0x5/0x6/0x7`: узлы и клиенты обновляются согласованно. Тип GAS SLOT `0x4`
сохраняет своё назначение.
## Общие правила обмена
- Многобайтовые значения в `DATA` передаются little-endian.
- Узел игнорирует адресованные кадры с чужим `DeviceType/DeviceID`.
- Прибор принимает команды ПМ с `Route=0`; ПМ принимает ответы с `Route=1`.
- Стандартные 11-битные CAN ID не являются кадрами ProtoCAN.
- RTR для загрузочного сервиса запрещён.
- Неописанные комбинации `MsgType/MsgBody/DLC` должны отвергаться.
## Эталон упаковки ID
```text
Priority = 1
Route = 0
DeviceType = 3
DeviceID = 5
MsgType = 0x9
MsgBody = 0x0702
CAN ID = 0x13590702
```
Этот пример соответствует `ENTER_BOOT`, `SessionID=7`. Машинные варианты
находятся в [examples/test-vectors.json](examples/test-vectors.json).