Files
templates/c/firmware-info/PORTING.md

8.4 KiB
Raw Blame History

Портирование firmware-info

Назначение и границы

Это C-библиотека описания работающего образа: SemVer, дата/время компиляции, 8 символов build ID и сериализация контракта v1. Она не обращается к сети, не читает версию из сервера и не записывает Flash. HAL, RTOS, UART и CAN ядру не нужны. Отправку результата выполняет приложение.

Для размещения .hex/.bin в каталоге SETGUI уже существуют setprotocol.firmware_publish и tools/firmware-publish. Связь компонентов и перенос публикации описаны в tools/firmware-publish/PORTING.md.

1. Файлы и конфигурация

Пример ниже предполагает lib/templates внутри нового проекта:

project/
  inc/firmware_info_config.h
  generated/firmware_build_id.h       # создаётся до сборки
  lib/templates/c/firmware-info/
  src/

Добавьте в сборку оба файла:

lib/templates/c/firmware-info/src/firmware_info.c
lib/templates/c/firmware-info/src/firmware_info_port.c

В include path добавьте inc, generated и lib/templates/c/firmware-info/include. Встроенный CMakeLists.txt собирает только ядро и host-тест; firmware_info_port.c и каталоги конфигурации нужно добавлять к целевому firmware target самостоятельно.

Скопируйте ports/<mcu>/firmware_info_config.template.h как inc/firmware_info_config.h. Есть варианты STM32F1/F4/G4 и К1921ВК028; они не содержат регистров МК. Для другого МК с обычными 8-битными байтами достаточно такого же config:

#ifndef FIRMWARE_INFO_CONFIG_H
#define FIRMWARE_INFO_CONFIG_H
#define FIRMWARE_VERSION_MAJOR 1U
#define FIRMWARE_VERSION_MINOR 2U
#define FIRMWARE_VERSION_PATCH 3U
#include "firmware_build_id.h"
#endif

Обязательный include в этом примере позволяет обнаружить пропущенный pre-build. В готовых шаблонах include опциональный через __has_include; если заголовок не подключён, порт использует LOCALDEV. Для компилятора без __has_include используйте явный include. Можно связать три версии с существующими макросами проекта, как это сделано в KONOR_ds18b20/inc/firmware_info_config.h.

2. Build ID

Из корня нового проекта перед компиляцией запустите:

powershell -NoProfile -ExecutionPolicy Bypass -File "lib/templates/c/firmware-info/tools/make_build_id.ps1" -Repository "." -Output "generated/firmware_build_id.h"

Указывайте -Repository и -Output явно: расположение сабмодуля и рабочий каталог IDE различаются между проектами. -Repository должен указывать на исходники прошивки, а не на репозиторий templates. Для Keil из каталога mdk соответственно используйте ..\lib\templates\..., -Repository ".." и -Output ".\Generated\firmware_build_id.h".

При доступном Git чистый checkout получает 8 знаков commit, изменения tracked файлов — 7 знаков и +. Если commit определить нельзя, используется NOGIT000. Новые untracked-файлы текущий генератор при определении dirty не учитывает. Дата/время берутся из __DATE__/__TIME__ при компиляции firmware_info_port.c; для выпуска выполняйте полный Rebuild, чтобы не оставить старый объектный файл.

3. Обработчик запроса версии

Пример функции подготовки полезной нагрузки, вызываемой вашим обработчиком:

#include "firmware_info_port.h"

firmware_info_status_t app_make_firmware_info(uint8_t *payload, size_t capacity)
{
    firmware_info_t info;
    firmware_info_status_t status = firmware_info_port_describe(&info);
    if (status != FIRMWARE_INFO_OK) return status;
    return firmware_info_to_le_bytes(&info, payload, capacity);
}

При успехе передайте ровно FIRMWARE_INFO_PAYLOAD_SIZE (24) байта в собственный транспорт. При ошибке верните ошибку протокола, а не содержимое буфера. Не отправляйте sizeof(firmware_info_t): структура не является wire format.

В KONOR обработчик app_send_firmware_info() отвечает на PROTO_MSG_FIRMWARE_INFO = 0x03, сохраняя sequence запроса. Старый 32-байтовый DEVICE_INFO остаётся отдельным сообщением. Для нового протокола сначала согласуйте команду с клиентом: подключение библиотеки само по себе не добавит декодер и отображение версии в GUI.

Для Modbus вызовите firmware_info_to_registers() с массивом из 12 uint16_t и разместите его в выбранной карте регистров. Адреса и Modbus-порядок байтов обеспечивает ваш Modbus-стек; LE-буфер в Modbus напрямую не копируйте.

4. Контракт v1

Индекс слова Содержимое
0 Версия контракта: 1
1, 2, 3 major, minor, patch
4 Год
5 (month << 8) | day
6 (hour << 8) | minute
7 Секунды
811 По два ASCII-символа build ID: первый в старшем байте слова

В LE-представлении младший байт каждого слова идёт первым. Например, build ID ab в начале строки даёт слово 0x6162, но байты 62 61; декодируйте сначала слово, затем символы из старшего/младшего байта. NUL-терминатор не передаётся.

Текущая проверка допускает major/minor до 255 и patch до 999. Если в каталоге используется (major << 16) | (minor << 8) | patch, ограничьте все три части до 255, иначе значения пересекутся. Версия каталога автоматически из C-config не извлекается.

Для C2000 с 16-битным char нельзя считать готовым байтовый порт: отдельно проверьте наличие uint8_t и представление октетов в транспорте. Публикация TMS SCI8-файла с ПК поддерживается независимо от переноса этой C-библиотеки.

5. Проверка переноса

  1. Соберите host-тест из tests/test_firmware_info.c вместе с ядром либо используйте CMake/CTest. Он проверяет дату, регистры и порядок байтов build ID.
  2. Соберите целевую прошивку с обоими .c и сгенерированным заголовком.
  3. Запросите версию у устройства: сравните SemVer, build ID, время и 24-байтовый ответ с конкретной сборкой. Проверьте, что прежний DEVICE_INFO не изменился.
  4. Подключите выпуск по инструкции публикатора; сравните версию в config и firmware-release.cmd перед Rebuild и --preflight.