Skip to content

Oscar Software Framework Manual Inter Process Communication Module

scs edited this page Jul 16, 2012 · 3 revisions

Go to Table of Contents.

Table of Contents

Inter-Process Communication Module (ipc)

Description

IPC communication: OscIpcGetParam

IPC communication: OscIpcSetParam

The ipc module provides an easy way of doing inter-process communication among processes belonging to the same application. The communication is executed in a client-server fashion. One side of the communication channel is the client which sends read and write requests to the server. The server then executes these requests and acknowledges them. This allows communication of a high priority (real-time) process that must not block acting as the server with a low priority statistics and human interface process acting as client. Both processes need to agree on a set of parameters and their sizes. Then the actual communication is done over parameter identifiers.

The IPC module sends request and response messages over AF_UNIX sockets in the file system. Each such socket represents a full-duplex interface and is called an IPC channel. A configurable number of such IPC channels can be registered to allow simultaneous communication with multiple processes.

The implementation of how the actual payload data is transferred depends on the platform.

Host: The payload data of a read or write is sent over the sockets like the messages.

Target: Only a pointer to the data in the other processes memory is exchanged and the data is accessed directly. This is possible because the target does not feature virtual memory. It saves the overhead of a copy operation.

Target Hardware Resource

None.

Dependencies

  • log: For error logging.

Usage

Following code segment demonstrates the usage of the ipc module. It is a simple example of a typical program sequence, and does not cover all the functionality of the module. For the sake of simplicity, error checking as well as framework creation and destruction are neglected.

Client:

 OSC_IPC_CHAN_ID chan;
 struct OSC_IPC_REQUEST req;
 uint32 param1;
 uint32 param2[] = { 0, 1, 2, 3 };
 
 OscIpcRegisterChannel(&chan, "OSC_IPC.sock", 0); /* (1) */
 
 OscIpcGetParam(chan, &param1, ID_PARAM1, SIZE_PARAM1); /* (2) */
 
 printf("Param 1 is %u!\n", param1);
 
 OscIpcSetParam(chan, param2, ID_PARAM2, SIZE_PARAM2); /* (3) */
  1. Register a channel to the server. We specify OSC_IPC.sock as the socket we want to connect to.
  2. Read parameter 1 from the server. This blocks until the parameter is read.
  3. Write Parameter 2 to the server. This blocks until the parameter has been written.
Server:
 OSC_IPC_CHAN_ID chan;
 struct OSC_IPC_REQUEST req;
 OSC_ERR err;
 uint32 param1 = 0xdeadbeef;
 uint32 param2[4];
 
 OscIpcRegisterChannel(&chan, /* (1) */
  "OSC_IPC.sock"
  F_IPC_SERVER | F_IPC_NONBLOCKING);
 
 while(1) /* Server main loop. */
 {
     err = OscIpcGetRequest(chan, &req); /* (2) */
     if(err)
     {
         if(err != -ENO_MSG_AVAIL)
         {
             printf("ERROR!\n");
         }
     }
     else
     {
         /* Success */ /* (3) */
         if(req.enType == REQ_TYPE_READ && req.paramID == ID_PARAM1)
         {
             *req.pAddr = param1;
         }
         else if(req.enType == REQ_TYPE_WRITE && req.paramID == ID_PARAM2)
         {
             memcpy(param2, req.pAddr, SIZE_PARAM2);
         }
         
         do /* (4) */
         {
             err = OscIpcAckRequest(chan, &req, TRUE);
         }
         while(err == -ETRY_AGAIN);
     }
     
     /* Do other stuff. */
 }
  1. Register a channel to the client. We specify " OSC_IPC.sock " as the socket name in the file system we want to listen to.
  2. Enter the main loop. Test at the start of the loop if there is a request available, otherwise continue. If there is currently no request -ENO_MSG_AVAIL is returned.
  3. If there is an incoming request, test its type and the parameter variable it concerns and execute the necessary read or write action. The request contains a pointer to the memory location of the parameter in the other process, which can be accessed directly on the target platform. In the host implementation, this points to a temporary memory location and thus can be used the same way.
  4. Acknowledge the request. This may temporarily fail with -ETRY_AGAIN if the socket is not connected. In this case try it again later, for example in the next iteration of the main loop in order not to lose too much time.
Clone this wiki locally