Запуск .Net Micro Framework 4.4 на STM32F4Discovery

95ad177860b04b2fad17a8eb2692650e.png
.Net Micro Framework — технология, позволяющая писать приложения для микроконтроллеров используя всю мощь управляемого кода и Visual Studio. Она существует давно и сейчас переживает второе рождение. Вокруг нее сформирован open-source проект, который не так давно переехал на GitHub. Однако пока еще это не «коробочный» продукт. Работа с .Net Micro Framework требует определенных навыков. В прошлый раз я писал про то, как создать и запустить простое «Hello world» приложение на эмуляторе для Windows. Сейчас речь пойдет о том, как поработать с .Net Micro Framework на настоящем «железе» — отладочной плате STM32F4Discovery.

Плата достаточно распространена и может быть приобретена, например, тут. Начиная с версии 4.4 порт для этой платы входит в дистрибутив netmf-interpreter. Ранее он существовал как отдельный проект.

В интернете и, в частности, на хабре можно найти материалы про запуск .Net Micro Framework на этой плате, но во-первых в них говорится о версии 4.3, а во-вторых там используются уже готовая сборка. Я же расскажу о том, как скомпилировать и запустить на STM32F4Discovery .Net Micro Framework версии 4.4 во всех подробностях. Статья будет длинная, так как нужно будет исправить несколько ошибок в дистрибутиве и скачать и установить несколько утилит и драйверов.

Подготовка к компиляции

Дистрибутив

В первую очередь нужно иметь сам дистрибутив.

Репозиторий находится тут. Можно скачать его как zip-архив, а можно получить, используя git. Инструкции на английском языке о том, как получить репозиторий и собрать из него установочные файлы, можно посмотреть тут. На основе этих инструкций и написана статья. Версии репозитория, связанные с конкретными релизами, можно скачать в zip-архивах тут.

Чтобы получить репозиторий с помощью git, нужно сделать следующее:

  1. Создать публичную копию на вашем аккаунте на серверах GitHub сделав fork. Все pull-запросы должны идти с публичного GitHub репозитория.
  2. Получить локальную копию репозитория, используя clone. Например, вот так:
    git clone https://github.com//netmf-interpreter.git
    Важно: При выборе пути для локального репозитория нужно обязательно сделать хотя бы одну родительскую папку. Например, D:\NETMF\repo, где repo — папка для репозитория. Это требуется для его правильной сборки.
  3. Настроить локальный репозиторий, как Upstream. Это позволит получать с помощью pull изменения с последних официальных коммитов и разбирать все несоответствия при получении кода локально до выполнения запроса pull. Для настройки Upstream можно использовать следующую команду:
    git remote add upstream https://github.com/NETMF/netmf-interpreter.git

Важно: Требования к локальному пути (должна быть хотя бы одна родительская папка — см. п 2 работы с git) актуальны и при распаковке репозитория из архива.

