Документация Engee

Отладка таргета

Страница в процессе разработки.

Общий механизм загрузки пакета поддержки описан в статье Пользовательские пакеты поддержки Engee.Интеграции. В этой статье рассмотрены особенности, которые важны именно при разработке таргета.

Загрузка пользовательского таргета

Пользовательский таргет реализован как пакет поддержки. Это означает, что он добавляется в Engee.Интеграции и синхронизируется c Engee. После чего все необходимые компоненты должны быть доступны через пакет поддержки, .nglib библиотеку, настройки блока EDM-Target и понятные инструкции по установке внешних зависимостей. Пользователь не должен самостоятельно искать или изменять файлы в репозитории пакета поддержки.

Julia-код пакета поддержки — это интерфейсный слой. Он делает классы и методы пакета поддержки доступными из блоков и скриптов Engee. Python-код — это реализация: именно в нем находятся BaseTarget-класс, генерация проекта, сборка, загрузка, запуск, работа с XCP, драйверами и внешними утилитами.

Из этого следуют практические правила:

  • если изменилось тело Python-метода, но имя метода, аргументы и типы возвращаемых значений не изменились, обычно достаточно перезапустить клиентскую программу Engee.Интеграции;

  • если добавлен новый публичный метод, изменена сигнатура, переименован класс или изменилась структура пакета, необходимо снова выполнить syncExtensions(), как описано в разделе Синхронизация и использование пакета поддержки в Engee;

  • если изменилась пользовательская библиотека .nglib, нужно обновить библиотеку в сессии Engee согласно механизму для пользовательских библиотек;

  • если изменилась сама модель или параметры блока EDM-Target, проект таргета необходимо генерировать заново из модели.

Логи и ошибки

Для пользовательских сообщений используйте встроенную систему логирования, как описано в разделе Отладка пакетов поддержки. Сообщения должны объяснять действия пользователя: проверка порта, установка тулчейна, выбор корректного режима выполнения, указание пути к компилятору, подключение устройства.

Ошибки таргета рекомендуется представлять в виде исключений с коротким сообщением, которое должно содержать причину возникновения и рекомендацию по устранению; при этом не следует рассчитывать на то, что пользователь имеет доступ к отчету о вызовах или исходному коду пакета поддержки, поэтому сообщение должно быть самодостаточным и не требовать дополнительного анализа.

Пример сообщения об ошибке

if model_settings.is_ext_mode:
    raise RuntimeError(
        "This target supports only independent execution. "
        "Disable interactive execution in Target Hardware settings."
    )

Отладка без повторной генерации модели

Во время разработки таргета часто требуется многократно отлаживать generate_executable_code. Генерация Си-кода из интерфейса Engee может занимать время, поэтому удобно один раз сохранить входные данные метода в JSON-файлы, а затем запускать Python-код локально на этих данных.

Данный механизм предназначен исключительно для разработки и отладки таргета; он не должен входить в состав пользовательского сценария работы и не должен являться обязательным компонентом поставляемого пакета поддержки.

Пример сохранения входных данных generate_executable_code

import json
from pathlib import Path
from typing import Any


def _to_jsonable(value: Any) -> Any:
    if hasattr(value, "model_dump"):
        return value.model_dump(mode="json", by_alias=True)
    if isinstance(value, dict):
        return {str(k): _to_jsonable(v) for k, v in value.items()}
    if isinstance(value, list):
        return [_to_jsonable(v) for v in value]
    return value


def dump_codegen_inputs(model, model_settings, model_code) -> None:
    dump_dir = Path("/tmp/mytarget-codegen-dump")
    dump_dir.mkdir(parents=True, exist_ok=True)

    payload = {
        "model": _to_jsonable(model),
        "model_settings": _to_jsonable(model_settings),
        "model_code": _to_jsonable(model_code),
    }

    for name, data in payload.items():
        path = dump_dir / f"{name}.json"
        path.write_text(
            json.dumps(data, ensure_ascii=False, indent=2),
            encoding="utf-8",
        )

Такой вызов можно временно разместить в начале generate_executable_code:

def generate_executable_code(self, model, model_settings, model_code):
    dump_codegen_inputs(model, model_settings, model_code)
    ...

После этого можно воспроизводить генерацию проекта без повторного запуска кодогенерации из интерфейса Engee.

Пример локального запуска по сохраненным JSON

from pathlib import Path

from targets.base_models import EngeeModel, ModelCode
from targets.contract_compat import ModelSettings

from targets.my_target.my_target import MyTarget


dump_dir = Path("/tmp/mytarget-codegen-dump")

model = EngeeModel.model_validate_json(
    (dump_dir / "model.json").read_text(encoding="utf-8")
)
model_settings = ModelSettings.model_validate_json(
    (dump_dir / "model_settings.json").read_text(encoding="utf-8")
)
model_code = ModelCode.model_validate_json(
    (dump_dir / "model_code.json").read_text(encoding="utf-8")
)

target = MyTarget()
target.generate_executable_code(model, model_settings, model_code)
target.compile_model(model)

Если нужно отлаживать только шаблоны и копирование файлов, достаточно запускать generate_executable_code. Если нужно проверить интеграцию с тулчейном, добавьте compile_model. upload_model и start_model лучше запускать отдельно, потому что они уже зависят от подключенного оборудования.

Проверка перед передачей таргета

Проверка корректности работы таргета выполняется по следующему сценарию:

  1. Пакет поддержки загружается через Engee.Интеграции.

  2. После syncExtensions() таргет доступен в скриптах и блоках Engee.

  3. Блок EDM-Target отображается в пользовательской библиотеке и сохраняет параметры маски.

  4. generate_executable_code создает проект без ручных правок.

  5. compile_model собирает проект с нуля.

  6. upload_model загружает артефакт на устройство или в среду выполнения.

  7. start_model запускает модель и возвращает понятный статус.

  8. Неподдерживаемый режим выполнения завершается понятной ошибкой.

  9. Демо-модель проходит полный пользовательский сценарий.

Для интерактивного режима дополнительно проверьте:

  1. Запуск команды измененияпотока данных.

  2. Выполнение команды изменения хотя бы одного параметра.

  3. Корректное освобождение ресурсов в stop_model.

Информация в README таргета

README таргета должен быть ориентирован на пользователя, а не содержать внутреннее описание репозитория. Рекомендуем указать:

  • поддерживаемую платформу и режимы выполнения;

  • как установить внешние зависимости: тулчейн, программатор, драйверы ОС;

  • как загрузить пакет поддержки и когда выполнять синхронизацию syncExtensions();

  • где находится .nglib библиотека блоков;

  • какие параметры есть у блока EDM-Target;

  • как запустить демо-модель;

  • типовые ошибки подключения, сборки и загрузки.