Редакция: 2026-10-14 Автор: Андрей Мищук 12 мин чтения

Программно-аппаратный комплекс «Архимед»

Техническое описание и руководство разработчика: платформа Zynq-7020, среда исполнения Rust + Forth + AI и измерительный тракт AD7401A

Программная архитектура (Rust + AI + Forth)

Программный комплекс функционирует в среде Embedded Linux на процессорной системе (PS) Zynq-7020 (ARM Cortex-A9). Архитектура построена по трёхуровневой концепции «Rust + AI + Forth», где каждый слой строго изолирован и решает свой круг задач.

Rust (системный фундамент) — владение ресурсами, типобезопасность, сеть, потоки и аппаратный I/O. Forth (публичный предметный API) — компактный расширяемый язык для комбинирования измерительных процедур и сценариев. AI (оркестратор) — интерпретация намерений оператора, генерация Forth-кода под задачу и диалог в роли виртуального физика-исследователя.

                 +--------------------------------------------------------+
                 |                     ВНЕШНИЕ КЛИЕНТЫ                    |
                 |  Терминал  |  Web UI (:8081)  |  MQTT  |  MCP / A2A    |
                 +-----+--------------+--------------+---------+----------+
                       |              |              |         |
                       v              v              v         v
+-----------------------------------------------------------------------------------+
|  PS (ARM Linux)             ИСТОЧНИКИ ВВОДА-ВЫВОДА                                |
|  [console]        [web]         [mqtt]        [mcp (:8090)]    [a2a (:8091)]     |
|       \             |              |                /               /             |
|        +------------+--------------+---------------+---------------+              |
|                                    |                                              |
|                                    v                                              |
|  +-----------------------------------------------------------------------------+  |
|  |                 ГЛАВНЫЙ ЦИКЛ ОБРАБОТКИ (word_service)                       |  |
|  |   Неблокирующий опрос: AI-воркер -> MCP -> Очереди ввода -> Таймеры        |  |
|  |   (при отсутствии событий: sleep 10 мс; выполнение транзакций целиком)      |  |
|  +-------------------------------------+---------------------------------------+  |
|                                        |                                          |
|                                        v                                          |
|  +-----------------------------------------------------------------------------+  |
|  |                     ИСПОЛНИТЕЛЬНОЕ ЯДРО FORTH (на Rust)                     |  |
|  |   - Стек данных / Стек возвратов            - Два раздельных аллокатора     |  |
|  |   - Центральное состояние Context           - Строгий стек-эффект примитивов|  |
|  +-------------------+-----------------------------------+---------------------+  |
|                      |                                   |                        |
|                      v                                   v                        |
|  +-------------------------------------+   +-----------------------------------+  |
|  |          AI-СЛОЙ (ИСТОЧНИК)         |   |          ПРИБОРНЫЙ СЛОЙ           |  |
|  |  - DeepSeek / Ollama                |   |  - odp (ODP6033 SCPI/TCP)         |  |
|  |  - Роли (ai/roles/ — Архимед)       |   |  - xdm (XDM3051 SCPI/TCP)         |  |
|  |  - Генерация Forth-команд           |   |  - spi (MCP42010 порогов)         |  |
|  |  - Ответы оператору                 |   |  - pulse / adc (MMIO /dev/mem)    |  |
|  |                                     |   |  - sqlite (журнал), timer, thread |  |
|  +-------------------------------------+   +-----------------+-----------------+  |
+--------------------------------------------------------------|--------------------+
                                                               | MMIO / SPI / TCP
                                                               v
                                    [ Аппаратная часть: PL Zynq-7020 + Внешние приборы ]

Архитектурное правило разделения ответственности

  • В Rust: безопасность памяти, строгие границы I/O, время жизни дескрипторов, сетевые стеки, потоки и единственные изолированные unsafe-блоки прямого маппинга физической памяти (/dev/mem).
  • В Forth: бизнес-логика опытов, временные диаграммы, композиция атомарных операций, алгоритмы автоциклов и предметная интерпретация битовых полей.

Исполнительное ядро Forth

Ядро интерпретатора разработано с нуля на языке Rust без внешних C-зависимостей.

Компоненты ядра:

  • Словарь слов (Dictionary) и компилятор в шитый/байт-код.
  • Два изолированных аллокатора: один под исполняемые примитивы, второй — под динамически скомпилированный пользовательский код.
  • Стек данных (Data Stack) и стек возвратов (Return Stack).
  • Контекст (Context): центральная структура состояния рантайма — указатели на стеки, текущий словарь, зарегистрированные источники ввода-вывода, дескрипторы приборов, таймеры и дескриптор базы SQLite.
  • Регистрация примитивов (init_forth): все базовые операции регистрируются на этапе запуска; для каждого слова декларативно задаётся и контролируется стек-эффект (например, ( device channel -- value )).
  • Цикл диспетчеризации (word_service): главный планировщик выполняет неблокирующий опрос очередей по строгому приоритету — результаты AI-воркера, транзакции MCP, входные очереди сетевых/терминальных источников, сработавшие таймеры. Если очередь пуста, цикл засыпает на 10 мс; каждая порция данных выполняется транзакционно.

Транспорты и источники ввода-вывода

Вся коммуникация абстрагирована через независимые источники (Sources): каждый источник изолирован, имеет собственные очереди, буфер транзакции, отдельный стек и контекст. Команда use переключает текущий активный вывод.

ИсточникТранспорт / ПортНазначение
consolestdin / stdoutЛокальная отладка и управление через последовательный порт / SSH
webHTTP / WebSocket (:8081)Веб-терминал для интерактивного управления через браузер
MQTTTCP (Брокер)Телеметрия, интеграция со SCADA и публикация статусов
MCPHTTP (:8090) + stdioModel Context Protocol — интерфейс для внешних AI-агентов
A2A-шлюзHTTP (:8091)Agent-to-Agent шлюз для приёма задач от распределённых агентов

Приборный слой (Device Abstraction Layer)

Приборы не являются источниками текста — они регистрируются как устройства и управляются через числовые дескрипторы, передаваемые через стек Forth.

А. Сетевые лабораторные приборы (SCPI over TCP)

  • odp — управление 3-канальным источником питания OWON ODP6033 (напряжения, токовые защиты, вкл/выкл каналов).
  • xdm — прецизионные показания мультиметра OWON XDM3051 (вольтметр, амперметр, 4-проводная схема).

Б. Периферия Linux и шины

  • spi — драйвер шины /dev/spidev1.0, протокол потенциометра MCP42010 (пороги окна компаратора TLV3502).
  • sqlite — встроенная СУБД для логирования временных серий и калибровок.
  • time, timer, thread — асинхронные таймеры, задержки и фоновые потоки Rust.

В. Аппаратные блоки FPGA (Direct MMIO via /dev/mem)

  • pulse + pulse_devmem — драйвер 8-канального генератора timing_controller (база 0x43C0_0000).
  • adc + adc_devmem — драйвер 4-канального PDM-демодулятора АЦП AD7401A (база 0x43C1_0000).

AI-слой и виртуальный ассистент

  • Провайдеры: локальные квантованные модели через Ollama либо удалённый API (DeepSeek).
  • Принцип исполнения: модель отвечает на естественном языке, а для взаимодействия со стендом генерирует валидные блоки кода на Forth, которые прозрачно направляются в очередь интерпретатора.
  • Ролевая модель: промпты хранятся в ai/roles/. Базовая роль — «Архимед», инженер-физик лаборатории нестационарных электромагнитных процессов, знающий ограничения стенда: напряжения до 60 В, предельные токи 200 мА.

Инициализация и последовательность загрузки (forth.frt)

Запуск завершается передачей управления стартовому Forth-скрипту forth.frt:

          [Старт бинарного файла Rust]
                       │
                       ▼
       Инициализация словаря и примитивов (init_forth)
                       │
                       ▼
             Запуск скрипта forth.frt:
               ├── 1. Создание устройств (adc0, spi-u17, pulse-board, pulse-board-2, odp, xdm)
               ├── 2. Инициализация источников (console, web, mqtt, mcp, a2a)
               ├── 3. Загрузка калибровок и запуск аппаратного Self-Test
               └── 4. Вызов слова `service`
                       │
                       ▼
         Вход в бесконечный неблокирующий цикл word_service
         (обработка очередей событий и сетевых портов)

С этого момента комплекс готов принимать управляющие воздействия через терминал, веб-интерфейс, по протоколу MCP или в диалоге с AI-ассистентом.

Аппаратная архитектура

Комплекс построен на модуле AC7020C с СнК AMD/Xilinx Zynq-7020 (два ядра ARM Cortex-A9 + программируемая логика Artix-7).

