Программно-аппаратный комплекс «Архимед»
Оглавление
- Программная архитектура (Rust + AI + Forth)
- Исполнительное ядро 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
переключает текущий активный вывод.
| Источник | Транспорт / Порт | Назначение |
|---|---|---|
| console | stdin / stdout | Локальная отладка и управление через последовательный порт / SSH |
| web | HTTP / WebSocket (:8081) | Веб-терминал для интерактивного управления через браузер |
| MQTT | TCP (Брокер) | Телеметрия, интеграция со SCADA и публикация статусов |
| MCP | HTTP (:8090) + stdio | Model 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 | +0x00 | RO | Текущий статус канала |
| CTRL | +0x04 | RW | Управление режимами и пуском |
| PRE_DELAY | +0x08 | RW | Предзадержка перед серией (в тактах 10 нс) |
| PULSE | +0x0C | RW | Длительность импульса. Запрещено 0 |
| PAUSE | +0x10 | RW | Длительность паузы (в тактах) |
| BURST | +0x14 | RW | Импульсов в пачке. Запрещено 0 |
| PST_DELAY | +0x18 | RW | Постзадержка после пачки (в тактах) |
| CYCLE | +0x1C | RW | Число пачек/циклов генерации |
| BURST_DONE | +0x20 | RO | Накопительный счётчик отработанных импульсов |
Диапазон параметров: 0 … 4 294 967 295. Конфигурации с PULSE = 0 или BURST = 0 отбрасываются ядром и вызывают флаг ошибки.
Биты CTRL (+0x04)
| Бит | Имя | Назначение |
|---|---|---|
| 0 | RUN | 1 — запуск; 0 — останов |
| 1 | RESET | Аппаратный сброс автомата состояний |
| 2 | MODE | 0 — ONE-SHOT; 1 — CONTINUOUS |
| 3 | INVERT | Инверсия полярности импульса |
| 4 | SEQUENCE | 1 — включение секвенсора (останов по порогу компаратора) |
| 5..31 | — | Зарезервированы |
Биты STATUS (+0x00)
| Бит | Имя | Назначение |
|---|---|---|
| 0 | running | Генератор активен |
| 1 | running_dup | Дублирующий флаг активности |
| 2 | done | Завершение последовательности импульсов |
| 3 | bReset | Ядро в состоянии сброса |
| 4 | error | Ошибка конфигурации (BURST = 0 или PULSE = 0) |
| 5 | comparator_sync | 1 — напряжение в окне; 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 — обратный ток (нагрузка → источник, включая ЭДС самоиндукции).
Карта регистров канала АЦП
| Смещение | Имя | Доступ | Назначение |
|---|---|---|---|
| +0x00 | CTRL | RW | Управление каналом АЦП |
| +0x04 | STATUS | RO | Статус готовности данных |
| +0x08 | COUNT | RO | Отсчётов OSR с последнего сброса |
| +0x0C | FWD_ACC | RO | Интеграл прямого заряда за RUN |
| +0x10 | FWD_CNT | RO | Число отсчётов прямого тока |
| +0x14 | FWD_AVG | RO | Средний прямой ток (Q8) |
| +0x18 | FWD_EMA | RO | EMA прямого тока (Q8 в [15:0]) |
| +0x1C | REV_ACC | RO | Интеграл обратного заряда за RUN |
| +0x20 | REV_CNT | RO | Число отсчётов обратного тока |
| +0x24 | REV_AVG | RO | Средний обратный ток (Q8) |
| +0x28 | REV_EMA | RO | EMA обратного тока (Q8 в [15:0]) |
Архитектура измерений
- Batch-тракт (ACC, CNT, AVG): интегральные характеристики пачки; данные защёлкиваются по спаду RUN. Среднее:
AVG = ACC × 256 / CNT. - Stream-тракт (EMA): скользящее среднее в реальном времени, обновляется каждый отсчёт (12,8 мкс).
Инженерные формулы и калибровка
Формат Q8 хранит целую часть в старших битах и 8 бит дробной части (значение делится на 256).
Калиброванное чтение из 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@