Files
templates/c/set-protocol/docs/STM_INVERTOR_GAS.md
T
Andrey e52ba797e4 feat(set-protocol): Добавь DEIF XDi, STM Invertor и порт HOPE G474
Объедини реализацию DEIF в C99-ядре, чтобы Python и Android
использовали один кодек и общие эталонные кадры.
Добавь две GAS-проекции единой карты STM Invertor и аппаратные
порты эмулятора и загрузчика для платы HOPE STM32G474VET6.

Проверки: сборка MSVC Debug, 24 теста CTest, 30 тестов Python
и 29 дополнительных проверок, синтаксис 16 файлов Python.
2026-10-24 15:39:59 +03:00

39 lines
5.3 KiB
Markdown

# STM Invertor: GAS 0x03 и GAS SLOT 0x04
Узел: DeviceType `0x7`, DeviceID `0xE`. Обработчик `set_invertor_gas_handle()` выбирает формат только по MsgType и использует существующие кодеки `pcan_gas` и `pcan_gas_slot`.
| Доступ | Адреса | Содержимое |
| --- | --- | --- |
| GAS `0x03` | Регистры `0x0000…0x02ED` / 0…749 | По 1…4 последовательных 16-битных значения; DLC 2/4/6/8 |
| GAS SLOT `0x04` | Слоты `0x0000…0x00F9` / 0…249 | Word0 — маска; Word1…Word3 — три значения; DLC 8 |
Это две проекции **одних 750 значений**. Отдельного массива слотов нет. Для слота `s` и полезного слова `w=1…3`: `Register=3*s+w-1`. Обратное отображение: `Slot=Register/3`, `Word=1+Register%3`. Word0 не является регистром.
Начальные адреса относятся к узлу 7/E и не перенумеровывают PERIPH. Наличие 750 адресов не требует выделения 1500 байт сплошной RAM: provider обслуживает только существующие данные и явно отклоняет неподключённые значения.
## Примеры
Запись регистра 1 значением `0x1234`: ID `0x17E30001`, DLC 2, Data `34 12`.
Запись того же значения через слот 0 / Word2: ID `0x17E40000`, DLC 8, Data `04 00 00 00 34 12 00 00`. Word1 и Word3 сохраняются.
Чтение любого представления использует DLC=0, Route=0. Ответ имеет Route=1. Первый регистровый ответ использует ID `0x1FE30000`, слотный — `0x1FE40000`. Прикладного ACK записи нет; при необходимости результат применения проверяется чтением статуса устройства.
## Прикладной порт
`read(context, address, value)` возвращает ноль для достоверного значения. Ошибка не подменяется успешным нулём. Регистровое чтение останавливается на первом недоступном адресе; слотный ответ отмечает маской каждую доступную позицию. Полностью недоступный слот не возвращает пустую успешную маску.
`write(context, addresses, values, count)` получает выбранные адреса единым набором. Provider сначала проверяет все права, диапазоны, состояния и значения, затем применяет набор под общей блокировкой. Неотмеченные позиции слота ему не передаются. Масочная запись не делает скрытого чтения и не требует перезаписывать readonly-соседей.
Регистровый адаптер сначала собирает все слова через существующий кодек 0x03. Он не вызывает write-provider при частичном выходе за 750 регистров. Усиленная проверка относится к этому адаптеру изделия и не меняет общий контракт блочной записи `pcan_gas` для остальных устройств.
Вызовы обработки одного экземпляра сериализуются приложением. Снимок чтения и применение записи защищает приложение; библиотека не включает прерывания, аппаратные разрешения или HAL. Наличие запроса на запись не подтверждает физическое выполнение команды силовой частью.
## Клиентские привязки
`set_invertor_gas_build()` возвращает готовые CAN ID и октеты; `set_invertor_gas_decode()` — проверенные тип, адрес и wire-слова ответа. Python/JNI не повторяют endian, маски идентификатора или формулу адресации. Размеры карт получают через `set_invertor_gas_limit()`.
`set_invertor_gas_register()` и `set_invertor_gas_coordinate()` возвращают проверенные координаты, не меняя выходы при отказе. Диспетчер не переводит повреждённый 0x04 в 0x03 и не принимает запросы соседнего узла либо эхо ответа как запись.
Тест `test_invertor_gas.c` проверяет оба wire-вектора, общий источник данных, маски, сохранение соседей, readonly, единственное применение набора, границы 249/749, ошибочные длины, флаги и адреса, а также клиентский ABI.