+-----------------------------------------------------------------------------------+
|                                  SoC Zynq-7020                                    |
|  +--------------------------------+   +----------------------------------------+  |
|  |     PS (Processing System)     |   |         PL (Programmable Logic)        |  |
|  |                                |   |                                        |  |
|  |  [Embedded Linux (ARMv7)]      |   |  [Timing Controller / Секвенсор]       |  |
|  |   - Forth Runtime / Rust       |   |   - База: 0x43C0_0000                  |  |
|  |   - SPI (/dev/spidev1.0)       |   |   - Ch0: Заряд (первичная цепь)        |  |
|  |                                |   |   - Ch1: Разряд (вторичная цепь)       |  |
|  +----------------+---------------+   +-------------------+--------------------+  |
|                   | AXI4-Lite                             |                       |
|                   +---------------------------------------+                       |
|                   | AXI4-Lite                             | Биты компаратора      |
|                   v                                       v (STATUS.5)            |
|  +--------------------------------+   +----------------------------------------+  |
|  | [Измеритель тока (AD7401A)]    |   | [Оконный компаратор (TLV3502)]         |  |
|  |  - База: 0x43C1_0000           |   |  - Аппаратный вход PL                  |  |
|  |  - 4 канала (шаг 0x40)         |   |  - Пороги: MCP42010 по SPI             |  |
|  |  - 20 МГц PDM, OSR=256         |   |    (диапазон 35...55 В)                |  |
|  +--------------------------------+   +----------------------------------------+  |
+-----------------------------------------------------------------------------------+

PS: запускает Linux со средой исполнения (Forth/Rust), координирует эксперимент, конфигурирует MMIO-периферию и внешние ЦАП/потенциометры по SPI. PL: аппаратно-детерминированный тайминг импульсов (10 нс), защита секвенсора по порогам компаратора и цифровой тракт демодуляции PDM-потока АЦП.

Импульсный генератор и секвенсор (timing_controller)

Блок формирует управляющие последовательности импульсов на силовых ключах с аппаратным шагом 10 нс (100 МГц).

  • Базовый адрес: 0x43C0_0000; адресное пространство 0x200 байт (до 8 каналов с шагом 0x24).
  • Канал 0 (pulse-board) — линия заряда (ключ первичной цепи).
  • Канал 1 (pulse-board-2) — линия разряда (ключ вторичной цепи).

Карта регистров канала

ИмяСмещениеДоступНазначение
STATUS+0x00ROТекущий статус канала
CTRL+0x04RWУправление режимами и пуском
PRE_DELAY+0x08RWПредзадержка перед серией (в тактах 10 нс)
PULSE+0x0CRWДлительность импульса. Запрещено 0
PAUSE+0x10RWДлительность паузы (в тактах)
BURST+0x14RWИмпульсов в пачке. Запрещено 0
PST_DELAY+0x18RWПостзадержка после пачки (в тактах)
CYCLE+0x1CRWЧисло пачек/циклов генерации
BURST_DONE+0x20ROНакопительный счётчик отработанных импульсов

Диапазон параметров: 0 … 4 294 967 295. Конфигурации с PULSE = 0 или BURST = 0 отбрасываются ядром и вызывают флаг ошибки.

Биты CTRL (+0x04)

БитИмяНазначение
0RUN1 — запуск; 0 — останов
1RESETАппаратный сброс автомата состояний
2MODE0 — ONE-SHOT; 1 — CONTINUOUS
3INVERTИнверсия полярности импульса
4SEQUENCE1 — включение секвенсора (останов по порогу компаратора)
5..31—Зарезервированы

Биты STATUS (+0x00)

БитИмяНазначение
0runningГенератор активен
1running_dupДублирующий флаг активности
2doneЗавершение последовательности импульсов
3bResetЯдро в состоянии сброса
4errorОшибка конфигурации (BURST = 0 или PULSE = 0)
5comparator_sync1 — напряжение в окне; 0 — вне окна

Оконный компаратор и пороговая защита

Тракт отслеживания уровней построен на скоростном компараторе TLV3502, выходы которого заведены в PL Zynq. Компаратор работает как быстрый аппаратный детектор границ.

Линия заряда (Ch0)  -----> | Потолок: POT0     | ---> Напряжение > 55 В -> Останов Ch0
Входное напряжение         | (Верхний порог)   |
        |                  +-------------------+
        v                            |
  [ TLV3502 ]                        v STATUS.5 (1 - в окне, 0 - вне окна)
        ^                            |
        |                  +-------------------+