К сожалению, релиз .NET Micro Framework v4.4 Release To Web (RTW) содержит ошибки, которые не позволяют сразу собрать установочные файлы из репозитория. Однако, эти ошибки можно исправить, и далее я расскажу как это сделать.
После того, как репозиторий тем или иным способом оказался скопирован в локальную папку, нужно сделать следующее:

  1. Скачать binary tools zip файл. Этот файл содержит утилиты, необходимые для сборки как установочных файлов, так и «портов» для устройств. В будущем планируется отказаться от этих утилит, но пока еще они нужны.
  2. Разархивировать содержимое binary tools zip-файла в родительскую папку репозитория. Например для пути D:\NETMF\repo, где repo — папка для репозитория, папки bin и tools должны оказаться в папке D:\NETMF.
  3. Важно: В файле
    \Framework\Tools\BuildTasksInternal\BuildSigner\BuildSignerSpotBuild.csproj
    в строке 37 нужно заменить
    $(MSBuildProgramFiles32)\Microsoft Internal\Codesign.Submitter\CODESIGN.Submitter.dll
    на
    $(SPOROOT)\tools\x86\CODESIGN\CODESIGN.Submitter.dll

    Это исправление первой ошибки. Без такой замены собрать репозиторий не удастся. Как было сказано выше, .Net Micro Framework это open source проект и, к сожалению, он сталкивается с теми же проблемами, что и другие открытые проекты. Это исправление необходимо только для релиза .NET Micro Framework v4.4 Release To Web (RTW). В дальнейшем репозиторий уже будет содержать поправленные файлы. Про эту проблему можно почитать тут.

  4. Нужно скачать библиотеку CMSIS и положить ее в папку \СMSIS. Где ее брать и какая именно версия нужна, написано в файле \СMSIS\ReadMe.md.

    CMSIS расшифровывается как Cortex Microcontroller Software Interface Standart. Это не зависящая от конкретного производителя библиотека для работы с ядром Cortex-M, поставляемая и поддерживаемая разработчиками ядра — компанией ARM. Использование этой библиотеки позволяет существенно упростить создание «портов» на разные микроконтроллеры разных производителей.

    В случае с версией .Net Micro Framework 4.4 нужно скачать CMSIS не ниже версии 4.3. Библиотека поставляется в виде zip-архива (CMSIS-SP-00300-r4p3–00rel0.zip). Ее можно скачать на сайте ARM. Содержимое архива нужно положить в папку \СMSIS.

  5. Далее нужно установить .Net Micro Framework Cryptographic Libraries. Эти библиотеки используются для подписи сборок, которые будут исполняться на микроконтроллерах. Для работы нужны только исполняемые файлы криптографической библиотеки. Но, при желании, можно узнать как она устроена, так как можно посмотреть и исходные коды.

    Библиотеки доступны в виде установочного msi файла. Я рекомендую установить их в любую удобную папку (далее будем называть ее ), а затем копировать их в корень каждого репозитория, например D:\NETMF\repo и D:\NETMF\repo_master.

Дистрибутив представляет собой сложную структуру с огромным количеством перекрестных ссылок. Объединено все это с помощью проекта для MSBuild. Файлы проекта внешне выглядят как знакомые всем sln и proj файлы для Visual Studio, однако внутри у них более сложная структура. Именно поэтому использовать Visual Studio для сборки не получится.

Подробнее о составных частях и связях внутри дистрибутива я расскажу в следующих статьях, а сейчас нужно знать, что порт для STM3F4Discovery находится в папке
\Solutions\STM32F4DISCOVERY
а собранные бинарные и hex файлы появятся в папке
\BuildOutput

Visual Studio

MSBuild входит в состав Visual Studio. В документации к .netmf interpreter 4.4 указано, что поддерживаются редакции Visual Studio 2015 Community, Pro и Ultimate, так что для успешной сборки порта нужно установить одну из них.

Компилятор ARM

Далее нужен компилятор для ARM. Предусмотрена работа с двумя компиляторами:

Компилятор RealView входит в состав средства разработки Keil MDK. Бесплатная версия имеет ограничение в 32 кб кода, однако порт имеет больший объем, поэтому обязательно нужна лицензия, например 7-Day MDK-Professional Trial License. Про установку Keil MDK 5 можно прочитать тут.
Он должен быть установлен по умолчанию в папку C:\Keil_v5 .

GCC бесплатен, но генерируемые им прошивки имеют на 10% больший объем, чем сгенерированные компилятором RealView. GCC ARM Embedded можно скачать в виде архива и распаковать содержимое в любое место. Папку с распакованным содержимым архива я буду далее называть .

Компиляция с помощью ARM RealView Compilation tools

В дистрибутиве уже сделаны настройки компиляции для версий MDK 3.1, 3.80a, 4.12, 4.13, 4.54, 5.04, 5.05. Если нужно использовать другую версию, то можно добавить несколько строк в файл
\tools\Targets\Microsoft.Spot.system.mdk.targets

Я использовал версию 5.06. Для этого после строк

"$(MDK_TOOL_PATH)\ARMCC\bin\armcc.exe" "$(MDK_TOOL_PATH)\ARMCC\bin\armcc.exe" "$(MDK_TOOL_PATH)\ARMCC\bin\armasm.exe" "$(MDK_TOOL_PATH)\ARMCC\bin\armlink.exe" "$(MDK_TOOL_PATH)\ARMCC\bin\armar.exe" "$(MDK_TOOL_PATH)\ARMCC\bin\fromelf.exe" $(MdkCrtLibLinkSwitch) $(SWTC)libpath $(MDK_TOOL_PATH)\ARMCC\LIB

я добавил строки

"$(MDK_TOOL_PATH)\ARMCC\bin\armcc.exe" "$(MDK_TOOL_PATH)\ARMCC\bin\armcc.exe" "$(MDK_TOOL_PATH)\ARMCC\bin\armasm.exe" "$(MDK_TOOL_PATH)\ARMCC\bin\armlink.exe" "$(MDK_TOOL_PATH)\ARMCC\bin\armar.exe" "$(MDK_TOOL_PATH)\ARMCC\bin\fromelf.exe" $(MdkCrtLibLinkSwitch) $(SWTC)libpath $(MDK_TOOL_PATH)\ARMCC\LIB

Теперь можно приступать к компиляици. Нужно открыть командную строку и перейти в папку с репозиторием, например так:
cd /d D:\WORKDIR\NetMf\NetMFRepo\repo

затем нужно установить переменные окружения, выполнив:
setenv_mdk 5.06

1042d9e3466c445b98f05efe3e1eb9ff.png

После чего перейти к папке с портом (\Solutions\STM32F4DISCOVERY). Например, так:
cd /d D:\WORKDIR\NetMf\NetMFRepo\repo\Solutions\STM32F4DISCOVERY

Теперь можно запускать компиляцию используя, например, такую команду:

msbuild dotnetmf.proj /p:flavor=release /fl

где
msbuild — вызов запуска сборки
dotnetmf.proj — проект порта для STM32F4DISCOVERY
/p:flavor=release — тип сборки (debug/release/rtm)
/fl — запись лога сборки в файл.

файл лога будет лежать в текущей папке (в примере это D:\WORKDIR\NetMf\NetMFRepo\repo\Solutions\STM32F4DISCOVERY). Если лог не нужен, то /fl можно убрать.

Чтобы посмотреть все варианты компиляции нужно выполнить
msbuild /t:help

3cd30b7d7f9d469fa52ae4cc81f5c74c.png

Компиляция идет долго и занимает у меня 10 минут:
d8cf9fe8b8ae4fa88e02bf14930992bc.png

В результат появится множество файлов из которых нужны будут:
\BuildOutput\THUMB2FP\MDK5.06\le\FLASH\release\STM32F4DISCOVERY\bin\Tinybooter.hex\
\BuildOutput\THUMB2FP\MDK5.06\le\FLASH\release\STM32F4DISCOVERY\bin\tinyclr.hex\ER_CONFIG
\BuildOutput\THUMB2FP\MDK5.06\le\FLASH\release\STM32F4DISCOVERY\bin\tinyclr.hex\ER_FLASH

Для чистой сборки перед выполнением команды
msbuild dotnetmf.proj /p:flavor=release /fl
нужно выполнить команду
msbuild /t:clean
или удалить папку
\BuildOutput

2bcd3d83505942a69195dd635c031a58.png

Компиляция с помощью GCC ARM Embedded

Использование GCC может потребовать еще одной правки. В файле:
\Solutions\STM32F4DISCOVERY\STM32F4DISCOVERY.settings
после строки
true
нужно добавить
true
Это исправляет ошибку «NNNN.a uses VFP register arguments». Подробнее можно прочитать тут.
Однако, эта ошибка может и не возникнуть, если использовать «чистую» сборку.

Для чистой сборки перед выполнением команды
msbuild dotnetmf.proj /p:flavor=release /fl
нужно выполнить команду
msbuild /t:clean
или удалить папку
\BuildOutput

2f96c26d28d54d6e8b5cca6674ab06c8.png

Итак, чтобы собрать порт нужно открыть командную строку и перейти в папку с репозиторием, например так:
cd /d D:\WORKDIR\NetMf\NetMFRepo\repo
затем нужно установить переменные окружения, выполнив:

setenv_gcc

где  — версия gcc
 — путь, где находится GCC ARM Embedded

Команда может выглядеть например так:
setenv_gcc 4.9.3 D:\WORKDIR\NetMf\gcc_4_9_3

