Данная работа демонстрировалась на конференции «Технологии разработки и отладки сложных технических систем» 27-28 марта 2018 года.
Постановка задачи
Требуется разработка системы из генератора сигналов и АЦП которая будет формировать сигнал с заданными параметрами и производить его оцифровку. Полученные данные должны быть переданы в Simulink на обработку.
Аппаратура
Для работы собран стенд из модуля АЦП и генератора. В качестве АЦП используется субмодуль FM412x500M в котором есть четыре канала АЦП с частотой дискретизации 500 МГЦ. Субмодуль установлен на несущий модуль FMC128E в котором есть ПЛИС Artix 7 и интерфейс USB 3.0. Оба устройства подключены к ноутбуку с запущенным Simulink. Для контроля работоспособности разумеется используется осциллограф.
Внешний вид стенда:
Структурная схема стенда:
Сформированный сигнал:
Алгоритм работы стенда:
- Simulink подготавливает к запуску АЦП и генератор
- Simulink даёт команду генератору на запуск
- Генератор формирует строб (жёлтый сигнал) и собственно сигнал (голубой)
- АЦП по фронту строба начинает сбор данных
- АЦП собирает массив и передаёт его в Simulink
- Simulink отображает принятый сигнал от АЦП
Это классический однократный режим сбора. Его особенностью является именно однократность. Аппаратура по фронту сигнала собирает заданный массив данных. Фаза сбора данных происходит в режиме «жёсткого реального времени», а вот обработка — как получиться. Скорость сбора определяется числом выбранных каналов и частотой дискретизации. Для четырёх каналов АЦП и частоте дискретизации 500 МГц скорость потока данных составляет 4 Гбайт/с. С этой скоростью данные могут быть записаны в SODIMM модуля FMC128E. То есть может быть сохранена выборка объёмом 4 Гбайт.
Далее данные должны быть переданы в компьютер. Модуль FMC128E подключается к компьютеру через интерфейс USB 3.0. Скорость передачи данных составляет 300 Мбайт/c.
Simulink принимает массив данных и передаёт его на дальнейшую обработку. Время этой обработки уже определяется сложностью модели. В данном примере массив просто отображается на панели осциллографа.
В какой-то момент Simulink решает что нужно проводить следующий цикл и всё повторяется. Опять по USB передаются команды на подготовку АЦП, на запуск генератора и на сбор данных.
Такой режим очень удобен для отладки аппаратуры и алгоритмов. Можно никуда не торопиться. Собрать массив данных. На него спокойно посмотреть, записать на диск, выпить кофе. А вот когда всё будет отработано, то тогда уже можно переходить на непрерывный режим сбора.
Подключение DLL
Matlab позволяет подключать функции реализованные во внешних DLL. Simulink также имеет возможность подключения внешних DLL, при этом он добавляет некоторые требования. Внутри Simulink внешняя DLL выглядит как блок S-Function.
MATLAB предоставляет огромное количество примеров, в том числе и по созданию внешних DLL. Однако способ который предлагает MATLAB не очень удобный. Существует OpenSource проект easyLink. В этом проекте разработана библиотека классов для подключения к Simulink.
Для создания компонента требуется создать класс наследник от BaseBlock и объявить порты:
Проблемы подключения DLL
Внешние DLL позволяют очень многое, но при работе с ними есть ряд проблем. Наиболее существенными лично для меня являются следующие:
- Затруднена отладка DLL
- Неудобно смотреть вывод printf()
- Перекомпиляция DLL требует выхода из MATLAB
При отладке программы требуется проводить пошаговую отладку. В случае DLL существует возможность подключиться к уже загруженной в память DLL, назначить там точку останова и провести сеанс отладки. Но это надо отлавливать момент загрузки DLL через Simulink, каким то образом задерживать старт работы. Всё это сделать можно, но неудобно.
В процессе работы очень хочется видеть отладочный вывод который формируется как стандартный потоко stdout. В случае с DLL этот поток как то можно перехватить, но мне это не удалось.
Ну и наконец самое главное неудобство это необходимость выхода из MATLAB при перекомпиляции DLL. Иначе просто не удаётся записать новый файл. А выход и последующий запуск MATLAB занимает много времени.
Для решения этих проблем существует классический способ построения сложных программных комплексов. Это взаимодействие между программами через разделяемую память.
Подключение через разделяемую память
Современные операционные системы, как Windows так и Linux, позволяют организовывать общие области памяти. Это позволяет создавать надёжные программы. Например одна программа может содержать графический интерфейс и взаимодействовать с оператором, а другая программа может взаимодействовать с аппаратурой. При этом зависание программы которая взаимодействует с аппаратурой не приведёт к зависанию программы взаимодействия с оператором. В случае с Simulink такой подход также даёт некоторые преимущества. Программа для работы с аппаратурой будет запущена один раз, она подготовит аппаратуру и будет ждать команды через разделяемую память. DLL будет загружаться каждый раз при запуске Simulink на моделирование. Поскольку DLL не работает напрямую с аппаратурой, то это этот запуск будет производиться быстро.
Для данного стенда разработаны две программы и две DLL:
- simulink_a7dac — программа управления генератором
- simulink_adc — программа управления АЦП
- sm_ctrl — DLL управления генератором
- sm_adc — DLL управления АЦП
Структурная схема представлена на рисунке ниже:
Программа simulink_adc построена на основе библиотеки Bardy. Эта программа позволяет работать с любыми АЦП производства АО «ИнСис». Настройка на конкретный АЦП и несущий модуль производится через файлы инициализации.
Вид схемы в Simulink
Ну и наконец как это выглядит внутри Simulink:
Всё выглядит так как и принято в Simulink. Один блок для управления АЦП. Второй блок для управления генератором. Для управления генератором доступен ряд параметров. Для АЦП — всё через файл инициализации. При необходимости ряд параметров АЦП также можно вывести на уровень блока.
Обратите внимание на два задающих генератора. Они задают в терминах модельного времени момент старта и момент сбора данных. Эти моменты очень важны. Они собственно и задают связь между моделью и реальным миром. Сигнал старта поступает в блок АЦП, он обрабатывается в DLL. Через разделяемую память он поступает в программу АЦП. Далее он преобразуется в последовательность команд записи в регистры, которые через USB поступают в ПЛИС. А внутри ПЛИС взводится автомат поиска фронта сигнала старта. И только после того как автомат будет взведён в обратную сторону по этой же цепочке пойдёт подтверждение. Когда подтверждение дойдёт до Simulink на выходе блока sm_adc появиться сигнал start_out который будет передан в блок sm_ctrl. Причём это будет всё тот же самый момент модельного времени. В блоке sm_ctrl по такой же цепочке сигнал будет передан в ПЛИС генератора и она сформирует посылку сигнала. АЦП захватит этот сигнал в своей памяти. От второго задающего генератора будет сформирован сигнал сбора данных. По такому же пути данные попадут в Simulink и поступят на выход данных блока sm_adc. В данный момент возвращается блок размером 16384 отсчёта. Принятый блок отображается в осциллографе.
Результаты
Работа через разделяемую память показала свою эффективность. Программа управления АЦП позволяет работать с любыми нашими АЦП. При этом остаётся удобный способ настройки параметров через файл конфигурации. Программа разработана как консольное приложение, при этом виден весь отладочный вывод. Есть индикация работоспособности. Компонент SM_CTRL позволяет подключать различные внешние приложения для управления аппаратурой. Отладка программы управления АЦП не вызывает никаких трудностей. Это обычная программа, в которой можно установить точки останова и проводить отладку. По этой же технологии могут быть разработаны и другие программы для взаимодействия между Matlab/Simulink и внешним миром.
Работа опубликована на сайте hub.exponenta.ru;
Ссылки:
Комментариев нет:
Отправить комментарий