HWObject

HWObject is the base class for a hardware object. The general driver communicates with the hardware-specific part via this class. If a separate hardware address is needed (beyond the peripheral address string), then an extended object must be derived from this class. If the Modbus generates a spontaneous message, for example, the Modbus driver's HWService Object creates a (Modbus-specific) HW object and passes this to the toDP(...) function of the DrvManager. Conversely, if a user tries to set a value at the periphery, the driver is notified by the event manager via a hotlink. The value contained in this hotlink is converted by the driver, a HW object is created, the converted value is transformed into a HW-specific date and passed to the HWService Object. A hardware address is implemented when a new object is derived from the HW object, containing the additional attributes for the hardware address (for the Modbus e.g. communication reference (kr) and index (ix)). Furthermore, the compare functions of the derived HWMapper should be adjusted to the hardware addresses of the derived HW object.

The HW object contains a pointer to a data buffer in which the periphery data is stored, an attribute dataLen which gives the size of this buffer in bytes, and an address string corresponding to the address given in the peripheral address config. The attribute transType contains the number of the transformation that is assigned to this HW object; in originTime a time can also be allocated to the object (the current time, if no separate source time came in with the data). One of the following data types can be assigned to the objSrcType: srcSpont for spontaneously incoming data, srcPolled for data that was obtained by polling, srcSingleQ for data that is the result of a single query, and lastly srcGeneralQ for data that was sent for a general query. These data types are used, among other cases, in the handling of smoothing (smoothing mode).

The attribute number_of_elements gives the number of elements in fields.

For all attributes, there are the corresponding setxxx and getxxx methods. The HWObject virtual method setAdditionalData(const RecVar &data, PVSSushort subix), which receives as first parameter the data and as second the subindex of the relevant data point element, serves for storing in the HW object the information additional to the original value for which the driver has registered with the event manager. For example, if the invalid bit in the HW object should always be set for fields if at least one data point element is set invalid, the function should be derived as follows:

  1. void setAdditionalData( const RecVar &data, PVSSushort subix)
    {
      if ( data.getRecLength() ) // additional information exists
      {
        int flags = ( (UIntegerVar *)data.getFirstVar() )-
        >getValue();
        // the first variable contains the flags,
        // that show what information was sent
        if ( flags & DrvManager::DRVCONNMODE_TIME )
        { 
          data.getNextVar(); 
        }
        // ignore time
        if ( flags & DrvManager::DRVCONNMODE_GA )
        { 
          data.getNextVar(); 
        } 
        // ignore GA bit
        if ( flags & DrvManager::DRVCONNMODE_EA )
        { 
          data.getNextVar(); 
        } 
        // ignore EA bit
        if ( flags & DrvManager::DRVCONNMODE_INVALID )
        {
          if ( (! getSbit(DRV_INVALID)) &&
          (((BitVar *)data.getNextVar())->getValue()))
          setSbit(DRV_INVALID);
        } 
        // logical or of the invalid bits, function
        // is called separately for each subindex
        ...
        // ignore user bits
      }
    }

It should be noted that in the first entry of RecVar there is a bit pattern (in a variable of type UIntegerVar), that indicates what information was sent, so for each set bit sequentially the next variable (getNextVar()) must be evaluated, even if (as above) it is not further used (except for the invalid bit in the example). But since the driver is only meant to register with the event manager for "interesting" information based on the peripheral address config (by means of the DrvManager method getAttribs2Connect(..) ), only the relevant flags should be set here too in the RecVar (hence the invalid bit in the example). A suitable error message could be output, for example, if additional information was discovered in RecVar.

Note that cutData() has to be used to delete old data from an object if you do not want the data pointer in the object to be deleted via a new setData or when deleting an object. E.g.

int myFunc ()
{
  PVSSchar buffer[10];
  // filling buffer with data
  HWObject obj;
  obj.setData(buffer);
  ….//any processing
  obj.cutData() // avoid deletion of buffer, because it is an automatic
  // variable allocated on the stack
}

In this example cutData() has to be used since the old data pointer is deleted in the destructor of the HWObject if it is !=NULL. This does not happen if cutData() is used before. cutData() sets the internal data pointer in the HWObject to NULL and returns the pointer value but does not release any memory (in the destructor of the HWObject no data pointer is deleted since the value is NULL). The memory has to be released manually.