Проектирование визуальных инструментальных средств для беспроводных сенсорных сетей
Применение разработанного DSM-решения
Введение
В настоящее время системы мониторинга и контроля объектов используются в различных областях экономики. Последние достижения в области информационных технологий позволяют создавать всё более совершенные технологии сбора и обработки данных, среди которых выделяется технология беспроводных сенсорных сетей (БСС). Растущий интерес к БСС приводит к необходимости разработки разнообразных приложений для узлов сети. В связи с этим актуальной является задача создания удобных инструментов проектирования и программирования БСС.
В состав БСС входят средства беспроводной связи, вычислительные компоненты и датчики, что делает возможности БСС чрезвычайно гибкими для построения систем мониторинга и контроля состояния объектов. Важным преимуществом данной технологии является возможность автоматического формирования и восстановления структуры сети, что наряду с отсутствием какихлибо физических соединений означает простоту ее внедрения, эксплуатации, обслуживания и модернизации. Однако жесткие ограничения на ресурсы узлов сети делают разработку управляющих программ для БСС весьма непростой задачей. Именно из-за этого многие компании, занимающиеся разработкой приложений для БСС, выпускают целые библиотеки и так называемые платформы, призванные упростить и ускорить процесс разработки. Но даже использование этих средств не позволяет получить готовую управляющую программу без дополнительного программирования, которое существенно отличается от программирования для ПК, во-первых, из-за специфики аппаратной части узлов сети, а во-вторых, из-за ограничений, существующих для энергетических и вычислительных ресурсов БСС.
Для сенсорных узлов сегодня существуют разные программные платформы. В данной статье речь пойдет о разработке управляющих программ с применением операционной системы TinyOS и языка программирования NesC. TinyOS — это первая операционная система (ОС), специально разработанная для БСС. TinyOS — система реального времени с управлением по событиям; отметим, что в ней не используется многопотоковый режим работы. Программы, работающие под управлением TinyOS, содержат обработчики событий и задачи, которые выполняются последовательно, не прерывая друг друга. Компоненты ОС и пользовательские программы создаются при помощи специального языка программирования NesC, который является расширением языка С. Инструментальные средства, применяемые в настоящее время при разработке приложений на NesC, в основном представляют собой текстовые редакторы, которые позволяют осуществлять лишь редактирование исходного кода приложений и не предоставляют тех возможностей, которые широко используются при разработке программного обеспечения для стандартных ПК. И если некоторые из таких возможностей реализуются довольно просто (например, подсветка синтаксиса, компиляция исходного кода из окна редактора), то другие требуют серьезной проработки с применением дополнительного инструментария.
В данной статье рассматривается создание законченного решения — визуального языка для описания структуры приложений БСС и программного средства для работы с ним. Модели, или диаграммы компонентов, построенные с применением этого языка, представляют в графическом виде множество используемых в приложении компонентов, интерфейсов и связей между ними, что должно помочь разработчикам сократить число ошибок, упростить понимание и документирование разрабатываемой системы и ускорить переход от этапа проектирования к реализации. Необходимость в создании новой нотации обусловлена тем, что технологии, применяемые при разработке приложений для БСС, заметно отличаются от технологий разработки программного обеспечения для ПК. Это делает средства моделирования общего назначения, такие как UML, малопригодными в данной предметной области. Основным требованием к нотации является соответствие ее сущностей элементам NesC, позволяющее генерировать код приложений по построенным моделям. Необходимо отметить, что в результате генерируется не весь код приложения, поскольку создаваемая модель способна описывать структуру приложений, но не нюансы их поведения.
Разработка DSM-решения
Разработка модели для конкретной предметной области называется предметноориентированным моделированием (domain specific modeling, DSM), а язык, которым оперирует разработанная модель, — предметноориентированным языком (domain specific language, DSL).
Создание предметноориентированного языка и программного средства для работы с ним, то есть DSM-решения, сегодня не начинается с нуля, а обычно ведется с использованием специального программного пакета, или DSM-платформы. В качестве DSM-платформы для создания языка моделирования приложений для БСС было выбрано средство DSL Tools компании Microsoft. Это средство располагает широкими сервисными возможностями и достаточно надежно (DSL Tools входит в состав пакета Visual Studio 2008 SDK, который применяется как составная часть среды разработки Visual Studio 2008). Отметим, что в качестве DSM-платформы можно взять и любое другое программное средство, например Borland Together или Eclipse/GMF, — принципы останутся неизменными.
Реализация DSM-решения в среде DSL Tools заключается в разработке специального проекта, состоящего из двух частей. Первая часть проекта содержит описание правил предметноориентированного языка. Во второй части определяется внешний вид пользовательского интерфейса редактора, предназначенного для работы с конструкциями предметноориентированного языка. Разработанный проект компилируется, и создается новый экземпляр среды разработки Visual Studio с интегрированными средствами для работы с предметноориентированным языком.
Выделим основные этапы создания решения: анализ структуры приложения NesC, формирование метамодели языка, создание нотации языка, разработка средств интеграции модели в редактор Visual Studio, разработка генератора исходного кода по построенным моделям.
Язык NesC
NesC (network embedded system C) — это компонентноориентированный язык программирования, построенный на базе языка программирования С. Основной структурной единицей программы на NesC является компонент, который через интерфейсы взаимодействует с другими компонентами. Каждый компонент или интерфейс помещается в отдельный файл. Интерфейсы могут содержать объявления команд и событий. Реализации команд должны быть описаны в компоненте-провайдере, а реализации обработчиков, объявленных в интерфейсе событий, — в компоненте-пользователе. Компоненты в NesC бывают двух типов: модули и конфигураторы. Модуль описывает действующие механизмы компонента: команды, которые он предоставляет, и обработчики событий. Конфигураторы задают связи между интерфейсами других компонентов, а также могут предоставлять свои интерфейсы.
Описание любого компонента в NesC, будь то конфигуратор или модуль, состоит из двух секций: интерфейсной и секции реализации. Интерфейсная секция компонента содержит объявления команд, событий и интерфейсов, то есть функций, которые использует или предоставляет компонент. Если компонент использует функцию, на это указывает зарезервированное слово uses, если предоставляет — provides. Интерфейсная секция может быть пустой или содержать объявления только используемых либо только предоставляемых функций. Взаимодействие с другими компонентами осуществляется через объявленные функции.
Поскольку разрабатываемый DSL в основном ориентирован на описание структуры NesC-приложений, приведенных выше сведений вполне достаточно. При разработке языка потребуются только синтаксические конструкции, применяемые при написании интерфейсов, компонентовконфигураторов и интерфейсных секций компонентовмодулей. Для создания абстрактного синтаксиса визуального языка удобно воспользоваться спецификацией NesC, записанной в БНФ.
Метамодель
Подобно тому как абстрактный синтаксис текстового языка описывается с помощью специальных текстовых конструкций, например БНФ, правила визуального языка обычно задаются в виде метамодели. Для этой цели в DSM-платформе предусмотрен специальный редактор классов, позволяющий создавать классы сущностей предметной области и описывать отношения между ними. При помощи этого редактора была описана структура, определяющая правила написания приложений на языке NesC. Получившаяся метамодель представлена на рис. 1.
Рис. 1. Метамодель языка NesC
Корневым элементом является класс NesCModel, который представляет собой конкретную модель (диаграмму) на разрабатываемом DSL. При разработке метамодели главной задачей было как можно точнее отразить сущности языка программирования NesC и связи между ними, что позволит реализовать генерацию исходного кода по модели. Таким образом, в качестве базового элемента был выделен «файл», поскольку именно он является самой общей сущностью, которая включает остальные. Однако непосредственно в языке NesC «файл» не несет никакой смысловой нагрузки, поэтому в метамодели он является абстрактным классом. Дочерние классы Interface и Component отвечают за более низкую детализацию файлов, выделяя файлы компонентов и интерфейсов. Объявления каждого интерфейса могут содержать наборы команд и событий, что и реализуется при помощи связей InterfaceHasCommands и InterfaceHasEvent соответственно. Здесь стоит обратить внимание на множественность этих связей. В соответствии с ними каждый интерфейс может содержать несколько команд или событий, однако каждое событие или команда принадлежит только к одному интерфейсу. Отметим, что у класса интерфейсов есть дополнительный атрибут VisibleOnDiagram, помогающий контролировать, отображается данный интерфейс на диаграмме или нет. Возможность скрывать некоторые интерфейсы позволяет разгрузить слишком сложные диаграммы, так как в программах на языке NesC, как правило, используется большое количество интерфейсов.
Дальнейшая детализация класса Component приводит к классам Module и Configuration, которые соответствуют реальным файлам компонента-модуля и компонента-конфигуратора. Объекты именно этих классов будут созданы, если пользователь модели добавит на диаграмму соответствующий компонент. Для второго типа файлов предусмотрена возможность подключения компонентов (связь ConfigurationUsesComponents). Назначение этой связи в том, чтобы указать конфигуратору, какими компонентами он оперирует, — в дальнейшем это понадобится для описания секции реализации компонента-конфигуратора.
Нотация языка
После представления абстрактного синтаксиса языка в виде метамодели необходимо описать его нотацию (или конкретный синтаксис), а также сопоставить элементам метамодели соответствующие элементы нотации, то есть определить отображение сущностей языка NesC в окне редактора модели. Для решения этих задач были разработаны специальные классы (рис. 2), каждый из которых описывает правила визуализации определенной сущности языка. Для более наглядного представления диаграммы используются разные виды фигур. Например, с помощью сложной фигуры с отделами (рис. 3) реализовано отображение таких классов метамодели, как Interface, Module и Configuration. Наряду с геометрическими фигурами, которые нужны для отображения понятий предметной области, в нотации были описаны соединительные линии, которые требуются для отображения связей между понятиями.
Рис. 2. Диаграмма классов, описывающих нотацию языка
ab
Рис. 3. Фигуры с отделами: а — модуль; б — интерфейс
Помимо описанных элементов нотации, в языке предусмотрена возможность управления видимостью интерфейсов на диаграмме при помощи их свойств. Специально разработанные процедуры позволяют пользователю скрывать интерфейсы с диаграммы, не удаляя их из модели, например если они необходимы для генерации исходного кода.
В результате выделим основные элементы нотации разработанного графического DSL:
- комментарий — прямоугольник с текстом комментария;
- интерфейс — прямоугольник с отделами Commands и Events для вывода на экран списка объявленных в интерфейсе команд и событий;
- компонентконфигуратор — скругленный прямоугольник с отделами Uses и Provides для отображения используемых и предоставляемых интерфейсов;
- компонентмодуль — скругленный прямоугольник с отделами Uses и Provides для отображения используемых и предоставляемых интерфейсов;
- линия, соединяющая сущность с комментарием, — сплошная линия без стрелок;
- линия, соединяющая компонентпровайдер с интерфейсом, — пунктирная линия с треугольной стрелкой на конце;
- линия, соединяющая компонентпользователь с интерфейсом, — пунктирная линия со стрелкой на конце;
- линия, подключающая компоненты к компоненту-конфигуратору, — сплошная линия со стрелкой на конце.
Средства интеграции модели со средой разработки
Для использования разработанного DSL необходим редактор, который позволил бы создавать и управлять сущностями языка. С применением DSM-платформы задача разработки редактора существенно упрощается, так как часть его функциональности реализуется при помощи готовых библиотек и графических инструментов. Подобным образом для разрабатываемого языка описания структуры программ на NesC были спроектированы такие элементы среды разработки, как браузер объектов, окно свойств и панель инструментов.
Браузер объектов (рис. 4а) отображает граф построенной модели и синхронизирован с диаграммой. С его помощью также можно создавать и удалять элементы из модели. Иерархия объектов в браузере точно совпадает с иерархией соответствующих классов в метамодели, которая была описана выше. В браузере объектов отображаются все созданные в модели объекты, даже те, что скрыты на диаграмме или не имеют отображения вообще.
Окно свойств (рис. 4б) служит для отображения и изменения значений свойств объектов модели.
a
b
v
Рис. 4. Элементы редактора: а — браузер объектов; б — окно свойств; в — панель инструментов
Панель инструментов (рис. 4в) содержит объекты, которые пользователь может создавать при работе с диаграммой компонентов NesC. Созданный при помощи панели объект может иметь собственное представление на диаграмме (например, «интерфейс», «компонент»), отображаться в рамках другого объекта (например, «команда» или «событие» отображаются в рамках объекта «интерфейс») или скрыт с диаграммы, но все созданные объекты обязательно можно просмотреть в браузере объектов.
Шаблоны для генерации кода
Для создаваемой диаграммы компонентов задача генерации кода программы на языке программирования NesC ставилась изначально, поэтому на всех этапах ее разработки решению этого вопроса уделялось большое внимание. Только грамотно построенная метамодель позволяет реализовать генерацию безошибочного кода. Особенности метамодели заключаются в том, что она строго отражает специфику и структуру языка программирования NesC, позволяя транслировать каждый блок на диаграмме в определенный фрагмент кода.
В зависимости от используемой платформы существуют разные механизмы генерации кода по построенной модели. После изучения доступных в Microsoft DSL Tools технологий генерации была выбрана технология, основанная на использовании шаблонов (A Template-Based Approach) и хорошо знакомая разработчикам вебприложений на основе ASP (Active Server Pages). Преимущества данной технологии заключаются в ее удобстве для создания и последующего редактирования шаблонов, поскольку код шаблонов является прямым представлением желаемого сгенерированного кода. Кроме того, шаблоны для генерации исходного кода, созданные при помощи шаблонного подхода, доступны пользователю DSL для редактирования, так как по умолчанию он включается платформой в конечный пакет для работы с DSL. Рассмотрим фрагмент шаблона, отвечающий за генерацию кода интерфейсов [1].
Сначала для просмотра всех элементов модели запускается цикл foreach, при помощи которого последовательно перебираются все объектыфайлы, созданные в модели. Иерархия классов в модели имеет общие черты с метамоделью языка и дополнена лишь некоторыми служебными классами. Поскольку класс NesCFile является общим предком для классов Interface и Component, а класс Component, в свою очередь, базовым классом для Module и Configuration (см. рис. 1), то при помощи одного цикла foreach по объектам класса NesCFile можно отобрать объекты остальных классов. Таким образом, приведенный фрагмент генератора кода отбирает из хранилища модели все объекты класса NesCFile и осуществляет проверку полученных объектов. В случае если объект является интерфейсом, осуществляется его обработка в соответствии с приведенным фрагментом: вначале выделяются и отображаются все команды, а затем аналогичная процедура проделывается для событий.
Применение разработанного DSM-решения
После выполнения описанных выше этапов, дополнительного редактирования и отладки проект был скомпилирован, в результате чего была получена среда разработки Visual Studio c интегрированными возможностями для создания и работы с визуальным языком описания структуры приложений для БСС (рис. 5).
Для проверки работоспособности и демонстрации возможностей полученного решения было написано несколько приложений на языке NesC, каждое из которых может выступать в роли управляющей программы узлов БСС. Затем при помощи решения были построены диаграммы компонентов этих приложений и по ним сгенерированы исходные тексты программ. Рассмотрим результаты применения DSM-решения на примере одного из приложений.
Рис. 5. Диаграмма компонентов NesC в среде VS 2008
Разработанное приложение реализует работу сети в проактивном и реактивном режимах. Это позволяет шлюзу сети получать периодическую информацию о контролируемом объекте, а в случае возникновения критической ситуации немедленно получить показания датчиков с опасными значениями. Для формирования структуры сети и доставки сообщений на шлюз в приложении используются XMesh-компоненты компании Crossbow. Периодически снимаемые узлом показания отправляются на шлюз не по одному, а целыми наборами, что позволяет снизить расход ресурса элемента питания.
Все компоненты в рамках одного приложения связываются при помощи конфигураторов в единую структуру, самым верхним узлом которой является компонент Main, самыми нижними — аппаратные компоненты узла. Разумеется, разработчику не требуется описывать всю эту структуру, вплоть до аппаратных компонентов (если, конечно, он не использует уникальное оборудование), так как разработчики библиотек TinyOS и аппаратных платформ для БСС уже позаботились об этом и предоставляют компоненты довольно высокого уровня. Диаграмма компонентов, построенная для данного приложения, представлена на рис. 6.
Рис. 6. Диаграмма компонентов NesC (интерфейсы скрыты)
На данной диаграмме скрыты сущности всех применяемых интерфейсов, что, как можно заметить, весьма удобно. Если же появится необходимость изучить отдельные связи межу компонентами подробнее, всегда можно их отобразить, воспользовавшись свойством VisibleOnDiagram у соответствующего интерфейса (рис. 7).
Рис. 7. Диаграмма компонентов NesC (с интерфейсами)
Диаграмма компонентов NesC изначально создавалась как артефакт, позволяющий упростить и ускорить разработку приложений для БСС. Помимо облегчения понимания программы в графическом представлении, в созданном DSM-решении реализована возможность генерации исходного кода на языке программирования NesC. Описание данной возможности приводилось выше, здесь лишь напомним, что на текущий момент генерируется только код для интерфейсной секции компонентов и файлов интерфейсов. Вот фрагмент сгенерированного кода приложения [2].
[1] foreach (NesCFile element in this.NesCModel.NesCFiles) { … if (element is Interface) { #> // Interface <#=element.Name #> interface <#=element.Name #> { <# foreach(Command CommandF in ((Interface)element).Commands) {#> command <#=CommandF.Name#> <#}#> <# foreach(Event EvetF in ((Interface)element).Events) {#> event <#=EvetF.Name#> <#}#> } <# } } |
[2] // ComponentModule Prog3M module Prog3M { Provides {interface StdControl} Uses { interface StdControl5 as PhotoControl interface Timer[unique(«Timer»)] interface Leds interface ADC as Light interface AllocationReq[BYTE_EEPROM_ID] interface ReadData[BYTE_EEPROM_ID] interface MhopSend[AM_XMULTIHOP_MSG] interface WriteData[BYTE_EEPROM_ID] } } // Interface WriteData[BYTE_EEPROM_ID] interface WriteData[BYTE_EEPROM_ID] { command write() event writeDone(uint8_t *data, uint32_t numBytesWrite, result_t success) } |
В представленном фрагменте описаны интерфейсные секции двух файлов: интерфейса WriteData и компонента-модуля Prog3M. В полном варианте сгенерированного кода подобным образом описаны все сущности, представленные в браузере объектов DSM-решения для данной модели, включая скрытые интерфейсы. Однако разработчику обычно не требуется код всех сущностей модели, поскольку они являются стандартными и уже описаны в среде разработки TinyOS.
Заключение
Разработанный программный продукт позволяет формировать модели NesC-приложений при помощи специализированного визуального языка. Эти модели являются достаточно наглядными и могут послужить артефактами для документирования приложений. Особого внимания при разработке модели требует выбор интерфейсов, которые следует визуализировать. Большое количество интерфейсов делает диаграмму перегруженной и сложной для понимания, в то время как полное их отсутствие не дает разработчику представления о связях между компонентами.
С помощью разработанного средства можно осуществлять прямое проектирование, используя специальные шаблоны для генерации кода. Код, генерируемый по модели при помощи шаблонов, является синтаксически верным кодом NesC, что позволяет применять его при дальнейшей разработке приложений для БСС. Полученная в результате генерации интерфейсная секция компонентов помогает разработчику избежать необходимости вручную формировать используемые и предоставляемые компонентами интерфейсы и их псевдонимы.
Представленное в этой статье решение расширяет возможности проектировщика NesC-приложений и является одним из немногих сегодня инструментов, делающих разработку приложений для БСС более удобной и эффективной.
Дальнейшее развитие связано с расширением возможностей системы по генерации кода, добавлением средства проверки правильности построенных моделей и созданием репозитория объектов.
Канд. техн. наук, доцент Национального исследовательского ядерного университета «МИФИ».
Сергей Сыроежкин
Аспирант национального исследовательского ядерного университета «МИФИ».