Объедини реализацию DEIF в C99-ядре, чтобы Python и Android использовали один кодек и общие эталонные кадры. Добавь две GAS-проекции единой карты STM Invertor и аппаратные порты эмулятора и загрузчика для платы HOPE STM32G474VET6. Проверки: сборка MSVC Debug, 24 теста CTest, 30 тестов Python и 29 дополнительных проверок, синтаксис 16 файлов Python.
33 lines
6.0 KiB
C
33 lines
6.0 KiB
C
#ifndef SET_INVERTOR_GAS_H /* Общий C-контракт связывает два вида GAS с одним источником значений инвертора. */
|
|
#define SET_INVERTOR_GAS_H /* Защищаем объявления от повторного подключения прошивкой и host-клиентом. */
|
|
#include "set_invertor_profile.h" /* Число слотов и пара DeviceType/DeviceID определены единственным профилем Templates. */
|
|
#include "pcan_gas.h" /* Тип 0x3 использует существующую карту регистров и общий разбор Classic CAN. */
|
|
#include "pcan_gas_slot.h" /* Тип 0x4 сохраняет маску Word0 и три выбранных значения. */
|
|
#ifdef __cplusplus /* Клиенты C++ должны обращаться к обычным C-символам общей библиотеки. */
|
|
extern "C" { /* Открываем совместимую область связывания без изменения wire-формата. */
|
|
#endif /* Последующие объявления также доступны компилятору C99. */
|
|
#define SET_INVERTOR_GAS_REGISTER_FIRST 0U /* В отдельном узле 7/E регистровая карта начинается с нуля независимо от PERIPH. */
|
|
#define SET_INVERTOR_GAS_SLOT_FIRST 0U /* Выделенные 250 слотов отдельного инвертора имеют адреса 0x0000…0x00F9. */
|
|
#define SET_INVERTOR_GAS_REGISTER_COUNT SET_INVERTOR_GAS_WORD_COUNT /* 750 регистров 0x0000…0x02ED хранят те же значения, что слоты типа 0x4. */
|
|
#if SET_INVERTOR_GAS_WORDS_PER_SLOT != PCAN_GAS_SLOT_DATA_WORDS /* Геометрия профиля обязана совпадать с актуальным масочным кодеком Templates. */
|
|
#error "Invertor GAS profile and slot codec disagree" /* При несовместимом изменении профиля прекращаем сборку вместо тихого смещения регистров. */
|
|
#endif /* Проверка действует одинаково для host и STM32. */
|
|
typedef int (*set_invertor_gas_read_fn)(void *context, uint16_t address, uint16_t *value); /* Ноль подтверждает одно достоверное значение; ошибка не подменяется успешным нулём. */
|
|
typedef int (*set_invertor_gas_write_fn)(void *context, const uint16_t *addresses, const uint16_t *values, unsigned count); /* Provider проверяет все 1…4 адреса, права и значения до единственного согласованного применения. */
|
|
typedef struct { /* Приложение владеет данными и отвечает за блокировку общего снимка на время одного вызова обработчика. */
|
|
void *context; /* Контекст связывает регистровый и слотный доступ с одним состоянием изделия. */
|
|
set_invertor_gas_read_fn read; /* NULL отключает чтение, сохраняя возможность явно разрешённой записи. */
|
|
set_invertor_gas_write_fn write; /* NULL полностью запрещает запись, в том числе команды через регистры. */
|
|
} set_invertor_gas_port_t; /* Структура не требует выделения массива из всех 750 слов или аппаратных заголовков. */
|
|
PCAN_ABI_API int32_t set_invertor_gas_register(unsigned slot, unsigned word); /* Возвращает регистр для Word1…Word3 либо -1 для маски и координат за пределами 250 слотов. */
|
|
PCAN_ABI_API int set_invertor_gas_coordinate(unsigned address, uint16_t *slot, uint16_t *word); /* Обратное отображение не изменяет выходы при ошибке; Word0 никогда не является значением. */
|
|
PCAN_ABI_API uint32_t set_invertor_gas_request_id(unsigned message_type, unsigned address, unsigned route); /* Общий кодек строит только MsgType 0x3/0x4 узла 7/E с адресами внутри соответствующей карты. */
|
|
PCAN_ABI_API int set_invertor_gas_handle(const set_invertor_gas_port_t *port, const pcan_frame_t *request, pcan_frame_t *response); /* Возвращает 1 для готового ответа, 0 для применённой записи, -1 при отказе; автоматического fallback нет. */
|
|
PCAN_ABI_API unsigned set_invertor_gas_limit(unsigned message_type); /* Возвращает 750 регистров для 0x3, 250 слотов для 0x4 либо ноль для неизвестного типа. */
|
|
PCAN_ABI_API int set_invertor_gas_build(unsigned message_type, unsigned address, const uint16_t *words, unsigned count, uint32_t *identifier, uint8_t data[8]); /* Тонкие языковые порты получают готовые ID и октеты: count=0 означает чтение, результат — DLC либо -1. */
|
|
PCAN_ABI_API int set_invertor_gas_decode(uint32_t identifier, unsigned flags, const uint8_t *data, unsigned length, unsigned metadata[2], uint16_t words[4]); /* Проверяет ответ 7/E; metadata содержит тип и адрес, результат — число 16-битных wire-слов либо -1. */
|
|
#ifdef __cplusplus /* Закрываем область C ABI только при использовании C++-компилятора. */
|
|
} /* Завершаем публичные объявления общей библиотеки. */
|
|
#endif /* Условие не меняет смысл C99-интерфейса. */
|
|
#endif /* Конец контракта двух представлений одних данных инвертора. */
|