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 /* open() */ #include /* 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 #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 /* sizeof() */ #include /* 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