TOC PREV NEXT INDEX

Put your logo here!


6 CODE EXAMPLES

6.1 Reflective Memory Access

The following code shows how to use to reflective memory. The first step is to retrieve the base address of the user memory. After that the reflective memory can be accessed directly, by means of simple R/W operations. It might be useful to map C-language data structures onto the reflective memory in order to make the implementation of the code independent from the hardware addresses. In the example below, a user defined data structure is mapped onto the reflective memory starting from an offset with respect the base address.

#define DATA_STRUCT_OFFSET 0x100
typedef struct
{
int a;
float b;
} DATA_STRUCT;
DATA_STRUCT *dataStruct;
int status;
int fd;
void *baseAddr;
float c;

/* Open a channel */
fd = open("/rmn0",lcudrvOPEN_SHARED,(int)&status);
if (fd < 0) { /* error handling */ }

/* Get the user memory base address */
status = ioctl(fd,rmnCMD_ADDR_GET_USER_MEM_BASE,(int)&baseAddr);
if (status != lcudrvOK) { /* error handling */ }

/* Use the reflective memory. The data written will be
* immediately transferred
to all the other nodes in the
* reflective memory network
*/
dataStruct = (DATA_STRUCT *)(baseAddr+DATA_STRUCT_OFFSET);
dataStruct->a = 10; /* <=== VME write on the refl. memory */
c = dataStruct->b; /* <=== VME read from the refl. memory */

/* some more code */

/* Close the channel */
close(fd);

6.2 Sending and Receiving Interrupts

The following code shows how to use the remote-interrupt feature of the reflective memory. The user application must first configure the selected interrupt source on the receiving node, attaching a user-provided ISR or getting back the interrupt synchronization semaphore pointer. After that the sending node can start sending interrupts, which will be immediately detected and served by the receiving node.

In the first example below the interrupt source 1 will be configured: the user-provided ISR will run in the interrupt context, the autoClear flag will be disabled and the interrupt FIFO will be cleaned.

/*-------------------------------------------------------------------------
* Code for ISR and interrupt configuration (ISR context) on receiving node
*--------------------------------------------------------------------------*/
void myUserISR(void *userArg, int senderID)
{
/* User-provided ISR code */
/* The number of the sending node "senderID" will be
* identified and passed to this routine by the rmn driver
*/
}

int status;
int fd;
static int myUserArg = 1234;

rmnINT_CONFIG_DATA intrConfigData;

/* Open a channel */
fd = open("/rmn0",lcudrvOPEN_SHARED,(int)&status);
if (fd < 0) { /* error handling */ }

/* Configure an interrupt source */
intrConfigData.source = 1;
intrConfigData.userISR = myUserISR;
intrConfigData.userArg = (void *)myUserArg;
intrConfigData.autoClear = 0;
intrConfigData.cleanFIFO = 1;
intrConfigData.mode = rmnISR_CONTEXT;

status = ioctl(fd,rmnCMD_CONFIG_INTERRUPT,(int)&intrConfigData);
if (status != lcudrvOK) { /* error handling */ }

/* From now on any interrupt of source 1 sent from other nodes to
* this one will be detected and the attached ISR will run.
*/

/* Close the channel */
close(fd);

/*-----------------------------------------------------------
* Code for sending an interrupt on the sending node
*--------------------------------------------------------------*/
rmnINT_SEND_DATA intrData;

/* Open a channel */
fd = open("/rmn0",lcudrvOPEN_SHARED,(int)&status);
if (fd < 0) { /* error handling */ }

/* Send an interrupt of source 1 to the target node 0 */
intrData.source = 1;
intrData.targetID = 0;
status = ioctl(fd,rmnCMD_SEND_INTERRUPT,(int)&intrData);
if (status != lcudrvOK) { /* error handling */ }

/* Close the channel */
close(fd);

This second example shows how to configure an ISR which runs in the task-context, that is getting activated by means of the interrupt synchronization semaphore.


/*------------------------------------------------------------------
* Code for interrupt configuration (task context) on receiving node
*-------------------------------------------------------------------*/
int status;
int fd;
SEM_ID syncSem;
rmnINT_CONFIG_DATA intrConfigData;

/* Open a channel */
fd = open("/rmn0",lcudrvOPEN_SHARED,(int)&status);
if (fd < 0) { /* error handling */ }

/* Configure an interrupt source */
intrConfigData.source = 1;
intrConfigData.autoClear = 0;
intrConfigData.cleanFIFO = 1;
intrConfigData.mode = rmnTASK_CONTEXT;

status = ioctl(fd,rmnCMD_CONFIG_INTERRUPT,(int)&intrConfigData);
if (status != lcudrvOK) { /* error handling */ }

/* From now on any interrupt of source 1 sent from other nodes to
* this one will be detected and the semaphore will be given
*/

/* Get the synchronization semaphore from the interrupt
* configuration data structure.
*/
syncSem = intrConfigData.semID;

/* Wait for the interrupt; when the interrupt is detected by the
* rmn driver, the semaphore will be given by the driver itself
*/
status = semTake(syncSem,WAIT_FOREVER);

/* Run the code to serve the interrupt */

/* Close the channel */
close(fd);



Quadralay Corporation
http://www.webworks.com
Voice: (512) 719-3399
Fax: (512) 719-3606
sales@webworks.com
TOC PREV NEXT INDEX