.NET Micro Framework

Microsoft .NET Framework во встраиваемых приложениях

Colin Miller

Исходный код можно скачать по ссылке

Продукты и технологии:

Microsoft .NET Framework, Visual Studio 2013, .NET Micro Framework, Интернет вещей (IoT)

В статье рассматриваются:

  • управление устройствами командами с телефона;
  • разработка встраиваемого ПО;
  • разработка элементов управления устройством.

Мир прошел долгий путь от первого контекстно-зависимого редактора кода на C, появившегося в начале 1980-х. Инструментарий и языки, изначально разработанные для настольных приложений, распространились на серверные, облачные и другие среды. Microsoft .NET Framework и Visual Studio предоставляют современный инструментарий, который значительно увеличивает эффективность труда программиста. Инструментарий и языки .NET Framework дают библиотеки и средства коллективной работы с богатыми возможностями и защищают программистов от наиболее распространенных ошибок.

Однако эти достижения обошли тех, кто работает над встраиваемыми устройствами. Рынок встраиваемых средств не столь велик, чтобы привлечь тот объем инвестиций, который был вложен в инструментарий для настольных, серверных и облачных приложений. Появление «интеллектуальных устройств» всех видов меняет эту ситуацию.

Благодаря .NET Micro Framework появились новые линейки продуктов, включая малые устройства, которые раньше требовали для разработки кода совершенно других навыков. Теперь код для них могут писать группы и индивидуальные лица, обладающие познаниями в .NET. Если вы .NET-разработчик и задумывались о том, как задействовать малые встраиваемые устройства в своих приложениях, то, надеюсь, эта статья убедит вас, что вы сможете использовать имеющиеся у вас знания, чтобы принять участие в программировании Интернета вещей (Internet of Things, IoT) и интеллектуальных устройств, количество которых растет взрывными темпами.

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

А нам не все равно? Пожалуй, нет. В одном из недавних аналитических обзоров утверждалось, что примерно 94% процессоров, которые, как ожидается, будут поставляться в 2017 году, не будут обладать достаточными мощностями для поддержки традиционных сред .NET-приложений. С появлением .NET Micro Framework вы можете расширить рынок для своих программ.

.NET Micro Framework изначально была разработана по проекту SPOT. Последние семь лет она была частью семейства инфраструктур .NET. Она выполняется на 32-разрядных процессорах слишком маломощных, чтобы поддерживать полноценные операционные системы. На практике это .NET, работающая непосредственно на аппаратном обеспечении с механизмом выполнения и системой типов, интегрированными в исполняемый образ.

Цель .NET Micro Framework — помочь .NET-разработчикам в создании встраиваемых приложений, способных работать на малых 32-разрядных устройствах на основе MCU. На конференции Build 2014 Microsoft описала спектр операционных платформ, охватывающих пространство IoT, где Windows Embedded Standard располагается в верхней части спектра, а .NET Micro Framework — в нижней (для малых устройств).

Разработка встраиваемого ПО

Интеллектуальные устройства имеют собственные вычислительные возможности и способны взаимодействовать с другими устройствами и потенциально с облаком. Для этой статьи я создал небольшого мобильного робота, управлять которым можно со смартфона под управлением Windows Phone. Цель — показать, как познания в области .NET, используемые для разработки приложений Windows Phone, равно применимы на стороне робота. Инструментарий и языковая поддержка новы в этой среде, а среда разработки обеспечивает бесшовное переключение между двумя платформами.

Знакомьтесь с Bert — это мобильный робот с четырьмя управляемыми колесами (рис. 1). В нем установлена электронная плата Netduino 2, доступная примерно за $35 от Secret Labs. Простой контроллер позволяет управлять двигателями на каждой стороне робота, чтобы он мог ездить вперед и назад. Однако управление скоростью не предусмотрено.

Робот Bert
Рис. 1. Робот Bert

Для связи в Bert имеется модуль Bluetooth, который взаимодействует с Netduino по последовательному интерфейсу. Чтобы не разбить Bert обо что-то или чтобы он не съехал с обрыва, спереди и сзади робот оборудован ИК-датчиками близости препятствий. Кроме того, имеются передние фары и поворотные сигналы просто для забавы.

