UPP/MATLAB
Razvalyaev be84043f18 Добавлена простенькая симуляция АЦП в сканирующем режиме.
Но надо отлаживать и сравнивать с работой реального (в плане разных режимов работы, доделать прерывания/дма, флаги и так далее)
2025-11-09 02:06:25 +03:00
..
app_wrapper Добавлена простенькая симуляция АЦП в сканирующем режиме. 2025-11-09 02:06:25 +03:00
MCU_STM32_Matlab Добавлена простенькая симуляция АЦП в сканирующем режиме. 2025-11-09 02:06:25 +03:00
MCU_Wrapper Добавлена простенькая симуляция АЦП в сканирующем режиме. 2025-11-09 02:06:25 +03:00
README.md Добавлена модель МК матлаб с компилятором MinGW 2025-11-08 23:40:43 +03:00
thyristors.slx Добавлена модель МК матлаб с компилятором MinGW 2025-11-08 23:40:43 +03:00
upp_r2023.slx Добавлена простенькая симуляция АЦП в сканирующем режиме. 2025-11-09 02:06:25 +03:00

MATLAB STM32 EMULATOR

СОДЕРЖАНИЕ

Общая структура эмулятора

Эмулятор состоит из четырех блоков:

  • приложение МК
  • оболочка МК для MATLAB, которая запускает приложение МК и эмулирует его периферию
  • оболочка приложения для настройки взаимодействия с кодом МК

Приложение МК в свою очередь разделено еще на два блока:

  • исходный код пользователя (код приложения)
  • исходный код библиотек и драйверов

Для каждого блока своя папка. Всего четыре папки:

Далее приведена структура эмулятора. Инструкция для портирования кода в MATLAB приведена ниже

Описание стуктуры эмулятора (пример для STM32)

Здесь содержиться описание четырех блоков эмулятора:

Оболочка МК

В этой папке содержаться оболочка(англ. wrapper) для запуска и контроля эмуляции микроконтроллеров в MATLAB (любого МК, не только STM). Оболочка представляет собой S-Function - блок в Simulink, который работает по скомпилированому коду. Компиляция происходит с помощью MSVC-компилятора.

S-Function работает особым образом: на шаге n она запускает скомпилированный код и ждет пока этот код выполниться. Только когда завершается выполнение кода, S-Function переходит на следующий шаг n+1.

Но программа МК это бесконечный цикл, который никогда не завершается. Поэтому есть несколько особенностей в выполнении такого кода в виде S-Function:

  • Для эмуляции создается отдельный поток для программы МК. Этот поток запускается в начале текущего шага симуляции, выполняется какое-то время, а потом приостанавливается. Это позволяет коду S-Function завершиться и перейти на следующий шаг.
  • Необходимо закрыть поток программы МК в конце симуляции. Для этого используется особый дефайн для while. Этот дефайн помимо условия while, проверяет условие окончания симуляции. И если симуляцию надо завершить, все бесконечные циклы while() пропускаются и поток доходил до конца функции main() и завершает себя.

Всего оболочка содержит 4 файла:

  • mcu_wrapper.c - файл, который запускает код МК и управляет его ходом. В нем содержаться функции для запуска/остановки потока программы МК, считывании входов и запись входов S-Function в соответствии с I/O портами МК.
  • MCU.c          - базовый файл, который представляет собой исходный код для компиляции S-Function в MATLAB. Вызывает функции из "mcu_wrapper.c"
  • mcu_wrapper_conf.h - общий для mcu_wrapper.c и MCU.c заголовочный файл. Содержит настройки для блока S-Function, а также дефайны для управления ходом программы МК.
  • run_mex.bat       - скрипт для компиляции кода компилятором MSVC. В нем прописываются пути для заголовочных файлов ".h", указываются файлы исходного кода ".c" и прописываются дефайны для компиляции.

Эмулятор STM для MATLAB

В папке "\MCU_STM32xxx_Matlab" есть два файла "stm32fxxx_matlab_conf.c/.h".

В них задаётся используемая периферия и подключаются библиотеки для периферии. Также объявляются функкции для инициализации/деинициализации периферии МК и структуры для эмуляции периферии. Симулятор МК находится в папке STM32F4xx_SIMULINK.

