Реализация

Для реализации собственно драйвера от классов, определенных в общем драйвере, должна быть получены следующие производные классы:
MyHWObject (не обязательный, описывает дополнительные свойства специальных аппаратных данных) — производный от HWObject.
MyHWMapper (в производном методе actualize(..) производится сопоставление аппаратных объектов с адресами периферии, здесь же создается и настраивается подходящее преобразование для каждого из аппаратных объектов) — производный от HWMapper.
MyDrvResource (не обязательный, служит для реализации внутренних точек данных и управлением специфичных для драйвера настроек; производный метод readSection() всегда должен вызывать метод commonKeyWord(), в котором происходит обработка ресурсов общего драйвера), производный от DrvResource.
MyHWService (используется для подключения к специальной периферии, учитывает связь с оборудованием, протоколы передачи, отправляет заранее созданные аппаратные объекты в указанном направлении на периферию, при необходимости упаковывает их в протокол-зависимые телеграммы. Обрабатывает входящие данные в направлении аларма и преобразует их в аппаратные объекты, которые затем направляются с помощью функции toDP() DrvManager в менеджер событий), производный от HWService.
MyDrvManager (устанавливает специальные производные объекты собственного драйвера, формирует каркас класса), производный от DrvManager.
MyTransformation (для каждого специального типа данных периферии должен быть создан отдельный объект преобразования, производный от базового класса Transformation).
main() (Главная программа, не является отдельным классом. Создается объект MyDrvManager).
При необходимости различные вспомогательные объекты
Типовая главная программа для специального драйвера может иметь, к примеру, следующий вид: 

// глобальные объекты
MyResources resources;
MyDrvManager *g_driver;
// обработчик прерываний
void sigReceiver( int sigNum )
{
g_driver->signalHandler( sigNum );
}
int main( int argc, char *argv[] )
{
MyResources::init( argc, argv );
if ( Resources::getHelpFlag() )
MyResources::printHelp();
else
             {
g_driver = new MyDrvManager;
signal( SIGINT, sigReceiver );
g_driver->mainProcedure( argc, argv );
             }
return 0;
}
MyResources::init(int argc, char *argv[])
{
begin(argc,argv[]);
while (readSection() || generalSection()) ;
// чтение параметров драйвера из файла конфигурации
end(argc, argv);
}
Типовой метод workProc() класса MyHWService может иметь следующий вид:

 void MyHWService::workProc()
{
TimeVar now;
MyHWObject myObj;
myObj.setOrgTime(now); // ввод исходного времени
myObj.setAddress(address); // упрощенное предположение:
// аппаратный адрес вводится из внешнего источника в строковый адрес
HWObject *pDp = DrvManager::getHWMapperPtr()->
  findHWObject(&myObj);
// поиск соответствующего аппаратного объекта в HWMapper
      if (pDp) // найден?
          { // да
          myObj.setDlen(pDp->getDlen());
          // длина данных берется из HWMapper
          PVSSchar *pBuf = new PVSSchar[myObj.getDlen()];
          // создание нового буфера данных
          memcpy(pBuf,dataBuf,myObj.getDlen());
          // Предположение: данные периферии доступны в dataBuf
          myObj.setData(pBuf);
              if (data_invalid) // данные допустимые?
myObj.setSbit(DRV_INVALID); // установка бита ошибки
                   DrvManager::getSelfPtr()->toDp(&myObj, pDp);
          }
       else … // Сообщение об ошибке
}
Для этой функции предполагается, что данные с адреса address (соответствует указанному адресу периферии) находятся в буфере dataBuf (один символ *), данные считаются недопустимыми, если установлен (логический) флаг data_invalid.
Соответствующая функция HWService writeData(), задающая точки данных на периферии, аналогично приведенной выше функции, может иметь следующий вид: void writeData(HWObject *myObj)
{
address = myObj->getAddress();
// задает соответствующий адрес
memcpy(dataBuf,myObj->getData(),myObj->getDlen());
// повторное копирование данных
}
В этом случае также предполагается, что данные с адреса «address» будут сделаны доступными (на этот раз нашим простым драйвером) в буфере dataBuf (который уже должен существовать). На самом деле эти две простые функции приведены только для того чтобы прояснить механизм. Реальный драйвер мог, к примеру, составить телеграмму в направлении отправки в writeData(), которая бы затем была отправлена по TCP/IP-подключению партнеру. В направлении приема (в workProc()) подобная телеграмма перед ее отправкой функцией toDp() общему драйверу была бы интерпретирована, из нее были бы извлечены адрес и необработанные данные, которые были бы записаны в myObj.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *