Добавлена модель МК матлаб с компилятором MinGW

Но по какой-то приниче запуск модели лочит MCU.mexw64 и его нельзя удалить. Но при этом можно переименовать... непонятно крч
This commit is contained in:
2025-11-08 18:18:17 +03:00
parent 67c8d0e039
commit afc4a114f6
412 changed files with 863427 additions and 120 deletions

183
MATLAB/README.md Normal file
View File

@@ -0,0 +1,183 @@
# MATLAB STM32 EMULATOR
**СОДЕРЖАНИЕ**
- [Общая структура эмулятора](#общая-структура-эмулятора)
- [Описание стуктуры эмулятора (пример для STM32)](#описание-стуктуры-эмулятора-пример-для-stm32)
- [Оболочка МК](#оболочка-мк)
- [Эмулятор STM для MATLAB](#эмулятор-stm-для-matlab)
- [Оболочка приложения](#оболочка-приложения)
- [Код пользователя](#код-пользователя)
- [Инструкция](#инструкция)
- [Портирование кода](#портирование-кода)
- [Как скомпилировать код](#как-скомпилировать-код)
- [Как запустить отладку](#как-запустить-отладку)
- [Ошибки при портировании](#ошибки)
## Общая структура эмулятора
Эмулятор состоит из четырех блоков:
- приложение МК
- оболочка МК для MATLAB, которая запускает приложение МК и эмулирует его периферию
- оболочка приложения для настройки взаимодействия с кодом МК
Приложение МК в свою очередь разделено еще на два блока:
- исходный код пользователя (код приложения)
- исходный код библиотек и драйверов
Для каждого блока своя папка. Всего четыре папки:
- Code ([од пользователя_](#код-пользователя))
- MCU_STM32xxx_Matlab ([_эмулятор STM для MATLAB_](#эмулятор-stm-для-matlab))
- MCU_Wrapper ([_оболочка МК_](#оболочка-мк))
- app_wrapper ([_оболочка приложения_](#оболочка-приложения))
_*в скобочках ссылки на подробное описание папки_
Далее приведена структура эмулятора. Инструкция для портирования кода в MATLAB приведена [ниже](#инструкция)
## Описание стуктуры эмулятора (пример для STM32)
Здесь содержиться описание четырех блоков эмулятора:
- [Оболочка МК](#оболочка-мк)
- [Эмулятор STM для MATLAB](#эмулятор-stm-для-matlab)
- [Оболочка приложения](#оболочка-приложения)
- [Код пользователя](#код-пользователя)
#### Оболочка МК
В этой папке содержаться оболочка(англ. 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](#папка-stm32f4xx_simulink).
В папке "_\MCU_STM32xxx_Matlab\Drivers_" находяться стандартные библиотеки для STM/ARM, но переделанные под компилятор MSVC. Всего там две папки: [CMSIS](#папка-cmsis), [STM32F4xx_HAL_Driver](#папка-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 библиотеки, которые общие для всех проектов следует помещать в [папку с эмулятором МК](#эмулятор-stm-для-matlab). Чтобы не редактировать исходники общих библиотек (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), для которых [не определено адресное пространство в симуляции](#папка-cmsis).