Обеспечь единый процесс обновления для STM32F103/F407/G474 и TMS320F2812/F28335: discovery, служебные ответы, BUSY, тайм-аут сессии и подтверждение приложения. Добавь самостоятельные проекты CCS, аппаратные хранилища и Python-клиент. Совместимость: структуры конфигурации и порта расширены, поэтому потребители должны пересобраться и обнулить новые поля. Для C28x callbacks используют pcan_boot_byte_t; периодический pcan_boot_poll обслуживает discovery и настроенный тайм-аут.
protocan (Python)
Хостовая сторона протоколов: разбор сообщений ProtoCAN, транспортный кадр моста CAN↔RS485 и кодеки каталога общего адресного пространства.
Только stdlib, Python 3.9+. Ни Qt, ни pyserial: модули не открывают порт и не
знают, откуда пришли байты, — им передают bytes. Поэтому они проверяются
обычными host-тестами и одинаково работают в GUI, в скрипте и в CI.
Состав
| Модуль | Что делает | Зеркало на C |
|---|---|---|
protocan.py |
разбор 29-битного идентификатора и тела всех типов сообщений в человекочитаемый вид | pcan_id.c |
transport.py |
кадр AA 55 … CRC16, потоковый разборщик с ресинхронизацией, CRC-16/CCITT-FALSE |
pcan_frame.c |
protocol.py |
кадр A5 5A протокола SETGUI: сборка, разбор, CRC32 |
gui_frame.c |
gas_catalog.py |
каталог регистров с именами и подписка на поток значений | gui_catalog.c |
Зависимость внутри пакета одна: gas_catalog использует protocol.
Остальные модули независимы.
Кодировщики C и Python дают побайтово одинаковый результат — это зафиксировано
эталонами в c/set-protocol/tests/test_transport.c.
Быстрый старт
from protocan import protocan, transport
parser = transport.FrameParser()
for frame in parser.feed(port.read(256)): # bytes из любого источника
print(protocan.decode(frame.can_id, frame.data).summary)
port.write(transport.build_frame(0x18FF0102, b"\x01\x02").encode())
Каталог регистров:
from protocan.gas_catalog import ObjectEntry, ObjectType, encode_entry, decode_entry
entry = ObjectEntry(address=0x0100, type=ObjectType.U16, flags=0,
scale_pow10=-1, unit=0, name="Температура")
raw = encode_entry(entry)
assert decode_entry(raw) == entry
Границы
Разбор отделён от ввода-вывода намеренно: порт, таймауты и переподключение — дело вызывающего кода. Байты внутрь, объекты наружу.
Проверено в проектах
SETGUI (вкладки «Шина CAN» и «Адресное пространство»), CAN_to_RS485.
Там пакет лежит внутри gui_desktop/core, здесь — источник истины.
GAS: регистры 0x3 и слоты 0x4
Адресация GAS: 0x3 — отдельные 16-битные регистры 0…65535, запись 1…4 слов. 0x4 — слот с Word0-маской и тремя значениями; PERIPH сохраняет 200 слов в 67 слотах 0xMM00…0xMM42. Формат определяется MsgType, без настройки профиля.