В папке "\MCU_STM32xxx_Matlab\Drivers" находяться стандартные библиотеки для STM/ARM, но переделанные под компилятор MSVC. Всего там две папки: CMSIS, STM32F4xx_HAL_Driver.

####### Папка STM32F4xx_SIMULINK В этой папке содержаться файлы для эмуляции периферии STM32 в MATLAB. Структура файлов такая же, как в библиотеке HAL:

  • название серии МК, который эмулируется (matlab),
  • идентификатор, что это для MATLAB (matlab),
  • периферия, функции для эмуляции которой содержит конкретный файл (gpio, tim). Пример: "stm32f4xx_matlab_tim.c/.h"

####### Папка CMSIS "Порт" библиотеки CMSIS для MSVC. Ниже приведен перечень всех файлов и краткое описание зачем они нужны:

  • arm_defines.h Содержит ARM дефайны для компиляции в MSVC.
  • core_cm4_matlab.h Данный файл является копией "core_cm4.h" с некоторыми изменениями
    • удалены первые ~160 строк, которые определяют компилятор ARM.
    • добавлена структура имитирующая память ядра *. Для того, чтобы при обращении по адресам регистров МК не было исключений при чтении по недоступному адресу.
  • stdint.h Данный файл является копией "stdint.h", из библиотеки для STM32. (только все дефайны uint32_t передалны как uint64_t. Т.к. в MATLAB всё компилируется в 64-битном формате, то сохранении адресов в 32-битных переменных, адреса будут усекаться и будут ошибки.)
  • stm32f407xx_matlab.h Данный файл является копией "stm32f407xx.h" с некоторыми изменениями:
    • добавлен кастомный "stdint.h" (через "", вместо <>)
    • добавлен "arm_defines.h" с ARM дефайнами для MSVC
    • добавлен матлабовский "cmsis_armcc_matlab.h" с вместо "cmsis_armcc.h"
    • добавлена структура имитирующая память ядра *. Для того, чтобы при обращении по адресам регистров МК не было исключений при чтении по недоступному адресу.
  • stm32f4xx.h - оригинальный файл "stm32f4xx.h".
  • system_stm32f4xx.h - оригинальный файл "system_stm32f4xx.h".

*память ядра не имитируется в полной мере, потому что STM32 - это 32-битный процессор, он имеет 4 Гб памяти. А MATLAB/MSVC делает ограничение на использование не больше 4Гб оперативной памяти. При этом еще есть матлабовские переменные которые тоже занимают место. Поэтому память эмулируется лишь частично. Как имено - задается в дефайнах и структуруре stm32f407xx_matlab.h.

####### Папка STM32F4xx_HAL_Driver Данная библиотека является копией HAL, за некоторыми исключениями. В основном касаются макросов для ожидания флага. Т.к. весь МК реализован програмно, то надо самому писать код, который будет выставлять флаги по определенным условиям. Только тогда библиотека HAL будет это считывать и выполнять свои функции. Но далеко не всегда есть необходимость так делать.

Поэтому, вместо того, чтобы пользоваться оригинальным HAL и писать эмулятор для всего 32-битного контроллера, можно переписать макросы или даже функции целиком под свои нужды.

Оболочка приложения

В папке "\app_wrapper" содержаться файлы для настройки взаимодействия между оболочкой МК и пользовательским кодом. Эта оболочка позволяет гибко настраивать как код МК будет интегрирован в симуляцию.

Основные файлы:

  • app_wrapper.c - основной файл оболочки приложения, содержит функции для инициализации, выполнения шага и деинициализации
  • app_init.c - код для инициализации приложения МК
  • app_io.c - работа с буферами ввода-вывода S-Function
  • app_includes.h - заголовочный файл для подключения к коду МК
  • app_wrapper.h - основные определения и структуры

Оболочка приложения предоставляет несколько секций для настройки:

  • Includes - подключение заголовочных файлов пользовательского кода
  • Dummy - заглушки для функций и переменных, которые не используются в симуляции
  • App Init - код инициализации приложения МК
  • App Step - код, выполняемый на каждом шаге симуляции
  • App Inputs - работа с входными портами S-Function
  • App Outputs - работа с выходными портами S-Function
  • App Deinit - код деинициализации приложения

Код пользователя

