DrvManager — управляющий класс драйвера. Он сам наследуется от базового класса manager.
DrvManager наследует от manager статические указатели на контейнер типа точки данных и контейнер точки данных. Кроме того, он содержит статические указатели на менеджер конфигураций точки данных и классы HWMapper, HWService и PollGroupList. Он также содержит указатель на массив DpConfigNrTypes, который используется для инициализации.
Для всех этих статических указателей существуют виртуальные функции, которые создают и устанавливают объекты (указатель на них находится в классе DrvManager), а именно функции install_$$$ (см. раздел 1). Поскольку в обычном случае для объекта HWService и HWMapper должен быть отдельный класс, для DrvManager тоже должен быть создан отдельный класс и перезаписаны функции install_HWMapper() и install_HWService().
При вызове функции DrvManager (базовый класс) — mainProcedure() (эта функция не была перезаписана в классе, унаследованном от DrvManager) происходит следующее:
Вызывается функция init() из класса DrvManager (статические указатели инициализируются функциями install_$$$)
- Устанавливается подключение к менеджеру данных и выполняется инициализация контейнера типа точек данных и контейнера точек данных (для конфигурационного элемента)
- Из базы данных запрашиваются идентификаторы точек данных по именам внутренних точек данных. Поскольку драйвер не может использовать в сообщениях имена точек данных, а только их идентификаторы, ему приходится запрашивать преобразование имен в dpidentifiers из менеджера данных и сохранять полученные dpidentifiers -> см. описание DrvRsrce!
- Инициализация объекта HWService.
- Драйвер создает подключение к менеджеру событий и регистрирует в нем все исходные значения точек данных с адресом периферии, заданном как выходной.
- Вызывается (виртуальная) функция mainLoop.
Функция DrvManager mainLoop() имеет следующий функционал:
- Переподключение к менеджеру событий после потери соединения.
- Вызов диспетчера (обрабатывающего диспетчерские заказы менеджера событий)
- Опрос (обработка циклических запросов данных)
- Вызов (виртуальной) функции workProc() объекта HWService (обработка входящих данных)
Выполняется в цикле, пока внутренний режим DrvManager не поменяется на DRVMODE_EXITING. (например, по нажатию Ctrl-C)
Функция toDp(HWObject *, HWObject *) аналогична виртуальной, но, в обычном случае не перезаписывается. Она используется для обработки входящих данных. Их преобразование из необработанной формы в инженерные значения выполняет функция toDp(..), при необходимости сглаживая и направляя их менеджеру событий.
Функция toHW(DpHLGroup *) обрабатывает отправку точек данных в направлении команды. Она получает от менеджера событий группу точек данных (при групповом входе), подлежащих отправке. Функция создает аппаратный объект или драйвер-ориентированный эквивалент и с его помощью вызывает функцию writeData(HWObject) объекта HWService, которая отправляет объект на периферию.
Виртуальный метод getAttribs2Connect(..) выдает по заданному адресу периферии атрибуты, которые драйвер должен регистрировать с помощью менеджера событий. Как правило, это исходное значение. Если, к примеру, требуется запросить также исходное время, специальный драйвер должен соответственно перезаписать эту функцию.
ПРИМЕР
unsigned int getAttribs2Connect( const PeriphAddr *) const
{ // для исходного значения и времени
возвращает DRVCONNMODE_VALUE | DRVCONNMODE_TIME;
}
Аналогично исходному значению и времени, регистрация возможна для следующих битов состояния:
- DRVCONNMODE_GA (бит общего запроса)
- DRVCONNMODE_GA (бит одиночного запроса)
- DRVCONNMODE_GA (бит ошибки)
- DRVCONNMODE_USER1 (информационный бит 1)
- DRVCONNMODE_USER2 (информационный бит 2)
- DRVCONNMODE_USER3 (информационный бит 3)
- DRVCONNMODE_USER4 (информационный бит 4)
… - DRVCONNMODE_USER29 (информационный бит 29)
- DRVCONNMODE_USER30 (информационный бит 30)
- DRVCONNMODE_USER31 (информационный бит 31)
- DRVCONNMODE_USER32 (информационный бит 32)
ПРИМЕЧАНИЕ
В крупных проектах инициализация драйвер-ориентированной конфигурации может отнимать значительное время. Иногда для нормальной работы это время превышает необходимое для драйвер-ориентированной реализации. В этом кроется проблема: драйвер пытается использовать информацию, которую он еще не получил (например, если драйвер пытается вызвать функцию AlertService::setAlert(), но соответствующая конфигурация _alert_hdl еще не была загружена).
Специальный драйвер может попытаться перезаписать метод обратного вызова DrvMananger::connectQueueDone(), чтобы получить уведомление о завершении инициализации драйвера. Только после вызова этого метода реализация специального драйвера должна полагаться на имеющуюся в наличии соответствующую информацию.