You are here: Foswiki>FESA Web>HowTo>InterfaceEquipmentLinks (05 Feb 2009, HaraldBraeuning)Edit Attach

Introduction

Equipment links define relationships between FESA classes allowing one class to access properties and data of another class. Interface equipment links are one of the three types of equipment links possible in FESA. A description and manual can be found here. This HowTo focuses on interface equipment links and details the pitfalls not mentioned in the manual.

Interface equipment links allow one FESA class to talk to another FESA class by using the latters interface and properties the same way the common middleware and GUI does. However, as both classes must reside on the same front end computer, there is no communication via network etc. involved.

A FESA executable consists of 3 parts:
  1. interface part
  2. real time part
  3. data

When the FESA class is deployed as a single-process (most common option) all three parts reside in a single execuatble called classname_M.cpu (i.e. FCT_SIS3350_M.ppc4 for a RIO3 cpu). The interface and real time part are also compiled as libraries. Using interface equipment links requires to things:
  1. the calling class must have knowledge of the interface of the called class
  2. the data of the called class must reside in a shared memory segment for communication

The first requirement is achieved by linking the interface part library of the called class to the binary of the calling class. The second requirement means, that the called class must be deployed as seperate-server-split. Otherwise, the data segement resides in the process owned memory and not in a shared memory segment.

The image below illustrates the deployment for two classes: FCT_SIS3350 and HBrTest with the first being called by the latter. InterfaceEquipmentLinks_Scheme.png

Note: The interface part of the called class exists twice on the front end. Thus any initialization which should occur only once like VME mapping, register mapping etc. must be done in the initialization of the real time part and not in the interface part.

Preparing the called class

Step 1

As the interface part library of the called class must be linked to the calling class, the compiler needs to have access to the header files and libraries. For this to work, the called class has to be delivered by the command:

FESA Deliver class version cpu

For example: FESA Deliver FCT_SIS3350 0 ppc4

Note: If any changes to the called class (i.e. FCT_SIS3350) are made, the class has to be delivered again. Otherwise, old libraries would be linked to the calling class.

Step 2

In order to have the data of the called class in a shared memory segment, the class needs to be deployed as seperate-server-split. This produces two binaries called classname_S.cpu for the interface/server part and classname_R.cpu for the realtime part. Currently to build these binaries do:

cd TEST; make server; make rt

Preparing the calling class

Step 1

Tell FESA that the interface of another class has to be linked. This is done by adding the appropriate equipment-links segment in the FESA class design. The image below shows this for the class FCT_SIS3350 version 0 whose interface is to be called from both the interface part and the real time part of the calling class.

InterfaceEquipmentLinks.png

The calling class can be deployed as usual as a single-process. The interface library of the called class will be automatically included.

Step 2

As described in the attached document create a directory with the front end name under the TEST directory. Create links to the binary of the calling class and to the device data file of the called class. Instantiate the device data of the calling class in this directory.

As an example we assume the front end to be sddsc001, the calling class being named HBrTest and the called class being named FCT_SIS3350. Then the following commands set up the correct file structure:

cd TEST; mkdir sddsc001; cd sddsc001

ln -s ../HBrTest_M.ppc4 HBrTest_M.ppc4

ln -s ../../../../FCT_SIS3350/v0/TEST/FCT_SIS3350DeviceData.xml FCT_SIS3350DeviceData.xml

cd ../..

Fesa Instantiate FCT_SIS3350 0 sddsc001 TEST/sddsc001

Setting / Getting data from the called class

Using the interface of the called class in a server or real time action requires the following steps:

  1. obtain a pointer to the equipment interface of the called class
  2. obtain a pointer to the device handled by the called class
  3. obtain a pointer to the property of the called class which is to be set or get
  4. set the property data and write the property or get the property and read the data.

The following code fragment shows this for the example of the FESA class FCT_SIS3350 acting on the device NONE-FCT_SIS3350. The calling class sets various settings of the class FCT_SIS3350 (using the property Settings) depending on the data passed to it.

  AbstractEquipmentInterface *pInterface = AbstractEquipmentInterface::getEqpIntfFromClassName("FCT_SIS3350");
  if (pInterface == 0)
    {
      throw FesaIOError("FESA_EQUIP", -1, "Equipment interface for FCT_SIS3350 not found!");
    }
  Property *pProperty = pInterface->getProperty("Settings");
  Device *pDev = pInterface->getDevice("NONE-FCT_SIS3350"); 

  rdaData d;
  rdaData filter;
      
  if (data.setting.get() == 0)
    {
      d.insert("ringbufferSampleLength12",4096L);
      d.insert("ringbufferPreDelay12",2048L);
    }
  else if (data.setting.get() == 1)
    {
      d.insert("ringbufferSampleLength12",8192L);
      d.insert("ringbufferPreDelay12",4096L);
    }
  else
    {
      d.insert("ringbufferSampleLength12",16376L);
      d.insert("ringbufferPreDelay12",8192L);
    }
  pProperty->set(*pDev,"",filter,d);

Running it

To run everything do the following:
  1. start the server part of the called class (i.e. FCT_SIS3350_S.ppc4)
  2. start the real time part of the called class (i.e. FCT_SIS3350_R.ppc4)
  3. check that everything works
  4. in the directory created under the TEST directory start the calling class (i.e. HBrTest_M.ppc4 if it is a single process)

If you do not want to access the called class directly, there should be no reason to have its interface part running. The following should then also work (not tested yet):
  1. in the directory created under the TEST directory start the calling class (i.e. HBrTest_M.ppc4 if it is a single process). This also creates the shared memory segment and initializes the interface of the called class once.
  2. start the real time part of the called class (i.e. FCT_SIS3350_R.ppc4)
  3. check that everything works

A note on shared memory

When the processes are killed the shared memory is not relased. This can cause severe problems during the testing phase, when the classes have been changed and the shared memory structure does not reflect the class anymore. The shared memory segment has to be deleted manually.

Under LynxOS use the command lipcs to get a list of shared memory segments. For our example with the class FCT_SIS3350 this displays:

__mq-100664141-shm             SHM rw-rw-rw- uid 0      gid 0     
FCT_SIS3350EquipmentShm        SHM rwxrwx--- uid 0      gid 0     
/FCT_SIS3350UserEv              MQ rw-rw-rw- uid 0      gid 0     
/dev/mem                       SHM rw-r--r-- uid 0      gid 0     

The segment FCT_SIS3350EquipmentShm is the shared memory segment for the FCT_SIS3350 device data. It will not be present, if the class is deployed in single-process mode. The other two entries /FCT_SIS3350UserEv and __mq-100664141-shm are present also with the single-process deployment and can be ignored. Assumption: they result from the user events used in the FESA class).

The shared memory segments can be deleted by the command lipcrm. For example

lipcrm FCT_SIS3350EquipmentShm

deletes the shared memory segment for the device data and

lipcrm /FCT_SIS3350UserEv

will delete the two entries /FCT_SIS3350UserEv and __mq-100664141-shm.

Pitfalls

If things do not work and the code crashes with segfaults for example, check the following:

  • Are you using up to date libraries of the called class ?
    • Do a Fesa Deliver
  • Are stale shared memory segments on the front end ?
    • Delete all shared memory segments with lipcrm
  • Are hardware pointers initialized twice ?
    • Data to be initialized one only must be initialized in the real time setup as the interface part is initialized twice
  • The two classes are not communicating ?
    • Make sure the called class is compiled as seperate server and RT part
Topic revision: r1 - 05 Feb 2009, HaraldBraeuning
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback