Implementation

For the implementation of your own driver, the following new classes must be derived from the classes defined in the general driver:

  • MyHWObject (optional, describes the additional properties of special HW data), is derived from HWObject.
  • MyHWMapper (in the derived method actualize(..), the matching between hardware objects and peripheral addresses is done, and a suitable transformation for each hardware object must also be created and configured here), is derived from HWMapper.
  • MyDrvResource (optional, serves for the implementation of internal data points, and for the entry and management of driver-specific settings; the derived method readSection() should always also call the method commonKeyWord(), in which the resources of the general driver are processed), is derived from DrvResource.
  • MyHWService (used for the link-up to the special periphery, takes into account the communication with the hardware, transfer protocols, sends previously created HW objects in the command direction to the periphery, packs them if necessary in protocol-dependent telegrams. Handles incoming data in the alert direction and converts it to HW objects, which are then forwarded with the DrvManager's toDP() to the event manager), is derived from HWService.
  • MyDrvManager (Installs the special derived objects of the own driver, forms an outline class), is derived from DrvManager.
  • MyTransformation (for each special peripheral data type, a separate transformation object must be created, which is derived from the base class Transformation).
  • main() (the main program, doesn't represent a separate class. An object MyDrvManager is created.)
  • various auxiliary objects, if necessary

A typical main program for a special driver could have the following appearance, for example:

// global objects
MyResources resources;
MyDrvManager *g_driver;
// interrupt handler
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()) ;
  // reading of the driver parameters from the configuration file
  end(argc, argv);
}

A typical MyHWService method workProc() might look something like this:

void MyHWService::workProc()
{
  TimeVar now;
  MyHWObject myObj;
  myObj.setOrgTime(now); // set source time
  myObj.setAddress(address); // simplified assumption: the
  // HW address is entered from externally into the string address
  HWObject *pDp = DrvManager::getHWMapperPtr()->
  findHWObject(&myObj);
  // look for corresponding HW object in the HWMapper
  if (pDp) // found ?
  { // yes
    myObj.setDlen(pDp->getDlen());
    // the data length is taken from the HWMapper
    PVSSchar *pBuf = new PVSSchar[myObj.getDlen()];
    // create new data buffer
    memcpy(pBuf,dataBuf,myObj.getDlen());
    // Assumption: the peripheral data is available in dataBuf
    myObj.setData(pBuf);
    if (data_invalid) // is the data invalid ?
    myObj.setSbit(DRV_INVALID); // set invalid bit
    DrvManager::getSelfPtr()->toDp(&myObj, pDp);
  }
  else ... // Error message
}

For this function it was assumed that from the address address (this corresponds to a configured peripheral address) data is present in the buffer dataBuf (one char *), the data being invalid if the flag data_invalid (boolean) is set.

The corresponding HWService function writeData(), which sets data points at the periphery in analogy to the above function, could look like this:

void writeData(HWObject *myObj)
{
  address = myObj->getAddress();
  // sets the address concerned
  memcpy(dataBuf,myObj->getData(),myObj->getDlen());
  // re-copying the data
}

In this case too, it is assumed that the data will be made available (this time by our simple driver) from address 'address' in the buffer dataBuf (which must already exist). These two simple functions are in fact only intended to clarify the mechanism. A real driver could e.g. compose a telegram in the send direction in writeData(), which is then sent via a TCP-IP connection to a partner. In the receive direction (in the workProc() ) such a telegram is interpreted, and the address and the raw data are extracted and entered in myObj, before it is passed with toDp() to the general driver.