Linux, Real-Time Linux,& IPC
by Frederick M. Proctor

Example 1:

(a) 
image=/boot/zImage 
label=rtlinux-0.6 
root=/dev/hda2 
read-only 
  
(b)  
image=/boot/zImage 
label=rtlinux-0.6 
root=/dev/hda2 
read-only 
append="mem=31m" 
  
(c) 
image=/boot/zImage 
label=rtlinux-0.6 
root=/dev/hda2 
read-only 
append="mem=15872k" 

Example 2: 

#include <unistd.h>    /* open() */ 
#include <fcntl.h>     /* O_RDWR */ 
int fd; 
if ((fd = open("/dev/mem", O_RDWR)) < 0) 
{ 
  /* handle error here */ 
} 

Example 3:

(a) 
ptr->command.arg1 = 1; 
ptr->command.arg2 = 2; 

(b) 
#include <sys/mman.h> 
#include "myheader.h" 
munmap(ptr, sizeof(MY_STRUCT)); 

Example 4:

(a)
#include "myheader.h" 
MY_STRUCT *ptr; 
ptr = (MY_STRUCT *) BASE_ADDRESS; 
ptr->command.arg1 = 1; 
ptr->command.arg2 = 2; 

(b)
ptr = (MY_STRUCT *) __va(BASE_ADDRESS) 


Listing One
typedef struct  
{ 
 unsigned char inuse;  /* more on this later */ 
 int command; 
 int command_number; 
 int arg1; 
 int arg2; 
} MY_COMMAND; 
typedef struct  
{ 
 unsigned char inuse;  /* more on this later */ 
 int command_echo; 
 int command_number_echo; 
 int stat1; 
 int stat2; 
} MY_STATUS; 
typedef struct  
{ 
 MY_COMMAND command; 
 MY_STATUS status; 
} MY_STRUCT; 


Listing Two
#include <stdlib.h>                /* sizeof() */ 
#include <sys/mman.h>              /* mmap(), PROT_READ, MAP_FILE */ 
#define MAP_FAILED ((void *) -1)   /* omitted from Linux mman.h */ 
#include "myheader.h" 
MY_STRUCT *ptr; 
ptr = (MY_STRUCT *) mmap(0, sizeof(MY_STRUCT), 
 PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, BASE_ADDRESS); 
if (MAP_FAILED == ptr) 
{ 
  /* handle error here */ 
} 
close(fd);                    /* fd no longer needed */ 


Listing Three  
typedef struct  
{ 
  unsigned char inuse; 
  int command; 
  int command_number; 
  int arg1; 
  int arg2; 
} MY_COMMAND; 
typedef struct  
{ 
  unsigned char inuse; 
  int command_echo; 
  int command_number_echo; 
  int stat1; 
  int stat2; 
} MY_STATUS; 

Listing Four 
MY_COMMAND my_command; 
/* compose command in local structure */ 
my_command.inuse = 1;  /* will overwrite during copy, so set here too */ 
my_command.command = 123; 
my_command.command_number++; 
my_command.arg1 = 2; 
my_command.arg2 = 3; 
/* set inuse flag */ 
command_ptr->inuse = 1; 
/* copy local structure to shared memory */ 
memcpy(command_ptr, &my_command, sizeof(MY_COMMAND)); 
/* clear inuse flag */ 
command_ptr->inuse = 0; 

Listing Five 
if (0 != command_ptr->inuse) 
{ 
 /* ignore it, perhaps incrementing a deferral count */ 
} 
else 
{ 
  /* okay to access shared memory */ 
} 

Listing Six
MY_STATUS my_status; 
/* set inuse flag */ 
status_ptr->inuse = 1; 
/* copy shared memory to local structure */ 
memcpy(&my_status, status_ptr, sizeof(MY_STATUS)); 
/* clear inuse flag */ 
status_ptr->inuse = 0; 
/* refer to local struct from now on */ 
if (my_status.stat1 == 1) 
{ 
  ... 
} 

Listing Seven 
if (0 != status_ptr->inuse) 
{ 
  /* defer status write, perhaps incrementing deferral count */ 
} 
else 
{ 
  /* okay to write status */ 
} 

Listing Eight
#define ERROR_NUM 64  /* max number of error strings to be queued */ 
#define ERROR_LEN 256  /* max string length for an error */ 
char error[ERROR_NUM][ERROR_LEN]; 

Listing Nine
#define ERROR_NUM 64  /* max number of error strings to be queued */ 
#define ERROR_LEN 256  /* max string length for an error */ 
typedef struct 
{ 
  unsigned char inuse; 
/* flag signifying Linux accessing */ 
  char error[ERROR_NUM][ERROR_LEN]; /* the errors themselves */ 
  int start; 
/* index of oldest error */ 
  int end; 
/* index of newest error */ 
  int num; 
/* number of items */ 
} MY_ERROR; 

Listing Ten 
/* initialize ring buffer; done once, perhaps in init_module() */ 
int error_init(MY_ERROR *errlog) 
{ 
 errlog->inuse = 0; 
 errlog->start = 0; 
 errlog->end = 0; 
 errlog->num = 0; 
 return 0; 
} 
/* queue an error at the end */ 
int error_put(MY_ERROR *errlog, const char *error) 
{ 
  if (errlog->num == ERROR_NUM) 
    { 
      /* full */ 
      return -1; 
    } 
  strncpy(errlog->error[errlog->end], error, ERROR_LEN); 
  errlog->end = (errlog->end + 1) % ERROR_NUM; 
  errlog->num++; 
  return 0; 
} 
/* dequeue the error off the front */ 
int error_get(MY_ERROR *errlog, char *error) 
{ 
  if (errlog->num == 0) 
    { 
      /* empty */ 
      return -1; 
    } 
  strncpy(error, errlog->error[errlog->start], ERROR_LEN); 
  errlog->start = (errlog->start + 1) % ERROR_NUM; 
  errlog->num--; 
  return 0; 
} 

Listing Eleven
char error[ERROR_LEN];  /* place to copy error */ 
/* set in-use flag in shared memory */ 
errlog->inuse = 1; 
/* copy error out */ 
if (0 != error_get(errlog, error)) 
{ 
  /* empty */ 
} 
else 
{ 
  /* handle it */ 
} 
/* clear in-use flag in shared memory */ 
errlog->inuse = 0; 

Listing Twelve
char error[ERROR_LEN];  /* place to compose error */ 
/* check for in-use */ 
if (0 != errlog->inuse) 
{ 
  /* defer writing, perhaps incrementing deferral count */ 
} 
else 
{ 
  /* compose it */ 
  strcpy(error, "your error here"); 
  if (0 != error_put(errlog, error)) 
  { 
    /* full */ 
  } 
} 









5