05ed5215e515412c91e468ccd5737790.png

После чего перейти к папке с портом (\Solutions\STM32F4DISCOVERY). Например так:

cd /d D:\WORKDIR\NetMf\NetMFRepo\repo\Solutions\STM32F4DISCOVERY

Компиляцию можно запустить используя, например, такую команду:

msbuild dotnetmf.proj /p:flavor=release /fl

где
msbuild — вызов запуска сборки
dotnetmf.proj — проект порта для STM32F4DISCOVERY
/p:flavor=release — тип сборки (debug/release/rtm)
/fl — запись лога сборки в файл.

файл лога будет лежать в текущей папке (в примере это D:\WORKDIR\NetMf\NetMFRepo\repo\Solutions\STM32F4DISCOVERY). Если лог не нужен, то /fl можно убрать.

Чтобы посмотреть все варианты компиляции нужно выполнить
msbuild /t:help

01f0d1d2820948708cc4678ce6d87ecf.png

Компиляция идет долго и занимает у меня 10 минут:
c7a165c33ccf4cf7b6127e48446dab75.png

В результат появится множество файлов из которых нужны будут:
\BuildOutput\THUMB2FP\GCC4.9\le\FLASH\release\STM32F4DISCOVERY\bin\Tinybooter.hex
\BuildOutput\THUMB2FP\GCC4.9\le\FLASH\release\STM32F4DISCOVERY\bin\tinyclr.hex\ER_CONFIG
\BuildOutput\THUMB2FP\GCC4.9\le\FLASH\release\STM32F4DISCOVERY\bin\tinyclr.hex\ER_FLASH

Прошивка платы

Итак, имеются 3 файла:
Tinybooter.hex, ER_CONFIG и ER_FLASH .

Tinybooter — это bootloader. Они используется для прошивки CLR. ER_CONFIG и ER_FLASH это сама CLR.

Для того, чтобы прошить плату нам потребуется дополнительное ПО:

  1. STM32 ST-LINK Utility — программатор, чтобы прошить TinyBooter.
  2. Установленные MicroFraimworkSDK.MSI и NetMFVS14.vsix — первый содержит необходимые библиотеки и утилиты, второй — template проектов .Net Micro Fraimwork для Visual Studio.
  3. USB драйер, необходимый для того, чтобы утилиты из состава MicroFraimworkSDK увидили плату (Для Windows 10 не нужен).

Для прошивки платы нужно сделать следующее:

  1. Подключить плату к компьютеру через miniUSB провод:
    87e37e0278304e0e8ef5258185d8640e.png
  2. Запустить STM32 ST-LINK Utility и выбирать меню Target→Connect:
    3e565a6fafb74a80a446c43d931715b2.png

    После соединения с платой STM32 ST-LINK Utility будет выглядеть примерно так:
    59f058e39da94ea99b4241c2a87a36a8.png

  3. Нужно стереть текущую прошивку выбрав в меню Target→Erase Sectors…:
    3400788657474b8d93bd152e8fff4989.png

    И там нажать Select All, а затем Apply:
    04104a82f39547e9973dbbe192626abf.png

    Процесс очистки flash микроконтроллера:
    effa252f30dc4fa1a3da34fab83a684f.png

    После очистки STM32 ST-LINK Utility будет выглядеть так:
    01950b4cecf941e69cc1acfe4e31d470.png

  4. Нужно прошить TinyBooter.hex выбрав меню Target→ Program & Verify…:
    66705b1b6189409d81ce21a475162f1b.png

    а затем выбрать файл tinybooter.hex и нажать Start:
    d08a2204d59b4f26a49d2bdf3cdd5ce8.png

    После прошивки STM32 ST-LINK Utility будет выглядеть так:
    9086b2dca33747b5871301a0302b146c.png

  5. Нужно перезагрузить плату или вытащив miniUsb провод или нажав черную кнопку Reset
  6. Вставить microUSB провод:
    53d34d0cf1e44c7da6ba2e4a77e41681.png

    STM32 ST-LINK Utility можно закрыть. miniUsb провод теперь будет использоваться только в качестве питания.

  7. На Windows 10 драйвер устанавливается автоматически, а для других версий нужно установить USB драйвер из списка выше в режиме ручной установки:
    d93cd53182744e36b3526e893a607a69.png
  8. Теперь нужно запустить .NET Micro Framework Deployment Tool.
    Найти ее можно в MicroFrameworkSDK:
    C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.4\Tools\MFDeploy.exe

    В ней нужно переключить интерфейс с Serial на USB:
    e6e28e4af2cb4186bbe4f5d63899217f.png

    После этого появится имя платы. Проверить правильность работы TinyBooter можно нажав кнопку Ping. В консоли будет выведено Pinigng… TinyBooter
    e86be2fdc937462681798ac7b95f89a4.png

  9. Далее нужно с помощью .NET Micro Framework Deployment Tool прошить оставшиеся 2 файла ER_CONFIG и ER_FLASH. Выбрать их нужно после нажатия нижней кнопки Browse…
    6827b6d5d82643abb63b409515efb906.png

    Для прошивки нужно нажать Deploy:
    bd4a20c3bc8e4405bce07afb4de31b95.png

    После прошивки можно нажать еще раз Ping и убедиться что CLR развернута на плате:
    1190629960a344a0a27d3b2a09c633a5.png

    Все, плата готова для работы.

