Опубликован: 24.04.2009 | Уровень: специалист | Доступ: платный
Лекция 8:

Программирование приложений в CE

Управляемый код и собственный код

Разработчики встроенных систем встречаются с проблемой выбора при разработке приложений для встроенных устройств в Windows Embedded CE. Выбор состоит в использовании управляемого кода и/или собственного (неуправляемого) кода. Собственный код использует C/C++, как было в предыдущих примерах программ. В собственном коде процедуры компилируются непосредственно в машинный код целевого устройства.

Управляемый код использует новый язык C# (произносится Си-шарп) или также Visual Basic.NET. Мы сконцентрируем здесь наше обсуждение и примеры на C#. C# компилируется в промежуточный байт-код, называемый Общим промежуточным языком (Common Intermediate Language -- CIL). Во время выполнения динамический процесс компиляции транслирует CIL в собственные инструкции, которые кэшируются. Это означает, что когда кэшированный код вызывается в следующий раз, будут выполняться непосредственно собственные инструкции, а повторная интерпретация CIL выполняется не будет. .NET Compact Framework выполняет код CLI в защищенной среде поверх Windows Embedded CE. Общая среда выполнения языка (CLR) и Framework Class Library (FCL) предоставляют слой полезных промежуточных функций для программистов, которые недоступны в C/C++.

Те читатели, которые уже знакомы с Java, увидят много сходства в синтаксисе Java и C#, CIL и байт-коде Java, и Виртуальной машине Java (JVM) и .NET Compact Framework.

С# предлагает разработчикам несколько преимуществ относительно C/C++. Программисты приложений C# являются более продуктивными, особенно при разработке сложных графических и сетевых приложений. С# предоставляет слой промежуточного программного обеспечения в тех прикладных областях, которые позволяют программистам работать на более высоком уровне абстракции, чем C/C++. C# включает встроенные средства языка для потоков и синхронизации (как в Java). C# создает также более безопасный код в том смысле, что выполняется больше проверок во время выполнения, чем в C/C++. Во время выполнения проверяются границы массивов и типы данных, и в C# не допускаются прямые манипуляции с указателями (как в Java). Другое преимущество состоит в том, что требуется только одна версия исполняемого кода CIL программы C# для поддержки приложения на различных типах процессоров, выполняющихся на различных аппаратных платформах.

Недостатками C# являются влияние на использование памяти и производительность. Среда .NET Compact Framework, которая требуется для поддержки C# увеличивает размер ядра CE на несколько мегабайтов. Динамическая компиляция с проверкой во время выполнения работает медленнее, чем собственный код C/C++. Периодически должны выполняться процедуры сборки мусора для восстановления памяти из брошенных объектов кучи, и возможно даже удаления некоторого кода из кэша кода. Во время сборки мусора все потоки должны приостанавливаться, и это может иметь отрицательное влияние на производительность системы в реальном времени. В настольной системе с избытком памяти и быстрыми процессорами, это не имеет большого значения, если сравнивать с небольшим встроенным устройством с ограниченной памятью и более медленными процессорами. Дизайнерам потребуется тщательно оценить достоинства и недостатки при выборе языка в конкретной ситуации.

Пример программы C# Hello World

Теперь рассмотрим кратко код простого консольного приложения C#. C# использует пространства имен. Пространства имен предотвращают конфликты имен между независимо созданными классами. Первая строка "using System" позволяет компилятору проверить ссылки в пространстве имен System. Так находится Console.WriteLine. Без "using System" ссылка должна записываться в виде System.Console.WriteLine. Допускается использование нескольких операторов using. Console.WriteLine выводит строковый аргумент в окне консоли (также как функция C/C++ printf) . Console.Readline считывает вводимые на клавиатуре символы. Это приложение печатает заголовок и приглашение на консоли. Затем оно продолжает читать строки, вводимые на клавиатуре, пока не будет введена строка "quit".

using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Threading;

namespace Hello_CS_World
{
    class Program
    {
      static void Main(string[] args)
       {
        bool _continue = true ;
        string message;
        StringComparer stringComparer=StringComparer.OrdinalIgnoreCase
// Выводит заголовок и строку приглашения на консоли 
        Console.WriteLine("Hello C# World");
        Console.WriteLine ("Type QUIT to Exit");

// Цикл считывания строк с клавиатуры, 
// пока пользователь не введет "quit"
            while (_continue)
            {
                message = Console.ReadLine();
                if (stringComparer.Equals("quit", message))
                {
                    _continue = false;
                }
            }   
        }
    }
}

Как было сделано в предыдущем уроке о C#, описанном в "Создание настройки ядра CE 6.0" в разделе 7.7, программы C#, которые создает Windows, почти всегда создаются с помощью дизайнера приложений Visual Studio, который имеет графические инструменты проектирования, которые автоматически создают код для приложения Windows Forms. Код обработчика событий для ответа на каждое событие затем добавляется разработчиком вручную. События C# аналогичны сообщениям C/C++ Windows. Существуют многочисленные книги, которые посвящены более подробному рассмотрению инструментам разработки программного обеспечения C#.

