Inside Real-Time Linux
by Jerry Epplin


Listing One
/* producer.c -- continually sends data at fixed intervals to a consumer of 
 * data. This structure can be used for a data-acquisition application.
 * Written by Jerry Epplin
 */

#ifndef MODULE
#define MODULE
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/errno.h>
//#include <linux/cons.h>

#include <rtl_sched.h>
#include <rtl_fifo.h>

RT_TASK ProducerTask;  /* handle for the task */

/* data to be sent to the Linux process */
static char *Data[] = { "This ", "data ", "is ", "sent ", "to ", 
                                                   "the ", "consumer.\n" };
/* number of data elements */
static const int NumData = sizeof(Data) / sizeof(char *);

static const int FIFO_NUM = 1;  /* FIFO handle */

static const int MSEC_INTVL = 100;  /* msecs between producer events */

/* Producer() -- Task which produces data, sending
 * it to the Linux process for consumption.
 */
static void Producer(int t)
{
  int idx, ret;
  /* Keep sending data to the consumer at */
  /* periodic intervals. */
  for (idx=0 ; ; idx=(idx+1)%NumData)
  {
    /* wait until this task is scheduled */
    if ((ret = rt_task_wait()) != 0)
      printk("Producer() -- rt_task_wait() failed with %d.\n", ret);
    /* send data to the consumer process */
    if ((ret = rtf_put(FIFO_NUM, Data[idx], strlen(Data[idx]))) != 0)
      printk("Producer() -- rtf_put() failed with %d.\n", ret);
   }
}
/* init_module() -- Called by kernel when module is
 * loaded with 'insmod'.  Creates the FIFO and starts the task.
 */
int init_module(void)
{
  int ret;
  /* create the FIFO */
  if ((ret = rtf_create(FIFO_NUM, 2048)) != 0)
    printk("init_module() -- rtf_create() failed with %d.\n", ret);

  /* start the task */
  if ((ret = rt_task_init(&ProducerTask, Producer, 0, 3000, 4)) != 0)
    printk("init_module() -- rt_task_init() failed with %d.\n", ret);

  /* set up the task for periodic scheduling */
  if ((ret = rt_task_make_periodic(&ProducerTask, rt_get_time(), 
                                                 1000*MSEC_INTVL)) != 0)
    printk("init_module() -- rt_task_make_periodic() failed with %d.\n", ret);

  return 0;
}
/* cleanup_module() -- Called by kernel when module
 * is unloaded with 'rmmod'.  Removes the FIFO and deletes the task.
 */
void cleanup_module(void)
{
  rtf_destroy(FIFO_NUM);
  rt_task_delete(&ProducerTask);
}


Listing Two
/* consumer.c -- consumer of data produced by producer
 * Written by Jerry Epplin
 */

#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <rtl_fifo.h>
#include <rtl_time.h>

#define BUFSIZE 70

char buf[BUFSIZE];

int main()
{
  fd_set rfds;
  int i, n, ret;
  int fd0;
  
  /* open the RT-FIFO device */
  if ((fd0 = open("/dev/rtf1", O_RDONLY)) < 0) {
    fprintf(stderr, "Error opening /dev/rtf1\n");
    exit(1);
  }
  /* show the data for a while */
  for (i=0; i<21 ; ++i)
  {
    FD_ZERO(&rfds);
    FD_SET(fd0, &rfds);

    /* wait until data is present */
    ret = select(FD_SETSIZE, &rfds, NULL, NULL, NULL);
    if (ret > 0)
    {
      if (FD_ISSET(fd0, &rfds))
      {
        /* read the data out and display it */
        n = read(fd0, buf, BUFSIZE - 1);
        buf[n] = '\0';
        printf("%s", buf);
      }
    }
    else
      printf("select() failed with %d.\n", ret);
  }
  return 0;
}




3


