.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, нужно сделать следующее:
- Создать публичную копию на вашем аккаунте на серверах GitHub сделав fork. Все pull-запросы должны идти с публичного GitHub репозитория.
- Получить локальную копию репозитория, используя clone. Например, вот так:
git clone https://github.com/<your GitHub ID>/netmf-interpreter.git
Важно: При выборе пути для локального репозитория нужно обязательно сделать хотя бы одну родительскую папку. Например,D:NETMFrepo
, гдеrepo
— папка для репозитория. Это требуется для его правильной сборки. - Настроить локальный репозиторий, как 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) содержит ошибки, которые не позволяют сразу собрать установочные файлы из репозитория. Однако, эти ошибки можно исправить, и далее я расскажу как это сделать.
После того, как репозиторий тем или иным способом оказался скопирован в локальную папку, нужно сделать следующее:
- Скачать binary tools zip файл. Этот файл содержит утилиты, необходимые для сборки как установочных файлов, так и “портов” для устройств. В будущем планируется отказаться от этих утилит, но пока еще они нужны.
- Разархивировать содержимое binary tools zip-файла в родительскую папку репозитория. Например для пути
D:NETMFrepo
, гдеrepo
— папка для репозитория, папкиbin
иtools
должны оказаться в папкеD:NETMF
. - Важно: В файле
<repo folder>FrameworkToolsBuildTasksInternalBuildSignerBuildSignerSpotBuild.csproj
в строке 37 нужно заменить
<HintPath>$(MSBuildProgramFiles32)Microsoft InternalCodesign.SubmitterCODESIGN.Submitter.dll</HintPath>
на
<HintPath>$(SPOROOT)toolsx86CODESIGNCODESIGN.Submitter.dll</HintPath>
Это исправление первой ошибки. Без такой замены собрать репозиторий не удастся. Как было сказано выше, .Net Micro Framework это open source проект и, к сожалению, он сталкивается с теми же проблемами, что и другие открытые проекты. Это исправление необходимо только для релиза .NET Micro Framework v4.4 Release To Web (RTW). В дальнейшем репозиторий уже будет содержать поправленные файлы. Про эту проблему можно почитать тут.
- Нужно скачать библиотеку CMSIS и положить ее в папку
Где ее брать и какая именно версия нужна, написано в файле
<repo folder>СMSIS.
<repo folder>СMSISReadMe.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. Содержимое архива нужно положить в папку
<repo folder>СMSIS
. - Далее нужно установить .Net Micro Framework Cryptographic Libraries. Эти библиотеки используются для подписи сборок, которые будут исполняться на микроконтроллерах. Для работы нужны только исполняемые файлы криптографической библиотеки. Но, при желании, можно узнать как она устроена, так как можно посмотреть и исходные коды.
Библиотеки доступны в виде установочного msi файла. Я рекомендую установить их в любую удобную папку (далее будем называть ее
), а затем копировать их в корень каждого репозитория, например
<crypto install folder>
D:NETMFrepo
иD:NETMFrepo_master
.
Дистрибутив представляет собой сложную структуру с огромным количеством перекрестных ссылок. Объединено все это с помощью проекта для MSBuild. Файлы проекта внешне выглядят как знакомые всем sln и proj файлы для Visual Studio, однако внутри у них более сложная структура. Именно поэтому использовать Visual Studio для сборки не получится.
Подробнее о составных частях и связях внутри дистрибутива я расскажу в следующих статьях, а сейчас нужно знать, что порт для STM3F4Discovery находится в папке
<repo folder>SolutionsSTM32F4DISCOVERY
а собранные бинарные и hex файлы появятся в папке
<repo folder>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 можно скачать в виде архива и распаковать содержимое в любое место. Папку с распакованным содержимым архива я буду далее называть
.
<gcc folder>
Компиляция с помощью ARM RealView Compilation tools
В дистрибутиве уже сделаны настройки компиляции для версий MDK 3.1, 3.80a, 4.12, 4.13, 4.54, 5.04, 5.05. Если нужно использовать другую версию, то можно добавить несколько строк в файл
<repo folder>toolsTargetsMicrosoft.Spot.system.mdk.targets
Я использовал версию 5.06. Для этого после строк
<CC Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.05'">"$(MDK_TOOL_PATH)ARMCCbinarmcc.exe"</CC>
<CPP Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.05'">"$(MDK_TOOL_PATH)ARMCCbinarmcc.exe"</CPP>
<AS Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.05'">"$(MDK_TOOL_PATH)ARMCCbinarmasm.exe"</AS>
<LINK Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.05'">"$(MDK_TOOL_PATH)ARMCCbinarmlink.exe"</LINK>
<AR Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.05'">"$(MDK_TOOL_PATH)ARMCCbinarmar.exe"</AR>
<FROMELF Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.05'">"$(MDK_TOOL_PATH)ARMCCbinfromelf.exe"</FROMELF>
<MdkCrtLibLinkSwitch Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.05'">$(MdkCrtLibLinkSwitch) $(SWTC)libpath $(MDK_TOOL_PATH)ARMCCLIB</MdkCrtLibLinkSwitch>
я добавил строки
<CC Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.06'">"$(MDK_TOOL_PATH)ARMCCbinarmcc.exe"</CC>
<CPP Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.06'">"$(MDK_TOOL_PATH)ARMCCbinarmcc.exe"</CPP>
<AS Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.06'">"$(MDK_TOOL_PATH)ARMCCbinarmasm.exe"</AS>
<LINK Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.06'">"$(MDK_TOOL_PATH)ARMCCbinarmlink.exe"</LINK>
<AR Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.06'">"$(MDK_TOOL_PATH)ARMCCbinarmar.exe"</AR>
<FROMELF Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.06'">"$(MDK_TOOL_PATH)ARMCCbinfromelf.exe"</FROMELF>
<MdkCrtLibLinkSwitch Condition="'$(COMPILER_TOOL_VERSION)'=='MDK5.06'">$(MdkCrtLibLinkSwitch) $(SWTC)libpath $(MDK_TOOL_PATH)ARMCCLIB</MdkCrtLibLinkSwitch>
Теперь можно приступать к компиляици. Нужно открыть командную строку и перейти в папку с репозиторием, например так:
cd /d D:WORKDIRNetMfNetMFReporepo
затем нужно установить переменные окружения, выполнив:
setenv_mdk 5.06
После чего перейти к папке с портом (<repo folder>SolutionsSTM32F4DISCOVERY
). Например, так:
cd /d D:WORKDIRNetMfNetMFReporepoSolutionsSTM32F4DISCOVERY
Теперь можно запускать компиляцию используя, например, такую команду:
msbuild dotnetmf.proj /p:flavor=release /fl
где
— вызов запуска сборки
msbuild
— проект порта для STM32F4DISCOVERY
dotnetmf.proj
— тип сборки (debug/release/rtm)
/p:flavor=release
— запись лога сборки в файл.
/fl
файл лога будет лежать в текущей папке (в примере это
). Если лог не нужен, то
D:WORKDIRNetMfNetMFReporepoSolutionsSTM32F4DISCOVERY
можно убрать.
/fl
Чтобы посмотреть все варианты компиляции нужно выполнить
msbuild /t:help
Компиляция идет долго и занимает у меня 10 минут:
В результат появится множество файлов из которых нужны будут:
<repo folder>BuildOutputTHUMB2FPMDK5.06leFLASHreleaseSTM32F4DISCOVERYbinTinybooter.hex
<repo folder>BuildOutputTHUMB2FPMDK5.06leFLASHreleaseSTM32F4DISCOVERYbintinyclr.hexER_CONFIG
<repo folder>BuildOutputTHUMB2FPMDK5.06leFLASHreleaseSTM32F4DISCOVERYbintinyclr.hexER_FLASH
Для чистой сборки перед выполнением команды
msbuild dotnetmf.proj /p:flavor=release /fl
нужно выполнить команду
msbuild /t:clean
или удалить папку
<repo folder>BuildOutput
Компиляция с помощью GCC ARM Embedded
Использование GCC может потребовать еще одной правки. В файле:
<repo folder>SolutionsSTM32F4DISCOVERYSTM32F4DISCOVERY.settings
после строки
<NO_BOOTLOADER_COMPRESSION>true</NO_BOOTLOADER_COMPRESSION>
нужно добавить
<PLATFORM_EMULATED_FLOATINGPOINT Condition="'$(COMPILER_TOOL)'=='GCC'">true</PLATFORM_EMULATED_FLOATINGPOINT>
Это исправляет ошибку “NNNN.a uses VFP register arguments”. Подробнее можно прочитать тут.
Однако, эта ошибка может и не возникнуть, если использовать “чистую” сборку.
Для чистой сборки перед выполнением команды
msbuild dotnetmf.proj /p:flavor=release /fl
нужно выполнить команду
msbuild /t:clean
или удалить папку
<repo folder>BuildOutput
Итак, чтобы собрать порт нужно открыть командную строку и перейти в папку с репозиторием, например так:
cd /d D:WORKDIRNetMfNetMFReporepo
затем нужно установить переменные окружения, выполнив:
setenv_gcc <gcc ver> <gcc folder>
где
— версия gcc
<gcc ver>
— путь, где находится GCC ARM Embedded
<gcc folder>
Команда может выглядеть например так:
setenv_gcc 4.9.3 D:WORKDIRNetMfgcc_4_9_3
После чего перейти к папке с портом (
). Например так:
<repo folder>SolutionsSTM32F4DISCOVERY
cd /d D:WORKDIRNetMfNetMFReporepoSolutionsSTM32F4DISCOVERY
Компиляцию можно запустить используя, например, такую команду:
msbuild dotnetmf.proj /p:flavor=release /fl
где
— вызов запуска сборки
msbuild
— проект порта для STM32F4DISCOVERY
dotnetmf.proj
— тип сборки (debug/release/rtm)
/p:flavor=release
— запись лога сборки в файл.
/fl
файл лога будет лежать в текущей папке (в примере это
). Если лог не нужен, то
D:WORKDIRNetMfNetMFReporepoSolutionsSTM32F4DISCOVERY
можно убрать.
/fl
Чтобы посмотреть все варианты компиляции нужно выполнить
msbuild /t:help
Компиляция идет долго и занимает у меня 10 минут:
В результат появится множество файлов из которых нужны будут:
<repo folder>BuildOutputTHUMB2FPGCC4.9leFLASHreleaseSTM32F4DISCOVERYbinTinybooter.hex
<repo folder>BuildOutputTHUMB2FPGCC4.9leFLASHreleaseSTM32F4DISCOVERYbintinyclr.hexER_CONFIG
<repo folder>BuildOutputTHUMB2FPGCC4.9leFLASHreleaseSTM32F4DISCOVERYbintinyclr.hexER_FLASH
Прошивка платы
Итак, имеются 3 файла:
.
Tinybooter.hex, ER_CONFIG и ER_FLASH
— это bootloader. Они используется для прошивки CLR.
Tinybooter
и
ER_CONFIG
это сама CLR.
ER_FLASH
Для того, чтобы прошить плату нам потребуется дополнительное ПО:
- STM32 ST-LINK Utility — программатор, чтобы прошить TinyBooter.
- Установленные MicroFraimworkSDK.MSI и NetMFVS14.vsix — первый содержит необходимые библиотеки и утилиты, второй — template проектов .Net Micro Fraimwork для Visual Studio.
- USB драйер, необходимый для того, чтобы утилиты из состава MicroFraimworkSDK увидили плату (Для Windows 10 не нужен).
Для прошивки платы нужно сделать следующее:
- Подключить плату к компьютеру через miniUSB провод:
- Запустить STM32 ST-LINK Utility и выбирать меню Target->Connect:
После соединения с платой STM32 ST-LINK Utility будет выглядеть примерно так:
- Нужно стереть текущую прошивку выбрав в меню Target->Erase Sectors...:
И там нажать Select All а затем Apply:
Процесс очистки flash микроконтроллера:
После очистки STM32 ST-LINK Utility будет выглядеть так:
- Нужно прошить TinyBooter.hex выбрав меню Target-> Program & Verify...:
а затем выбрать файл tinybooter.hex и нажать Start:
После прошивки STM32 ST-LINK Utility будет выглядеть так:
- Нужно перезагрузить плату или вытащив miniUsb провод или нажав черную кнопку Reset
- Вставить microUSB провод:
STM32 ST-LINK Utility можно закрыть. miniUsb провод теперь будет использоваться только в качестве питания.
- На Windows 10 драйвер устанавливается автоматически, а для других версий нужно установить USB драйвер из списка выше в режиме ручной установки:
- Теперь нужно запустить .NET Micro Framework Deployment Tool.
Найти ее можно в MicroFrameworkSDK:
C:Program Files (x86)Microsoft .NET Micro Frameworkv4.4ToolsMFDeploy.exe
В ней нужно переключить интерфейс с Serial на USB:
После этого появится имя платы. Проверить правильность работы TinyBooter можно нажав кнопку Ping. В консоли будет выведено
Pinigng… TinyBooter
- Далее нужно с помощью .NET Micro Framework Deployment Tool прошить оставшиеся 2 файла ER_CONFIG и ER_FLASH. Выбрать их нужно после нажатия нижней кнопки Browse…
Для прошивки нужно нажать Deploy:
После прошивки можно нажать еще раз Ping и убедиться что CLR развернута на плате:
Все, плата готова для работы.
Первый проект на Visual Studio
Теперь можно создать и запустить проект на Visual Studio. Сделаем простой blinky проект, мигающий светодиодами.
Запускаем Visual Studio и создаем новый проект:
Если установка SDK и vsix была выполнена верно, то появится новый template проекта Micro Framework. Выберем Console Application:
Создав solution, можно зайти в свойства проекта:
В настройках проекта на вкладке .NET Micro Framework в поле Transport выбираем USB. После этого название платы должно появиться в поле Device:
Сохраняем и закрываем настройки.
Далее нужно добавить Refrence на сборку по адресу:
C:Program Files (x86)Microsoft .NET Micro Frameworkv4.4AssembliesleMicrosoft.SPOT.Hardware.dll
И последним этапом нужно заменить код в
на этот:
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);
}
}
}
}
Запускаем проект:
И через несколько секунд светодиоды на плате начинают мигать.
Заключение
.NET Micro Fraimwork — достаточно сложный проект. На текущий момент, он все еще требует определенных навыков и знаний, особенно при работе с репозиторием. В данной статье я специально максимально подробно рассказал о том, с чем приходится сталкиваться при компиляции портов, так как эта информация пригодится при разработке решений для собственных плат.
Однако запустить .NET Micro Fraimwork на STM32F4Discovery можно проще и быстрее, взяв уже готовые файлы Tinybooter.hex, ER_CONFIG и ER_FLASH. Скачать их можно тут.
В ближайшее время я подготовлю архив, содержащий исправленную версию репозитория и все необходимые инструменты для сборки и запуска порта на STM32F4Discovery с помощью GCC, и опубликую на geektimes короткую инструкцию о том, как это сделать.
Автор: AlexandrSurkov