Пример программы C# с последовательным портом

В C# можно использовать элемент управления SerialPort для отправки и получения данных из последовательного порта, такого как COM1: и COM2: на eBox. По умолчанию используется COM1: на скорости 9600 бод, с 8 битами данных, без контроля четности, с одним стоп битом, и без квитирования. Не забудьте установить SP2 для .NET Compact Framework 2.0 прежде чем использовать SerialPort, и проверьте, что все другие программы, которые могли бы использовать последовательный порт, его не используют (т.е., сообщения последовательного отладчика CE, ActiveSync, KITL). Ниже показан пример C#, который печатает "Hello CS Serial World" на COM1:.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
namespace Hello_CS_Serial_World
{
    class Program
    {
        static void Main(string[] args)
        {
        SerialPort _serialPort;
        // Создаем новый объект SerialPort с требуемыми настройками.
        _serialPort = new SerialPort();
        //По умолчанию ("COM1", 9600, Parity.None, 8, StopBits.One)    
        _serialPort.Open();
        _serialPort.WriteLine("Hello CS Serial World");
        _serialPort.Close();
        }
    }
}

Примеры программ и драйверы Phidget USB

Phidgets являются семейством дешевых внешних устройств В/В на основе USB. Модули Phidgets поддерживают как аналоговый, так и цифровой В/В. Для Phidgets доступен широкий набор датчиков и интерфейсов. Один из наиболее популярных модулей Phidgets показан на рисунке 8.9. Этот модуль содержит дисплей LCD 20 на 2 символов и модули цифрового и аналогового интерфейса на задней стороне платы. Он поддерживает 8 цифровых входов и 8 цифровых выходов. Цифровой В/В соединяется с винтовыми терминальными блоками сзади платы. 8 входов модулей аналоговых датчиков можно соединить с платой. Каждый модуль аналогового датчика соединяется с помощью специальных 3-контактных разъемов (5V питание, аналоговый сигнал, и земля). При использовании стандартных драйверов частота дискретизации может составлять от 50 до 125 сэмплов в секунду.

Это устройство Phidget USB содержит LCD и цифровые и аналоговые контакты В/В

Рис. 8.9. Это устройство Phidget USB содержит LCD и цифровые и аналоговые контакты В/В

Для использования Phidgets на целевом оборудовании eBox 2300, необходимо установить в ядро ОС пять файлов драйверов устройств Phidget CE 6.0, и добавить соответствующие записи реестра. Когда драйверы будут установлены, будут доступны вызовы API Phidgets, которые могут использоваться в приложениях C/C++ и C#.

Несколько руководств по API драйверов и примеры приложений доступны на Web-сайте Phidget в области загрузки (www.phidgets.com). Полный исходный код драйвера устройства Phidgets доступен как проект общедоступного исходного кода CE.

Чтобы упростить установку драйвера, был разработан подпроект PhidgetsDrivers CE 6.02. Подпроект не перекомпилирует все драйверы, скорее он просто копирует двоичные файлы в каталог выпуска, задает необходимые записи реестра, и создает файл *.bib для включения драйверов в ядро ОС. Инструмент CEFileWiz3 будет полезен для начального создания файлов для подпроектов, таких как PhidgetsDrivers.

Чтобы включить драйвер Phidgets в новое ядро ОС, чтобы прикладные программы могли использовать Phidgets, скопируйте весь каталог PhidgetsDrivers в каталог проекта OSDesigns, который содержит каталоги подпроектов (т.е., используемым по умолчанию местоположением будет WINCE600\OSDESIGNS\MyOSProject\MyOSProject ). Так как файл poslink.bat просто копирует файлы, каталог подпроекта должен быть в правильном местоположении, и он должен также называться PhidgetsDrivers.

После копирования каталога PhidgetsDrivers, выберите Subprojects в представлении решения, сделайте щелчок правой кнопкой мыши, выберите добавить существующий подпроект, и выберите PhidgetsDrivers.pbpxml. Через несколько секунд должен появится новый подпроект PhidgetsDrivers.

Сделайте щелчок правой кнопкой мыши на подпроекте PhidgetsDrivers и выберите Build. Новый подпроект PhidgetsDrivers должен теперь собраться без ошибок. Если каталог копируется в неправильное местоположение или записывается с ошибкой, в сборке появится файл postlink.bat копирования ошибок. Проверьте все обновления драйверов Phidgets для CE 6.0 на Web-сайте Phidgets. Новые двоичные файлы драйверов можно скопировать в существующий каталог подпроекта в \target\X86 в каталоги выпуска и отладки.