Простое приложение для Windows Phone является производным от демонстрационной программы, представленной на конференции Build. Оно подключается к нужному устройству и использует встроенный в электронную плату акселерометр, чтобы Bert объезжал препятствия, посылая команды по Bluetooth. Вы можете увидеть интерфейс этого приложения на рис. 2 и раскрывающийся список для выбора команд на рис. 3. Выберите Enumerate, чтобы указать подключаемое устройство, которому вы хотите посылать команды. Команды отражаются на экране как буквы, задающие направление.

Интерфейс приложения Windows Phone
Рис. 2. Интерфейс приложения Windows Phone

Раскрывающийся список выбора устройства
Рис. 3. Раскрывающийся список выбора устройства

Вы можете портировать .NET Micro Framework на другую аппаратную платформу с помощью .NET Micro Framework Porting Kit (bit.ly/1wp57qm). Используйте этот набор для написания низкоуровневых интерфейсов для специфического аппаратного обеспечения, с которым вы работаете. Это уже ближе к классическому программированию встраиваемого ПО. Хорошая новость в том, что поставщики уже сделали это за вас. Плата Netduino, задействованная в этом приложении, является одним из таких примеров: у вас есть все, что нужно, чтобы приступить к кодированию платы в Netduino SDK (bit.ly/1CQygzz).

Netduino основана на процессоре Cortex-M3 от STMicro, имеет от 192 до 384 Кб флеш-памяти и от 60 до 100 Кб оперативной памяти и совместима по разъемам с картами расширения (shields) Arduino. Вы можете найти другие устройства, поддерживающие .NET Micro Framework, в GHI Electronics, Mountaineer, Sparkfun, Adafruit, Amazon и других магазинах.

Эта электронная плата также является открытой программно-аппаратной платформой, поэтому, написав свое приложение и пожелав ввести его в коммерческое использование, вы можете выбрать из нескольких вариантов. Для приложений с малой аудиторией можно просто использовать плату Netduino, но, если вы ориентируетесь на более широкую аудиторию или у вас есть специфические требования вроде необходимости интегрировать дополнительную электронику на ту же электронную плату, вы можете передать файлы с открытым проектом производителю платы и действовать дальше на основе его решения.

Поскольку я взял плату Netduino, я установил Netduino SDK. Он включает .NET Micro Framework SDK с шаблонами Visual Studio и поддержкой всех необходимых библиотек. Для других программируемых плат вам может понадобиться установить .NET Micro Framework SDK отдельно. Этот SDK включает эмулятор, поэтому вам не потребуется какое-либо аппаратное обеспечение для экспериментов с .NET Micro Framework, хотя использование реального аппаратного обеспечения продуктивнее, если вы уже знаете, с какими датчиками вы будете работать.

Создание встраиваемого приложения

После установки Netduino SDK (который содержит .NET Micro Framework SDK) создание встраиваемого приложения .NET Micro Framework начинается так же, как и в любом другом проекте Visual Studio. Вы выбираете New Project и тип нужного вам приложения. Как показано на рис. 4, я выбрал Netduino 2 Application, соответствующее плате, установленной в Bert.

Выбор встраиваемого приложения .NET Micro Framework
Рис. 4. Выбор встраиваемого приложения .NET Micro Framework

Создав проект, вы можете перейти непосредственно к созданию коммуникационного канала между роботом и смартфоном.

Как и многие встраиваемые приложения, Bert работает на аккумуляторах. То есть вы должны писать код в расчете на экономное использование электроэнергии. Хорошая новость в том, что .NET Framework и .NET Micro Framework отлично подходят для этого. Если нет потока, который нужно выполнять, .NET Micro Framework может автоматически переводить процессор в состояние с пониженными энергопотреблением. Кроме того, все чаще добавляют второй экономичный процессор для отслеживания прерываний и перевода основного процессора в состояние с еще более низким энергопотреблением. Вскоре вы увидите, годится ли .NET Framework для программирования такого типа.