Линия разряда (Ch1) -----> | Пол: POT1         | ---> Напряжение < 35 В -> Останов Ch1
                           | (Нижний порог)    |
                           +-------------------+

Настройка порогов через MCP42010

Пороги задаются двухканальным потенциометром MCP42010 через /dev/spidev1.0. Шаг ≈ 4,06 В на код.

  • POT0 (канал 0): верхний порог («потолок», отключение линии заряда).
  • POT1 (канал 1): нижний порог («пол», отключение линии разряда).

Управление из Forth:

0x11 0x0B cmp-set              \ оба порога (окно ~34.5...56.5 В)
0 <код> spi-u17 mcp42010-set   \ POT0: верхний порог (заряд)
1 <код> spi-u17 mcp42010-set   \ POT1: нижний порог (разряд)

Логика автоцикла секвенсора

  • Генератор 0 (заряд): накачка до превышения потолка (55 В), затем аппаратное глушение линии.
  • Генератор 1 (разряд): сброс энергии во вторичную цепь до падения ниже пола (35 В).
  • Одновременная работа генераторов 0 и 1 исключена аппаратно.

Измеритель тока AD7401A

Прецизионное двухполярное измерение тока на шунте R = 0,5 Ом (полная шкала ±320 мВ).

  • Базовый адрес 0x43C1_0000; шаг между каналами 0x40 байт (4 канала).
  • Сигма-дельта PDM-поток на 20 МГц, децимация OSR = 256 бит.
  • Интервал отсчёта 12,8 мкс; частота выборки 78 125 отсчётов/с.

Интерпретация PDM-демодулятора

  • 128 единиц за 256 бит — нулевой ток.
  • > 128 — прямой ток (источник → нагрузка).
  • < 128 — обратный ток (нагрузка → источник, включая ЭДС самоиндукции).

Карта регистров канала АЦП

СмещениеИмяДоступНазначение
+0x00CTRLRWУправление каналом АЦП
+0x04STATUSROСтатус готовности данных
+0x08COUNTROОтсчётов OSR с последнего сброса
+0x0CFWD_ACCROИнтеграл прямого заряда за RUN
+0x10FWD_CNTROЧисло отсчётов прямого тока
+0x14FWD_AVGROСредний прямой ток (Q8)
+0x18FWD_EMAROEMA прямого тока (Q8 в [15:0])
+0x1CREV_ACCROИнтеграл обратного заряда за RUN
+0x20REV_CNTROЧисло отсчётов обратного тока
+0x24REV_AVGROСредний обратный ток (Q8)
+0x28REV_EMAROEMA обратного тока (Q8 в [15:0])

Архитектура измерений

  • Batch-тракт (ACC, CNT, AVG): интегральные характеристики пачки; данные защёлкиваются по спаду RUN. Среднее: AVG = ACC × 256 / CNT.
  • Stream-тракт (EMA): скользящее среднее в реальном времени, обновляется каждый отсчёт (12,8 мкс).

Инженерные формулы и калибровка

Формат Q8 хранит целую часть в старших битах и 8 бит дробной части (значение делится на 256).

I_FWD = FWD_AVG × 5000 / 256  [мкА]
Q_net = (FWD_ACC − REV_ACC) × 64  [нКл]

Калиброванное чтение из Forth:

adc-fwd-ua@   \ прямой ток, мкА
adc-rev-ua@   \ обратный ток, мкА

Регламент измерений и предохранители

  • Напряжение источника: строго до 60 В.
  • Максимальный ток: при превышении 200 мА в любом направлении серию необходимо остановить.
  • Корректность таймингов: запрещена запись нулевых значений в PULSE и BURST.

Типовой сценарий запуска (Forth)

\ 1. Пороги окна компаратора TLV3502
0x11 0x0B cmp-set

\ 2. Включение АЦП и сброс счётчиков канала 0
adc0 1 adc-enable!
adc0 adc-reset-count

\ 3. Параметры тайминга генератора
1000 pulse-width!    \ 10 мкс импульс (1000 * 10 нс)
500  pulse-pause!    \ 5 мкс пауза
10   pulse-burst!    \ 10 импульсов в пачке
1    pulse-cycles!   \ 1 цикл
0    pulse-mode!     \ ONE-SHOT
1    pulse-seq!      \ секвенсор по компаратору

\ 4. Запуск и ожидание завершения
pulse-start

\ 5. Останов и считывание после защёлкивания Batch-тракта
pulse-stop
adc-avg-valid? wait
adc-batch@