Когда драйверы установлены правильно, то при выполнении нового образа времени выполнения ОС, когда какое-либо устройство USB Phidget подключено к eBox, устройство должно перечислить и загрузить соответствующий драйвер автоматически. Также в окне вывода отладки появится последовательность, связанных с USB сообщений. Если новое устройство USB неизвестно (т.е., драйвер Phidgets установлен неправильно), появится диалоговое окно, предлагающее пользователю ввести имя драйвера для нового устройства USB.

Несколько примеров демонстрационных приложений C# можно найти в проекте WindowsCE. NET Examples, который поставляется вместе с драйверами. Они могут использоваться для тестирования наиболее распространенных модулей Phidget на правильность работы. Включен полный исходный код приложений. Доступен также файл проекта, который можно использовать для сборки демонстрационных приложений Phidget. После сборки приложений, их можно развернуть на eBox и выполнить. В примере решения WindowsCE.NET Phidget представлены следующие приложения C# вместе с драйверами:

  • Контроллер InterfaceKit выводит статус цифрового и аналогового модуля В/В 8/8/8. Цифровые состояния указываются флажком, а значения аналоговых датчиков появляются на ползунковых индикаторах. Удобный способ проверки датчиков.
  • Контроллер TextLCD можно использовать для вывода текста, вводимого в текстовом поле в модуле LCD Phidgets.
  • Phidget Manager выводит имя и тип всех присоединенных модулей Phidgets.
  • Контроллер RFID будет выводить теги RFID, прочитанные в данный момент модулем RFID Phidgets.

Эти демонстрационные приложения C# показаны во время выполнения на eBox на рисунке 8.10. Модули Phidget соединяются с eBox и посылают данные назад на дисплей GUI. Модуль датчика присоединяется к первому аналоговому входу, который выводится на первом ползунковом индикаторе в контроллере интерфейса. Позиция ползункового индикатора указывает относительное значение показателя аналогового напряжения датчика. Phidget LCD выводит "Hello Phidget World", а индикатор RFID показывает значение тега 010230dff3. Отметим, что Phidget Manager обнаружил, что RFID Phidget, Phidget Interface Kit с LCD, и Phidget Servo Controller подключены к портам USB eBox.

Демонстрационные программы Phidget C#, выполняющиеся на eBox с несколькими присоединенными модулями Phidgets

Рис. 8.10. Демонстрационные программы Phidget C#, выполняющиеся на eBox с несколькими присоединенными модулями Phidgets

Чтобы разрабатывать свои собственные приложения C#, изучите эти примеры и загрузите соответствующие руководства интерфейса API Phidgets для получения дополнительной информации.

Для приложений C/C++ Phidgets программы C/C++ нужно будет включить phidget21.h, загрузить драйвер устройства Phidgets, используя LoadLibrary(_T("phidget21.dll")), и используя несколько вызовов функций GetProcAddress для возврата каждой точки входа, необходимой для функций библиотеки Phidgets, так как для компоновки с проектом C++ нет доступной библиотеки phidget21.lib в текущем выпуске драйверов. Для каждой отдельной точки входа API Phidgets, используемой в приложении, требуется вызов функции GetProcAddress. Подпроект PhidgetsLCD4, содержит пример кода C++ использующего эту технику, который выводит текст и данные на модуле Phidgets LCD.

// Пример использования LoadLibrary для загрузки драйвера Phidgets 
hModule = ::LoadLibrary(_T("phidget21.dll"));
	if (hModule == NULL)
		return 0;


// Пример показывающий использование GetProcAddress 
// для каждой точки входа 
	typedef int (__stdcall *Phidget_open)(CPhidgetHandle phid, 
int serialNumber);
Phidget_open open = (Phidget_open)::GetProcAddress(hModule,               _T("CPhidget_open"));

Файлы настройки подпроекта PhidgetsDrivers CE 6.0 были получены из http://www.learningce.com/779.aspx. Файлы драйвера общественного проекта общего исходного кода для Phidgets доступны по адресу http://www.codeplex.com/PhidgetsWinCEDriver. Этот сайт является лучшим местом для комментариев и вопросов. Официальный сайт загрузки продуктов Phidgets может содержать более новые версии последних драйверов CE 6.0 http://www.phidgets.com/modules.php?op=modload&name=Downloads&file=index&req=getit&lid=30.

Проект Panner C# для настройки сервомеханизма Phidgets дистанционного управления с ИК датчиком расстояния, показанный на рисунке 5.23, сканирует ближайший объект5. Угол сервомеханизма выводится на индикаторе LED, а GUI выводит статусную информацию.

Бахтиёр Бутаев
Бахтиёр Бутаев
Таджикистан, Душанбе, Таджикский Технический Университет (ТТУ), 2013
Ярославй Грива
Ярославй Грива
Россия, г. Санкт-Петербург