Сохрани адресацию отдельных регистров GAS 0x3 и выдели слотам тип 0x4 с маской Word0. Добавь единое C-ядро GAS_WATCH2, тонкие Python/JNI-порты и проверки общих эталонных байтов. Совместимость: тип 0x4 больше не обслуживает Modbus Coil. Потребителям PCAN_MSG_MODBUS_COIL и ProtoCanMsgToModbusCoil нужно перейти на GAS_SLOT и отдельный API слотов; регистровый GAS остаётся на 0x3.
4.2 KiB
GAS SLOT 0x4: маска в Word0
Нормативный контракт: ОАП. GAS 0x3 адресует отдельные 16-битные регистры; GAS SLOT 0x4 использует собственный адрес слота и заменяет прежний Modbus Coil.
Один кадр: Word0=маска, Word1, Word2, Word3; все слова little-endian. В Word0 допустимы только непустые комбинации битов 1…3 (0x0002…0x000E с нулевым битом 0). Бит выбирает одноимённое слово. Запись всегда DLC=8; невыбранные значения игнорируются и сохраняются в устройстве. DLC=0 запрашивает чтение; ответ DLC=8 содержит маску достоверных слов. RTR, standard/error frame, пустой ответ и усечённые данные отвергаются.
Изменить только Word2 на 0x1234: payload 04 00 00 00 34 12 00 00. Полная запись трёх значений использует маску 0x000E. Word0 — метаданные, не четвёртый регистр.
MCU
pcan_gas_slot_handle_address(type, id, port, request, response) обслуживает любой узел и слот 0…65535. Возвращает 1 при ответе, 0 после записи, -1 при отказе. Provider чтения заполняет четыре wire-слова, включая Word0-маску; provider записи сначала проверяет все выбранные права и значения, затем изменяет только отмеченные позиции под общей блокировкой. Кодек не гарантирует транзакционность внешних Flash/callback операций.
pcan_gas_slot_handle(mode, ...) дополнительно проверяет страницу PERIPH. Slot=(mode<<8)|LocalSlot, LocalSlot 0…66. Три значения на слот сохраняют 200 слов на mode; в последнем слоте доступны Word1/Word2. pcan_gas_slot_native(local, word, write, &address) принимает word 1…3 и переводит 3*local+word-1 в прежние native-сервисы. Нулевая позиция, резерв и запрещённая запись отвергаются.
Вызывать обработчик из главного цикла/задачи; ISR только принимает кадры. DLC измеряется wire-октетами, в том числе на C28x с 16-битным char. Общий формат не выделяет все 384 КиБ логического пространства в RAM.
Python и Android
GasSlots.frame(5, 0) возвращает (0x11540500, b''). frame(5, 0, [0x0004, 0, 0x1234, 0]) меняет только Word2. frame_address(7, 14, 65535, [...]) адресует независимый узел и полный 16-битный слот. decode() проверяет PERIPH, decode_address() — общий формат. Wire-маска и endian формируются единственным C-кодеком.
Android/JNI: nativeRequestId/nativeDecode для PERIPH; nativeAddressId/nativeDecodeWords для общего узла; nativeEncode принимает маску и три значения. Пустой запрос возвращает пустой набор значений; ошибка — null.
В CAN-журнале тип 0x4 выбирается автоматически по MsgType. Параметра gas_profile нет; 0x3 всегда отображается как регистры. GAS_WATCH2 и регистровые провайдеры 0x3 сохраняют адреса и ABI.
Проверки
CTest: protocan_gas_register, protocan_gas_slot, protocan_modbus_server; Python: test_gas_slots.py; JNI host smoke. Общие эталоны: doc/setcan/protocan/examples/gas-slot-vectors.json. Старые узлы Coil 0x4 несовместимы с новым назначением и обновляются согласованно.