Files
templates/c/set-protocol/include/pcan_gas_slot.h
T
Andrey 876b58517c feat(set-protocol): Раздели GAS и добавь пакетный сбор регистров
Сохрани адресацию отдельных регистров GAS 0x3 и выдели слотам тип 0x4 с маской Word0. Добавь единое C-ядро GAS_WATCH2, тонкие Python/JNI-порты и проверки общих эталонных байтов.

Совместимость: тип 0x4 больше не обслуживает Modbus Coil. Потребителям PCAN_MSG_MODBUS_COIL и ProtoCanMsgToModbusCoil нужно перейти на GAS_SLOT и отдельный API слотов; регистровый GAS остаётся на 0x3.
2026-10-23 14:14:48 +03:00

49 lines
8.0 KiB
C
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.
#ifndef PCAN_GAS_SLOT_H /* Отдельный интерфейс исключает смешение нового номера слота со старым адресом регистра. */
#define PCAN_GAS_SLOT_H /* Защита допускает включение из общего заголовка и непосредственно из порта MCU. */
#include <stdint.h> /* Фиксированные слова и uint_least8_t доступны также на C28x без восьмибитного char. */
#include <stddef.h> /* NULL используется без зависимости от ОС и динамической памяти. */
#include <limits.h> /* CHAR_BIT выбирает экспорт host ABI отдельно от 16-битного C28x. */
#if CHAR_BIT == 8 /* Host/ARM используют существующий экспорт DLL/SO. */
#include "pcan_abi.h" /* Переиспользуем публичный экспорт единого host-кодека. */
#elif !defined(PCAN_ABI_API) /* Встроенный C28x статически собирает функции без Windows-атрибутов. */
#define PCAN_ABI_API /* Не требуем отсутствующий на C28x uint8_t из host ABI. */
#endif /* Все последующие объявления одинаковы по смыслу на ARM, host и C28x. */
#ifdef __cplusplus /* C++ и JNI связываются с C99-ядром через стандартные C-имена. */
extern "C" { /* Начинаем область совместимого C ABI. */
#endif /* Дальнейшие объявления пригодны также для чистого C. */
#define PCAN_GAS_SLOT_WORDS 4U /* Восемь октетов кадра содержат четыре wire-слова: маску Word0 и три значения Word1…Word3. */
#define PCAN_GAS_SLOT_DATA_WORDS 3U /* Два октета маски оставляют шесть октетов для трёх независимых 16-битных значений. */
#define PCAN_GAS_SLOT_MASK 0x000EU /* Биты 1…3 выбирают одноимённые значения; бит 0 и биты 4…15 зарезервированы. */
#define PCAN_GAS_SLOT_MODE_COUNT 32U /* Два типа PERIPH по шестнадцать DeviceID дают mode 0…31. */
#define PCAN_GAS_SLOT_MODE_SLOTS 67U /* Округление 200/3 вверх сохраняет все регистры PERIPH; в последнем слоте действуют два значения. */
#define PCAN_GAS_SLOT_MODE_WORDS 200U /* Значение измеряется в 16-битных словах, не в байтах MCU. */
#define PCAN_GAS_SLOT_FLAG_IDE 1U /* Флаг Extended ID совпадает с транспортом pcan_frame; отдельно объявлен для C28x-порта. */
#define PCAN_GAS_SLOT_FLAG_RTR 2U /* RTR запрещён слотным профилем; запрос чтения использует data frame с DLC=0. */
#define PCAN_GAS_SLOT_FLAG_ERR 8U /* Ошибочный кадр моста не должен читаться как запрос к данным. */
typedef int (*pcan_gas_slot_read_fn)(void *, uint16_t, uint16_t[4]); /* Provider возвращает маску достоверных значений в Word0 и три значения; ноль означает успех. */
typedef int (*pcan_gas_slot_write_fn)(void *, uint16_t, const uint16_t[4]); /* Provider сначала проверяет все выбранные слова, затем меняет только биты 1…3 маски Word0 под общей блокировкой. */
typedef struct { /* Независимый MCU-кадр не меняет legacy ABI и не требует uint8_t на C28x. */
uint32_t id; /* Расширенный CAN ID содержит адрес узла и 16-битный номер слота. */
unsigned flags; /* IDE/RTR/ERR используют документированные значения транспортных флагов. */
unsigned dlc; /* Длина измеряется в октетах линии, а не в sizeof элементов C28x. */
uint_least8_t data[8]; /* На C28x октет хранится в 16-битной ячейке; значения строго 0…255. */
} pcan_gas_slot_frame_t; /* Порт переводит структуру в регистры CAN, не копируя wire-структуру через ABI. */
typedef struct { /* Один порт соединяет общий обработчик с данными конкретного узла без глобальной памяти. */
void *context; /* Контекст принадлежит проекту и должен жить дольше обработчика. */
pcan_gas_slot_read_fn read; /* NULL запрещает чтение; callback получает полный 16-битный адрес слота. */
pcan_gas_slot_write_fn write; /* NULL запрещает запись; callback не должен менять соседние слоты. */
} pcan_gas_slot_port_t; /* Размер существующих структур pcan_gas не изменяется. */
PCAN_ABI_API int32_t pcan_gas_slot_address(unsigned mode, unsigned local); /* Возвращает (mode<<8)|local либо -1 для mode>31 или local>66. */
PCAN_ABI_API uint32_t pcan_gas_slot_id(unsigned device_type, unsigned device_id, unsigned address, unsigned route); /* Формирует MsgType=0x4 для любого узла и адреса 0…65535 без сужения неверных входов. */
PCAN_ABI_API uint32_t pcan_gas_slot_request_id(unsigned mode, unsigned local, unsigned route); /* Формирует Extended ID PERIPH с Priority=1 и MsgType=0x4; ноль означает ошибку. */
PCAN_ABI_API int pcan_gas_slot_encode(const uint16_t *words, unsigned count, uint_least8_t *data); /* Допускает count=0 либо четыре wire-слова с непустой маской в Word0; длина измеряется октетами. */
PCAN_ABI_API int pcan_gas_slot_decode_words(uint32_t id, unsigned flags, const uint_least8_t *data, unsigned dlc, uint16_t *words); /* Проверяет общий слотный кадр любого узла; возвращает 0/4 либо -1 без изменения выхода при отказе. */
PCAN_ABI_API int pcan_gas_slot_decode(uint32_t id, unsigned flags, const uint_least8_t *data, unsigned dlc, unsigned *mode, unsigned *local, uint16_t *words); /* Проверяет узел, слот и октеты; возвращает 0/4 либо -1 без изменения выходов. */
PCAN_ABI_API int pcan_gas_slot_native(unsigned local, unsigned word, unsigned write, uint16_t *address); /* Переводит Word1…Word3 в родной адрес PERIPH; Word0 является маской и не адресует регистр. */
PCAN_ABI_API int pcan_gas_slot_handle_address(unsigned device_type, unsigned device_id, const pcan_gas_slot_port_t *port, const pcan_gas_slot_frame_t *request, pcan_gas_slot_frame_t *response); /* Обслуживает масочную запись и чтение 0x4 для любого узла; не вызывает Modbus или GAS 0x3. */
PCAN_ABI_API int pcan_gas_slot_handle(unsigned mode, const pcan_gas_slot_port_t *port, const pcan_gas_slot_frame_t *request, pcan_gas_slot_frame_t *response); /* Возвращает 1 для ответа, 0 после записи, -1 при отказе; не вызывает legacy fallback. */
#ifdef __cplusplus /* Закрываем C ABI только при включении из C++. */
} /* Конец объявлений с C-соглашением о связывании. */
#endif /* Общие защитные символы не зависят от языка порта. */
#endif /* Завершаем защиту единственного интерфейса слотного профиля GAS. */