Что ожидает модуль
main.hиcan.hиз CubeMX- STM32 HAL CAN, RTC и TIM
- CAN FIFO0 и Extended ID
- STM32 GCC ABI для C bit-fields
diff --git a/c/set-protocol/docs/legacy/PROTOCOL.md b/c/set-protocol/docs/legacy/PROTOCOL.md
index 3daef73..4c044d2 100644
--- a/c/set-protocol/docs/legacy/PROTOCOL.md
+++ b/c/set-protocol/docs/legacy/PROTOCOL.md
@@ -3,7 +3,7 @@
> GAS `0x3` использует адреса отдельных 16-битных регистров. GAS SLOT `0x4` — отдельный сервис с маской в Word0 и тремя значениями Word1…Word3. Полный контракт: [ОАП](../../../../doc/setcan/protocan/OAP.md). Существующие регистровые сервисы сохраняют свои адреса.
Статус: **Stable с зарезервированным загрузочным расширением**
-Версия: **2.1: GAS 0x3 и масочный GAS SLOT 0x4** IRQ вычитывает FIFO0. Pulse обрабатывается сразу, остальные Extended-кадры попадают в кольцевой буфер и разбираются в основном цикле. Прикладные действия, хранение SETTINGS, EEPROM, DS18B20, таймаут online/offline и полноценный bootloader не входят в ядро.
+Версия: **2.2: единый Modbus 0x5, функции и количество 1…4**
Порядок байтов payload: **little-endian**, если явно не указано иное
## Назначение
@@ -63,9 +63,8 @@ can_id =
| `0x2` | `ANALOG` | оба | 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 |
+| `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 |
@@ -83,7 +82,7 @@ can_id =
|---|---|
| broadcast | команда `[15:4]`, параметр `[3:0]` |
| discrete/analog | подтип `[15:12]`, значение/адрес `[11:0]` |
-| Modbus | начальный адрес `[15:4]`, количество `[3: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]` |
@@ -91,6 +90,35 @@ can_id =
| 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.
diff --git a/c/set-protocol/ports/stm32-bxcan/README.md b/c/set-protocol/ports/stm32-bxcan/README.md
index 04c89a3..537bfdf 100644
--- a/c/set-protocol/ports/stm32-bxcan/README.md
+++ b/c/set-protocol/ports/stm32-bxcan/README.md
@@ -81,9 +81,8 @@ c/set-protocol/
| `0x2` | аналоговое (`ANALOG`) |
| `0x3` | общее адресное пространство |
| `0x4` | GAS SLOT: Word0-маска и три значения |
-| `0x5` | Modbus Discrete |
-| `0x6` | Modbus Holding |
-| `0x7` | Modbus Input |
+| `0x5` | Modbus: функции 1…4, количество 1…4 |
+| `0x6…0x7` | Резерв |
| `0x8` | ошибка |
| `0x9` | управление загрузчиком (`BOOT_CONTROL`, зарезервировано) |
| `0xA` | данные прошивки, слот A (`BOOT_DATA_A`, зарезервировано) |
@@ -98,7 +97,7 @@ c/set-protocol/
- broadcast: младшие 4 бита — дополнительное поле, старшие 12 бит — команда;
- discrete: младшие 12 бит — данные/адрес, старшие 4 бита — подтип;
- analog: младшие 12 бит — ID датчика, старшие 4 бита — тип величины;
-- Modbus: младшие 4 бита — количество регистров, старшие 12 бит — начальный адрес;
+- Modbus: адрес `[15:4]`, функция минус один `[3:2]`, количество минус один `[1:0]`; функция и количество 1…4;
- SETTINGS: старший байт — номер сборки `Z`, младший байт — позиция `Y`;
- error: младший байт — код ошибки, старший байт — дополнительная информация.
@@ -264,7 +263,7 @@ PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogTSens(struct RXMsg msg)
- `ProtoCanMsgToAnalog...()` — универсальные данные, настройки, U/I/T;
- `ProtoCanMsgToSettings()` — GET/WRITE/CLEAR привязки ROM к локации;
- `ProtoCanMsgToGeneralAddressSpace()`;
-- `ProtoCanMsgToModbus...()`;
+- `ProtoCanMsgToModbus()`;
- `PROTOCAN_RequestError()`.
Стандартные слабые обработчики в основном являются демонстрационными: часть возвращает `PROTOCAN_OK` без действий, часть отправляет текстовые ответы вроде `TS0001` или `GAS-0001`. Для рабочего изделия их обычно нужно переопределить.
@@ -373,7 +372,7 @@ tx.ErrorData.Info = 0x34;
(void)PROTOCAN_SEND(id, tx);
```
-Для `BROADCAST`, `DISCRETE` и `ANALOG` используется `tx.CoreData`; для Modbus-типов — `tx.ModbusData`, для `SETTINGS` — `tx.SettingsData`. Для успешных ответов и ошибок SETTINGS удобнее использовать готовые функции `PROTOCAN_SEND_SETTINGS_RESPONSE()` и `PROTOCAN_SEND_SETTINGS_ERROR()`. Если количество передаваемых элементов больше нуля, соответствующий указатель `Data` должен быть валиден до завершения вызова.
+Для `BROADCAST`, `DISCRETE` и `ANALOG` используется `tx.CoreData`; для единого Modbus — `tx.ModbusData` с полями `Function` и `RegCount` 1…4, для `SETTINGS` — `tx.SettingsData`. Для успешных ответов и ошибок SETTINGS удобнее использовать готовые функции `PROTOCAN_SEND_SETTINGS_RESPONSE()` и `PROTOCAN_SEND_SETTINGS_ERROR()`. Если количество передаваемых элементов больше нуля, соответствующий указатель `Data` должен быть валиден до завершения вызова.
## Пульс устройства
@@ -605,4 +604,4 @@ CRC32 обнаруживает случайное повреждение, но
[Адресация GAS](../../docs/GAS_SLOT.md): `0x3` — отдельные 16-битные регистры `0…65535`, запись 1…4 слов. `0x4` — слот с Word0-маской и тремя значениями; PERIPH сохраняет 200 слов в 67 слотах `0xMM00…0xMM42`. Формат определяется MsgType, без настройки профиля.
-`PROTOCAN_GAS_SLOT_BIND(&port)` подключает provider типа 0x4 до обработки очереди. `ProtoCanMsgToGasSlot()` вызывает общий адресный обработчик, `PROTOCAN_SEND_GAS_SLOT()` кодирует Word0-маску и три значения. Неподключённый provider возвращает ошибку. Типы Modbus 0x5…0x7 сохраняют прежние номера.
+`PROTOCAN_GAS_SLOT_BIND(&port)` подключает provider типа 0x4 до обработки очереди. `ProtoCanMsgToGasSlot()` вызывает общий адресный обработчик, `PROTOCAN_SEND_GAS_SLOT()` кодирует Word0-маску и три значения. Неподключённый provider возвращает ошибку. Единый Modbus использует MsgType 0x5; коды 0x6/0x7 свободны. `ProtoCanMsgToModbus()` заменяет три прежних weak-обработчика; функция и количество извлекаются через `pcan_modbus_function()` и `pcan_modbus_count()`. `PROTOCAN_SEND_MODBUS()` отправляет одно окно 1…4; `Data=NULL` означает запрос чтения, битовые банки используют маску в `Data[0]`. Неподключённая карта отвечает штатной ошибкой, без демонстрационных ASCII-значений.
diff --git a/doc/setcan/index.html b/doc/setcan/index.html
index c455bb1..0cffed8 100644
--- a/doc/setcan/index.html
+++ b/doc/setcan/index.html
@@ -134,7 +134,7 @@
└── doc/index.html эта страница
Что ожидает модуль
main.h и can.h из CubeMXПуть кадра
Единая точка отправки
PROTOCAN_SEND() выбирает упаковщик по MsgType. GAS и Modbus автоматически разбиваются на кадры до 8 байт.Единая точка отправки
PROTOCAN_SEND() выбирает упаковщик по MsgType. GAS разбивается на кадры до 8 байт; единый Modbus передаёт одно окно из 1–4 битов или регистров.Что приложение реализует само
Переопределите нужную __weak-функцию в собственном C-файле: семейства ProtoCanMsgToBroadcast…, …Discrete…, …Analog…, ProtoCanMsgToSettings, ProtoCanMsgToGeneralAddressSpace и …Modbus…. Не редактируйте демонстрационную реализацию в ядре — так обновлять библиотеку проще.
Переопределите нужную __weak-функцию в собственном C-файле: семейства ProtoCanMsgToBroadcast…, …Discrete…, …Analog…, ProtoCanMsgToSettings, ProtoCanMsgToGeneralAddressSpace и ProtoCanMsgToModbus. Не редактируйте демонстрационную реализацию в ядре — так обновлять библиотеку проще.
| Код | Тип | Назначение | Статус |
|---|---|---|---|
| 0x0 | BROADCAST | Общие команды всем устройствам | stable |
| 0x1 | DISCRETE | Состояния, команды, флаги | stable |
| 0x2 | ANALOG | Датчики U / I / T и универсальные данные | stable |
| 0x3 | GAS | Общее 16-битное адресное пространство | stable |
| 0x4 | GAS SLOT | Word0 — маска битов 1…3, Word1…Word3 — три значения | stable |
| 0x5…0x7 | MODBUS | Discrete, Holding, Input | stable |
| 0x8 | ERROR | Код ошибки и дополнительная информация | stable |
| 0x9…0xD | BOOT | Управление, блоки A/B, статус, discovery | draft |
| 0xE | SETTINGS | Привязка 1-Wire ROM к локации Z/Y | stable |
| 0xF | PULSE | Присутствие устройства | stable |
| 0x0 | BROADCAST | Общие команды всем устройствам | stable |
| 0x1 | DISCRETE | Состояния, команды, флаги | stable |
| 0x2 | ANALOG | Датчики U / I / T и универсальные данные | stable |
| 0x3 | GAS | Общее 16-битное адресное пространство | stable |
| 0x4 | GAS SLOT | Word0 — маска битов 1…3, Word1…Word3 — три значения | stable |
| 0x5 | MODBUS | Функция 1–4: Coil, Discrete, Holding, Input; количество 1–4 | stable |
| 0x6…0x7 | Резерв | Свободны | reserved |
| 0x8 | ERROR | Код ошибки и дополнительная информация | stable |
| 0x9…0xD | BOOT | Управление, блоки A/B, статус, discovery | draft |
| 0xE | SETTINGS | Привязка 1-Wire ROM к локации Z/Y | stable |
| 0xF | PULSE | Присутствие устройства | stable |
Статус: Stable с зарезервированным загрузочным расширением
-Версия: 2.1: GAS 0x3 и масочный GAS SLOT 0x4
+Версия: 2.2: единый Modbus 0x5, функции и количество 1…4
Порядок байтов payload: little-endian, если явно не указано иное
ProtoCAN — прикладной протокол поверх classic CAN 2.0B. Используются только @@ -515,24 +515,17 @@ Priority Route DeviceType DeviceID MsgType MsgBody
0x5MODBUS_DISCRETEMODBUS0x6MODBUS_HOLDING0x7MODBUS_INPUT0x6…0x70x8[15:12], значение/адрес [11:0][15:4], количество [3:0][15:4], функция − 1 [3:2], количество − 1 [1:0]Контракт обоих GAS: OAP.md. Тип 0x3 адресует отдельные слова; тип 0x4 имеет маску битов 1…3 в Word0 и три значения. Для PERIPH 0x4 используются 67 слотов 0xMM00…0xMM42, последний содержит два значения. Старый Coil 0x4 заменён; формат определяется MsgType.
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
+сохраняет своё назначение.
Профиль синхронизации часов и сообщения платы о завершении инициализации:
GLOBAL_TIME.md. Он сохраняет штатный BROADCAST RTCSETUP
@@ -1104,7 +1150,7 @@ Provider проверяет все выбранные права и значен
Word0 — метаданные кадра, не четвёртый хранимый регистр. Координата значения —
(SlotAddress, WordIndex), где WordIndex=1…3. Любой узел поддерживается общими
pcan_gas_slot_id() и pcan_gas_slot_handle_address(); адрес слота не ограничен страницами PERIPH.
-Тип 0x4 MODBUS_COIL заменён этим сервисом. Modbus 0x5/0x6/0x7 сохраняет номера.
+Тип 0x4 MODBUS_COIL заменён этим сервисом. Единый Modbus использует 0x5, функцию и количество 1…4 в Body; 0x6/0x7 свободны.
Старое оборудование с Coil 0x4 требует согласованного обновления; автоопределения формата нет.
mode=0…31; DeviceType=1+mode/16, DeviceID=mode mod 16.
@@ -1490,10 +1536,18 @@ GAS 0x3 сохраняет собственные адреса подключё
Modbus Discrete/Holding/Input объединены в MsgType 0x5; Coil/Discrete/Holding/Input выбираются функцией 1…4, количество ограничено 1…4.
+Body Modbus: адрес [15:4], функция минус один [3:2], количество минус один [1:0]; номера 0x6/0x7 освобождены.
+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 согласованы.
+