Данная папка содержит исходный код приложения МК. При этом драйверы и стандартные/HAL библиотеки, которые общие для всех проектов следует помещать в папку с эмулятором МК. Чтобы не редактировать исходники общих библиотек (CMSIS/HAL) в каждом проекте.

Инструкция

Общий алгоритм портирования кода для симуляции в MATLAB приведен ниже. Все настройки выполняются через графический интерфейс маски блока MCU.

  1. Добавление и базовая настройка блока

    • Перетащите блок MCU из библиотеки McuLib.slx в вашу модель
    • Откройте маску блока (двойной клик на блоке)
    • На вкладах "Wrapper Parameters", "App Wrapper User Code", "Config Peripheral" укажите пути к папкам:
      • Wrapper Path - путь к оболочке МК (MCU_Wrapper)
      • App Wrapper Path - путь к оболочке приложения (app_wrapper)
      • Peripheral Library Config - путь к конфигурации периферии (JSON файл)
  2. Настройка портов ввода-вывода

    • На вкладке "Порты ввода/вывода" задайте количество входных и выходных портов
    • Для каждого порта укажите имя и разрядность
    • Система автоматически сгенерирует соответствующий код в оболочке
  3. Конфигурация периферии

    • На вкладке "Конфигурация периферии" загрузите JSON файл с настройками
    • GUI автоматически создаст вкладки для каждой периферии (ADC, TIM, GPIO и т.д.)
    • Настройте параметры каждой периферии через соответствующие вкладки
  4. Настройка оболочки приложения

    • На вкладке "Оболочка приложения" выберите нужную секцию кода:
      • Includes - для подключения заголовочных файлов
      • Dummy - для создания заглушек функций
      • App Init/Step/Deinit - для кода инициализации, выполнения и деинициализации
      • App Inputs/Outputs - для работы с портами ввода-вывода
    • Редактируйте код непосредственно в текстовом поле маски
    • Сохраните изменения кнопкой "Сохранить код"
  5. Добавление исходных файлов

    • На вкладке "Исходные файлы" используйте таблицы для указания:
      • Путей к заголовочным файлам (.h)
      • Исходных файлов (.c, .cpp) и библиотек (.obj, .lib)
    • Добавляйте файлы через кнопки "Добавить файлы" и "Добавить папку"
  6. Компиляция кода

    • На вкладке "Компиляция" нажмите кнопку "Скомпилировать"
    • Выберите режим компиляции:
      • Release - для финальной симуляции
      • Debug - для отладки с точками останова
    • Следите за процессом компиляции в окне вывода
    • При ошибках - исправьте код и повторите компиляцию
  7. Запуск симуляции

    • После успешной компиляции запустите симуляцию модели
    • Для отладки подключитесь к MATLAB.exe из Visual Studio
    • Установите точки останова в коде МК или оболочки

Как запустить отладку

Для отладки симуляции необходимо приписать в mexing.m в вызове "run_mex.bat" слово debug, тогда код скомпилируется для дебага. После этого необходимо открыть любой(?) редактор кода, например Visual Studio. Открыть папку проекта (там должны быть все исходники программы и эмулятора). И подключиться к MATLAB.exe.

Теперь можно поставить точку в исходном коде эмулятора или программы МК и запустить симуляцию. Когда MATLAB дойдет до этого места, симуляция остановиться и в Visual Studio можно будет посмотреть все переменные, пройти код по строкам и в общем делать всё то, что можно делать в режиме отладки. Но отладка рабоатет только один раз. При повторном запуске симуляции остановки не произойдет. Поэтому перед каждой отладкой надо перекомпилировать код.

Ошибки

Ошибки при компиляции

Самые распространеные ошибки компилятора при портировании нового кода - это ошибки переопределения. Связаны с weak-фукнциями. В MSVC их нет как таковых. Поэтому необходимо закомментировать все weak-функции в HAL или пользовательском коде, чтобы на весь код было только одно определение функции.

Ошибки при симуляции

Обычно это исключения при чтении по недоступному адресу. Связано с разным адресным пространством МК и ПК. Поэтому надо выяснить на какой строке произошло исключение. И смотреть по какому адресу произошла попытка чтения и по какому адресу надо на самом деле считывать. И после этого скорректировать код так, чтобы адрес брался корректный.

Из общих решений - это может быть при попытки чтения по "экзотическим" адресам (bit-banding), для которых не определено адресное пространство в симуляции.