Первый проект на Visual Studio

Теперь можно создать и запустить проект на Visual Studio. Сделаем простой blinky проект, мигающий светодиодами.

Запускаем Visual Studio и создаем новый проект:
2c84fd7138d04975bdbb1fb0051b4c0f.png

Если установка SDK и vsix была выполнена верно, то появится новый template проекта Micro Framework. Выберем Console Application:
34dbcd3f9e734dfd8c6c0ca1b8023b18.png

Создав solution, можно зайти в свойства проекта:
4e9c11fb9c4742e2abc623b3e6bb4fde.png

В настройках проекта на вкладке .NET Micro Framework в поле Transport выбираем USB. После этого название платы должно появиться в поле Device:
21eea30c82b24c02983c82f2ab6287e2.png

Сохраняем и закрываем настройки.

Далее нужно добавить Refrence на сборку по адресу:
C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.4\Assemblies\le\Microsoft.SPOT.Hardware.dll

a7256596a551489d8b1fdc1be52abc83.png

И последним этапом нужно заменить код в program.cs на этот:

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace STM32F4DISC_Test
{
    public class Program
    {
        public static void Main()
        {
            OutputPort ledGreen = new OutputPort((Cpu.Pin)60, false);
            OutputPort ledYellow = new OutputPort((Cpu.Pin)61, false);
            OutputPort ledRed = new OutputPort((Cpu.Pin)62, false);
            OutputPort ledBlue = new OutputPort((Cpu.Pin)63, false);

            while (true)
            {
                ledGreen.Write(true);
                Thread.Sleep(500);
                ledYellow.Write(true);
                Thread.Sleep(500);
                ledRed.Write(true);
                Thread.Sleep(500);
                ledBlue.Write(true);
                Thread.Sleep(500);
                ledGreen.Write(false);
                ledYellow.Write(false);
                ledRed.Write(false);
                ledBlue.Write(false);
                Thread.Sleep(500);
            }
        }
    }
}

Запускаем проект:
eafa66aa680249969b6b64012a2738a2.png

И через несколько секунд светодиоды на плате начинают мигать.

Заключение

.NET Micro Fraimwork — достаточно сложный проект. На текущий момент, он все еще требует определенных навыков и знаний, особенно при работе с репозиторием. В данной статье я специально максимально подробно рассказал о том, с чем приходится сталкиваться при компиляции портов, так как эта информация пригодится при разработке решений для собственных плат.
Однако запустить .NET Micro Fraimwork на STM32F4Discovery можно проще и быстрее, взяв уже готовые файлы Tinybooter.hex, ER_CONFIG и ER_FLASH. Скачать их можно тут.

В ближайшее время я подготовлю архив, содержащий исправленную версию репозитория и все необходимые инструменты для сборки и запуска порта на STM32F4Discovery с помощью GCC, и опубликую на geektimes короткую инструкцию о том, как это сделать.

© Geektimes