# Правила общего кроссплатформенного кода Этот репозиторий — единственный источник общих алгоритмов для `GUI_Android`, `SETGUI`, прошивок и будущих GUI. Копирование одной реализации между Kotlin, Python, C# или другим языком запрещено. ## 1. Граница C-ядра и порта В `c/set-protocol` на C99 обязательно размещаются: - форматы кадров и идентификаторов, CRC/checksum, endian-преобразования; - построение команд, разбор и проверка ответов; - автоматы обмена, сегментация, повтор, таймаутные состояния без системных часов; - общие вычисления, таблицы и каталоги, влияющие на поведение протокола; - проверка образов прошивки и других бинарных форматов. Порт на языке GUI содержит только: - вызовы C через стабильный ABI (`ctypes`, JNI, P/Invoke, Swift FFI и т. п.); - преобразование C-структур в модели языка без повторения алгоритма; - работу с USB, COM, Bluetooth, SocketCAN и API операционной системы; - жизненный цикл, потоки, разрешения, хранение настроек и UI; - локализованный текст и чисто визуальные преобразования. Порт не вычисляет CRC, не собирает wire-пакет и не разбирает его поля заново. Если для функции C-ядро недоступно, приложение сообщает об ошибке сборки или загрузки. Алгоритмический fallback на языке GUI запрещён: он снова создаёт две версии протокола. ## 2. Разделение контроллеров Профили контроллеров нельзя сливать по совпадению названия транспорта: - **ПМ67 / TMS320F2812** — основной контроллер, собственные RS и CAN; - **ПМ35 / TMS320F28335 periph** — отдельный контроллер и отдельный CAN для настроечного терминала, а также собственный прямой RS232/485-протокол. Выбор профиля выполняется в GUI, но выбранный профиль вызывает свой отдельный модуль C-ядра. Наличие одной CAN-линии не даёт права удалить или подменить другую. ## 3. Порядок изменения протокола 1. Добавить или изменить публичный заголовок и реализацию в `c/set-protocol/include` и `c/set-protocol/src`. 2. Зафиксировать эталонные байты и ошибочные случаи в C-тесте. 3. При необходимости расширить `pcan_abi.h`, сохраняя бинарную совместимость. 4. Добавить тонкие порты в `ports/` и `python/`; в них не должно быть второго кодека. 5. Одними и теми же векторами проверить C, Python и Android/JVM. 6. Собрать SETGUI и Android с одним commit submodule `templates`. Изменение только в одном GUI считается незавершённым. Сначала меняется `templates`, затем оба потребителя обновляют ссылку submodule на проверенный commit. ## 4. Требования к C-ядру - C99, без зависимости от GUI и конкретной ОС. - Буферы и их размеры передаются явно; владение памятью остаётся у вызывающего. - Для MCU основная логика не требует heap, исключений или файловой системы. - Endian и размеры целых задаются через `stdint.h`, структуры wire-формата не передаются через ABI без явного стабильного представления. - Экспорт shared library идёт через `PCAN_ABI_API`; существующие символы не меняют смысл и сигнатуру. - Ошибки возвращаются детерминированным кодом и тестируются наряду с успехом. ## 5. Проверка на ревью Изменение нельзя принимать, если ответ «да» хотя бы на один вопрос: - появился одинаковый CRC/parser/builder в двух языках; - UI знает byte offset, endian или служебный байт wire-протокола; - Python и Kotlin содержат одинаковую таблицу команд, влияющую на обмен; - добавлен тихий fallback, поведение которого отличается от C; - обновлён один GUI без обновления и теста `templates`; - ПМ67 и ПМ35 сведены к одному соединению или одному состоянию контроллера. Текущее состояние и очередь переноса перечислены в [`doc/CROSS_PLATFORM_AUDIT.md`](doc/CROSS_PLATFORM_AUDIT.md).