Код в этом приложении выполняется в ответ на внешнее событие и делает только то, что необходимо для реакции на это событие. Поэтому весь исполняемый код находится в обработчике события или в потоке, который большую часть времени пребывает в приостановленном состоянии:

public class Program
  {
    public static void Main()
    {
      RunRobot myRunRobot = new RunRobot();
      myRunRobot.Start();
      while (true)
      {
        Thread.Sleep(Timeout.Infinite);
      }
    }
  }

Конструктор RunRobot инициализирует экземпляры средств ввода-вывода, которые я рассмотрю подробнее чуть позже, а метод RunRobot.Start — прерывания, которые инициируют реальное выполнение:

public void Start()
  {
  // Разрешаем прерывания ввода по BT в радиоприемнике HC-06
  hc06.DataReceived += hc06_DataReceived;
  // Используем кнопку на плате
  // для включения/выключения приема команд
  button = new InterruptPort(Pins.ONBOARD_SW1, false,
    Port.ResistorMode.Disabled,
    Port.InterruptMode.InterruptEdgeHigh);
  // Начинаем отслеживать нажатия кнопки
  button.OnInterrupt +=
    new NativeEventHandler(button_OnInterrupt);
  }

Работа с Bluetooth

Подготовка Bluetooth-соединения между Bert и приложением Windows Phone состоит из трех операций.

  1. Подключаем модуль Bluetooth к роботу.
  2. Посылаем команды из приложения Windows Phone.
  3. Принимаем эти команды на Bert.

Поскольку Netduino совместима с Arduino, для многих видов связи можно найти плату расширения, которая обеспечит поддержку необходимых вам соединений. Arduino — популярная среди любителей электроники платформа, имеющая богатую экосистему периферийных устройств. Вы можете изготовить широкий диапазон аппаратных решений из существующих модулей.

Если вы не хотите тратить время на подключение, посмотрите на продукты Gadgeteer от GHI Electronics. В случае этих плат и компонентов вы сможете использовать мастер, который поможет решить, куда вставлять компоненты для получения стандартных соединений (рис. 5), поэтому вам не потребуется никаких познаний в области связи. Интерфейсы модулей находятся на сходном высоком уровне. Как и Arduino, Gadgeteer имеет богатый набор существующих модулей, с помощью которых вы создаете свое решение. Подключив необходимые модули, вы по-прежнему кодируете в .NET Micro Framework. Это особенно полезно для быстрого создания концептуальных прототипов.

Мастер Gadgeteer показывает соединения
Рис. 5. Мастер Gadgeteer показывает соединения

Код в этом приложении выполняется в ответ на внешнее событие и делает только то, что необходимо для реакции на это событие.

В случае Bert я не использую Gadgeteer, а собираю свои модули. Модуль Bluetooth (HC-06) имеет последовательный интерфейс с четырьмя соединениями: VIN, GND, RX и TX. Соедините VIN (Voltage In) с выводом 5 В или 3,3 В от Netduino, GND подключите к одному из GND-соединений. Глядя на схему ввода-вывода для Netduino на рис. 6, вы увидите, что RX (Receive) модуля BT соединен с Netduino TX (Transmit), а TX модуля BT — с Netduino RX в последовательном порту COM1. При необходимости в Интернете можно посмотреть ряд примеров соединения этих модулей к распространенным микроконтроллерам.

Определение контактов ввода-вывода Netduino
Рис. 6. Определение контактов ввода-вывода Netduino

Соединив нужные контакты, можно включить Netduino (питание подается и на модуль BT) и связать устройство со смартфоном. По умолчанию модуль BT называется HC-06, так что можно использовать это имя. Но я сменил имя на Bert, используя AT-команды. Чтобы сменить имя модуля BT, отправьте массив байтов с символами «AT+NAMEBert». Кроме того, с помощью этого интерфейса можно настроить модуль Bluetooth, включая такие параметры, как скорость передачи данных в бодах (communication baud rate).

Теперь вы можете использовать смартфон для подключения к Bert как к любому другому BT-устройству и посылать команды. Сначала я обращаюсь к встроенному акселерометру и настраиваю разумный интервал отчетов, чтобы не перегрузить работой бедного Bert:

accelerometer = Accelerometer.GetDefault();
if (accelerometer != null)
{
  uint minReportInterval = accelerometer.MinimumReportInterval;
  desiredReportInterval = minReportInterval > 250 ?
    minReportInterval : 250;
  // Такое замедление предотвращает переполнение командами
  accelerometer.ReportInterval = desiredReportInterval;
  // Добавляем событие для показаний акселерометра
  accelerometer.ReadingChanged +=
    new TypedEventHandler<Accelerometer,
    AccelerometerReadingChangedEventArgs>(ReadingChanged);
}

Обработчик события ReadingChanged передает команды, как показано на рис. 7.

Рис. 7. Обработчик событий для передачи команд Bert

AccelerometerReading reading = args.Reading;
if (reading.AccelerationX > .4)  // произвольные уровни,
                                 // задаваемые для упрощения
{
  // Передаем команду Right (вправо)
  if( cmdSent != 'R')   // не посылаем одну команду повторно
  {
    // Обновляем дисплей смартфона
    txtRight.Text = "On";
    txtLeft.Text = " L";
    txtForward.Text = " F";
    txtBack.Text = " B";
    // Посылаем команду
    packet = Encoding.UTF8.GetBytes("R");
    cmdSent = 'R';
    SendData(packet);
  }

Прием и выполнение команд

Теперь нужно продумать прием команд на стороне робота. BT-модуль подключается к первому последовательному порту Netduino. Создайте экземпляр SerialPort и буфер сообщений, как вы делали ьы это в других версиях .NET Framework:

SerialPort hc06;                            // BT-радио
byte[] cmdBuffer = new byte[32]; // входной буфер
                                                   // для приема команд

Затем конфигурируем последовательный порт для коммуникации с модулем Bluetooth (9600 бод по умолчанию), и, хотя я мог бы сбросить это значение с помощью AT-команд, коммуникации не будут интенсивными, чтобы не усложнять программу, поэтому более высокие скорости не нужны:

// Настраиваем радиосвязь по Bluetooth
hc06 = new SerialPort(SerialPorts.COM1, 9600,
  Parity.None, 8, StopBits.One);
hc06.ReadTimeout = 1000;
hc06.Open();

Затем я настраиваю обработчик событий DataReceived, который инициирует большую часть обработки в приложении. Иначе говоря, Bert спит, пока не получит какую-то команду. Процессор работает ровно столько, чтобы привести моторы в правильное состояние, а затем снова засыпает:

// Разрешаем прерывания при вводе по BT
hc06.DataReceived += hc06_DataReceived;

Входные команды выполняются в обработчике событий (рис. 8).

Рис. 8. Входящие команды, приводящие Bert в движение

do
{
  try
  {
    // Читаем по одному байту за раз
    count = hc06.Read(cmdBuffer, 0, 1);
  }
  catch (Exception) { } // просто глотаем исключения
  if (count > 0)
  {
    cmd = (char)cmdBuffer[0];
    executeCmd(cmd);   // немедленно выполняем команду
  }
} while (count > 0);

Никакой код ничем не отличается о того, что вы обычно пишете в настольных приложениях.

Приводим Bert в движение

Контроллер моторов просто требует установить четыре входа в некое логическое состояние, чтобы определить, как вращать колеса. Логика такова:

/*
A2  A1  Мотор 1                             B2  B1  Мотор 2
0     0   Передача блокирована     0    0    Передача блокирована
0     1   По часовой стрелке          0    1    По часовой стрелке
1     0   Против часовой стрелки  1    0    Против часовой стрелки
1     1   Передача блокирована    1    1    Передача блокирована
*/

Как и многие встраиваемые приложения, Bert работает на аккумуляторах. То есть вы должны писать код в расчете на экономное использование электроэнергии.

Для этого я создаю OutputPort и связываю его с одним из цифровых разъемов Netduino, как показано на рис. 6. OutputPort — это уникальный класс в .NET Micro Framework, так как устройства, выполняющие полнофункциональную .NET Framework, обычно не могут адресоваться к индивидуальным цифровым портам ввода-вывода. В .NET Micro Framework есть целый набор новых классов для обработки дополнительных типов ввода-вывода и других задач, уникальных в этой прикладной области, в том числе для управления электропитанием:

// Вывод контроллера моторов
A1 = new OutputPort(Pins.GPIO_PIN_D2, false);
// A – колеса по левой стороне, если смотреть спереди
A2 = new OutputPort(Pins.GPIO_PIN_D3, false);
B1 = new OutputPort(Pins.GPIO_PIN_D4, false);
// B – колеса по правой стороне, если смотреть спереди
B2 = new OutputPort(Pins.GPIO_PIN_D5, false);
Для управления ими вы просто записываете true или false:
switch (cmd)
{
  case 'F':
  {
    Debug.Print("Forward");
    A1.Write(false);   // вперед влево = false/true
    A2.Write(true);
    B1.Write(true);    // вперед вправо = true/false
    B2.Write(false);
    break;
  }

Ездим аккуратно

Я хочу, чтобы Bert не врезался в разные вещи ради его целости, сохранности вещей и сохранения здоровья людей вокруг него, поэтому установил в него ИК-датчики близости препятствий от Sharp — спереди и сзади. Эти датчики возвращают значение от 0.0 до 1.0 в зависимости от расстояния до ближайшего объекта, который отражает излучаемый ИК-сигнал.

Передний датчик смотрит диагонально вниз, распознавая поверхность примерно на 18 дюймов перед Bert. Это позволяет мне использовать один датчик для обнаружения объектов, а также избежать падения с поверхности, если он, например, приближается к лестнице. Значения, возвращаемые этими датчиками, являются аналоговыми, а значит, я создаю экземпляр другого класса, уникального для .NET Micro Framework, а именно AnalogInput:

AnalogInput foreRange;   // ввод диапазона переднего дальномера
AnalogInput backRange;   // ввод диапазона заднего дальномера
// Задаем диапазоны дальномеров,
// чтобы избегать столкновений и падений
foreRange = new AnalogInput(
  Cpu.AnalogChannel.ANALOG_5, 100, 0, -1);
backRange = new AnalogInput(
  Cpu.AnalogChannel.ANALOG_4, 100, 0, -1);

Этот конструктор идентифицирует специфический аналоговый порт, к которому я подключаюсь, множитель, используемый для преобразования вывода в более удобный диапазон, смещение, на которое модифицируется вывод для удобства и точность вывода, где –1 означает максимальную точность. Чтобы периодически выполнять эти измерения и позволить процессору находиться в спящем состоянии как можно дольше, показания считываются по таймеру. Я устанавливаю его, когда начинается прием команд со смартфона, и удаляю, когда команд нет:

// Запуск таймера для rangeFinders
Timer rangeReader = new Timer(new TimerCallback(
  rangeTimerHandler), null, 0, 100);

Универсальное прерывание

Последний новый класс, с которым я должен вас ознакомить, — InterruptPort. Он позволяет отслеживать изменения в цифровом вводе и реагировать на изменения, например на передний фронт изменения из Low в High. Я использую это для кнопки на плате Netduino, которая заставляет Bert реагировать на команды со смартфона. То есть он игнорирует команды, пока эта кнопка не нажата, а при повторном ее нажатии он вновь игнорирует команды:

// Используем кнопку на плате
// для включения/выключения приема команд
button = new InterruptPort(Pins.ONBOARD_SW1, false,
  Port.ResistorMode.Disabled,
  Port.InterruptMode.InterruptEdgeHigh);

Pins.ONBOARD_SW1 — это внутреннее соединение для включателя платы Netduino. Вы можете соединить включатель с любым цифровым портом, перечисленным на рис. 6. Второй аргумент указывает, нужен ли мне глитч-фильтр (glitch filter), применяемый к этому вводу включения, чтобы избежать многократного срабатывания при одном нажатии кнопки.

Следующий параметр задает, какой резистор установлен на включателе — повышающий (pull up) или понижающий (pull down). Это определяет позицию порта по умолчанию, когда кнопка не нажата (High или Low). Последний параметр указывает инициировать прерывание на переходе обратно к High, если Bert реагирует немедленно. Создав экземпляр InterruptPort, можно назначить обработчик прерывания:

// Начинаем отслеживать нажатия кнопки
button.OnInterrupt += new NativeEventHandler( button_OnInterrupt);

Обработчик прерывания заставляет Bert начать отслеживать любые команды, поступающие со смартфона (рис. 9).

Развертывание кода на вашем устройстве не сложнее его подключения и нажатия клавиши F5.

Рис. 9. Обработчик прерывания, активирующий мониторинг команд

private void button_OnInterrupt(
  uint data1, uint data2, DateTime time)
{
  cmdListenState = !cmdListenState;
  if (cmdListenState)
  {
    // Устанавливаем таймер для rangeFinders
    rangeReader = new Timer(new TimerCallback(
      rangeTimerHandler), null, 0, 100);
  }
  else
  {
    rangeReader.Dispose(); // удаляем таймер, так как Bert
                           // не обрабатывает команды,
                           // а значит, он не должен двигаться
  }
  led.Write(cmdListenState);  // встроенный LED указывает,
                              // принимает ли Bert команды
}

Встраиваемые приложения и .NET Micro Framework

Встраиваемые приложения обычно выполняют набор функций, ориентированный на аппаратное обеспечение и рассчитанный на минимальные требования. Создание таких тонко оптимизированных встраиваемых приложений требует более высоких начальных вложений. И они окупаются при более длительном жизненном цикле продукта.

Одна из самых трудных задач в традиционной разработке встраиваемого ПО — время, уходящее на выполнение проектов. Немалая доля таких проектов закрывается, потому что затраты на них становятся слишком велики или требования меняются до того, как проекты удается вывести на рынок.

На динамику встраиваемых приложений влияет ряд факторов. Когда Microsoft семь лет назад впервые выпустила .NET Micro Framework, большинство встраиваемых приложений создавались на 8-разрядных процессорах для уменьшения стоимости, реализации необходимых требований к производительности и энергопотреблению (например, возможность длительной работы на аккумуляторах).

В то же время основной рост в области встраиваемых приложений наблюдается в том сегменте, который ориентирован на 32-разрядные процессоры вроде ARM7. Эти процессоры постоянно дешевеют и предлагают адекватную производительность для многих приложений; кроме того, улучшается ситуация с энергопотреблением. Более новые процессоры Cortex продолжают перетягивать многие новые встраиваемые приложения на семейство 32-разрядных процессоров.

Не так давно было больше устройств, которые являются неотъемлемой частью более широких приложений, включая встраиваемые устройства, шлюзы, поддержку соединений с облаком, базы данных, приложения бизнес-анализа и т. д. Эти новые области применения меняют экономику встраиваемых приложений.

Становится все важнее придерживаться стандартных коммуникационных протоколов. Большая часть этих новых устройств относится к потребительскому сегменту, поэтому длительные циклы разработки сопряжены с более высоким риском. Время выхода на рынок для этих приложений еще важнее, чем для остальных, особенно учитывая взрывной рост «интеллектуальных устройств».

Сама широта охвата этих новых типов приложений является еще одним важным фактором. Потенциально они объединяют в одном лице разработчика настольных приложений с его знаниями в областях крупномасштабных коммуникаций, баз данных и бизнес-аналитики, а также облачных протоколов и разработчика встраиваемых программно-аппаратных средств с его знаниями аппаратного обеспечения и низкоуровневого программирования. Инструментарий и языки помогают использовать те же навыки в рамках целых приложений и тем самым способствуют повышению эффективности проектов.

Именно на этом фоне и была разработана .NET Micro Framework. Основы этой платформы создавались как внутренние инструменты для разработки контрольных приложений Microsoft SPOT. Когда платформа стала полезной для других внутренних проектов, продукт приобрел завершенный вид и был выпущен как универсальная платформа в 2007 г.

Факторы, связанные со стоимостью, производительностью и экономичностью встраиваемых приложений, никуда не делись. Если уж на то пошло, то, когда речь заходит о приложениях, где нужно развертывать тысячи датчиков в каком-то здании, фактор стоимости становится еще критичнее. Факторы производительности и экономичности тоже зависят от масштабов применения. Курс на расширение областей применения, которые могут быть охвачены .NET Micro Framework, по-прежнему остается в центре внимания Microsoft.

Развертывание и отладка

Развертывание кода на вашем устройстве не сложнее его подключения и нажатия клавиши F5, как и в случае приложения Windows Phone. Однако настройка немного отличается. В диалоге Project | Properties есть вкладка .NET Micro Framework, где можно указать транспорт (USB, последовательный порт или TCP/IP) и идентифицировать устройство. По умолчанию выбирается USB. При этом устройство .NET Micro Framework идентифицируется автоматически, поэтому, если только у вас нет подключений к нескольким устройствам, данное диалоговое окно вам скорее всего вообще не понадобится. К этому моменту решение скомпилировано и сборки развернуты на устройстве. Вы можете наблюдать за всеми процессами в окне Output в Visual Studio. Выполнение начинается немедленно, и вы можете запустить отладку кода, выполняемого на устройстве.

Кроме того, вы можете развернуть приложение в эмуляторе, выполняемом на настольном ПК. Разница в том, что Windows Phone имеет сравнительно ограниченное количество комбинаций, поэтому вы можете выбрать ближайший подходящий эмулятор из набора, предоставляемого Visual Studio. Для .NET Micro Framework предусмотрен лишь базовый эмулятор Microsoft. Скорее всего вам придется создать собственный эмулятор, который подходит вашему аппаратному обеспечению. Это определенно стоит рассмотреть, если вы хотите приступить к кодированию до того, как у вас появится нужное аппаратное обеспечение.

В прошлом сценарий отладки коммуникации между роботом и приложением Windows Phone можно было бы реализовать с помощью отладчика JTAG. Он отделен от среды разработки и незнаком .NET-разработчику, поэтому, возможно, один разработчик следит, что происходит в Windows Phone, а другой наблюдает (используя иной инструментарий), что делается на встраиваемом устройстве. Но вы можете отслеживать оба устройства одновременно в Visual Studio. У вас есть возможность пошагово выполнять код на смартфоне и прерывать его при передаче команды, а затем входить в код, выполняемый в Bert при приеме этой команды.

Заключение

Полное описание того, как создавать любое значительное встраиваемое приложение в .NET Micro Framework, потребовало бы целой книги. Целью этой статьи было продемонстрировать тот факт, что обучение не потребует слишком больших усилий и что вы сможете использовать ваши знания .NET в создании встраиваемых приложений на основе .NET Micro Framework.

Этот проект потребовал нескольких классов, не входящих в полнофункциональную .NET. Кроме того, некоторые вещи, с которыми вы знакомы по полнофункциональной .NET Framework, нельзя втиснуть в .NET Micro Framework, но среда Visual Studio полностью поддерживается IntelliSense, точками прерывания, контрольными точками, стеком вызовов и другими инструментами, к которым вы привыкли. Конечно, существуют встраиваемые приложения, для которых .NET Micro Framework не является правильным выбором. Но для многих он работает весьма хорошо.

Итак, теперь вы готовы попробовать себя в роли программиста встраиваемых приложений.


Colin Miller - главный менеджер программ в группе Internet of Things в Microsoft. Работает в Microsoft около 20 лет, занимался такими проектами, как Internet of Things, Embedded, Developer Tools, Research, MSN, Internet Explorer, Word и др. С ним можно связаться по адресу colin.miller@microsoft.com.

Выражаю благодарность за рецензирование статьи эксперту Microsoft Лоренцу Тессиоре (Lorenzo Tessiore).