[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: RT linux



HI

  i Tried the mbuff example code, what i have written
  still its giving  error, when i am running makefile.
  here i am sending the entire code,
  could pls hel to sort out this porblem
the problem is as follows

i   am working in RT linux Shared memory,
  ie I tried communiction between  real time task and linux Process.
  while running Makefile , its giving error that
   " Undefined reference to  shm_allocate( )  in mbuff.h and its giving some
 line number"

    the same is the case with shm_deallocate().
    but actually, i  didn't  use anyware in my code, these functions.
instead i used the calls mbuff_* functions.
   what could be the reason.

    at the time of compiling my programme,  mbuff driver is already loaded.


 CODE  consists of four  files
   1. shmh.h header file
2. shmc.c which is a  file consists of common functions defined here
3.rtpc.c  this is a real time kernel module
4. appc.c applivcation module

code is as follows

________________________________________________

make file
---------------------

all: shmc.o rtmod.o appc

MYCFLAGS = -O2 -Wall
include ../../rtl.mk




shmc.o: shmc.c
        $(CC) ${INCLUDE} ${CFLAGS} ${MYCFLAGS} -c shmc.c

rtpc.o: rtpc.c
        $(CC) ${INCLUDE} ${CFLAGS} ${MYCFLAGS} -c rtpc.c

rtmod.o: rtpc.c shmc.c
        $(CC) ${INCLUDE} ${CFLAGS} ${MYCFLAGS} -c  rtpc.o shmc.o

appc: appc.c shmc.c
        $(CC) ${INCLUDE} ${CFLAGS} ${MYCFLAGS} -o appc appc.c shmc.c


#rtmod.o: rtpc.c shmc.c
#       $(CC) ${INCLUDE} ${CFLAGS} -c rtpc.c shmc.c

#test, remove any modules, load new ones and run app

test: all

# REMOVE  ADC_Stub, TEMP_RT modules


        @echo "started running script files "
        @echo "Type <return> to continue"
        @read junk
        (cd ../../; scripts/rmrtl)
        @echo "Now insert the fifo and scheduler"
        @echo "Type <return> to continue"
        @read junk
        (cd ../../; scripts/insrtl)
        @echo "Now start the real-time tasks  module"
        @echo "Type <return> to continue"
        @read junk

#       @insmod /usr/src/rtlinux-*/drivers/mbuff/mbuff.o
#       @insmod /usr/src/rtlinux-*/drivers/rt_com/rt_com.o


        @echo "Now starting the application"

clean:
        rm -f *.o

include $(RTL_DIR)/Rules.make




------------------------------

header file
--------------------
ifndef SHMH_H
#define SHMH_H


#define SHM_DEV_FILE ("/dev/mbuff")
#define SHM_NAME        ("control")
#define SHM_SIZE        (sizeof(MY_STRUCT))


/*
  common.h

  Declarations for command/status shared memory interface
  */



/* the command structure */
typedef struct
{
  unsigned char inuse;
  int command;

 int command_number;
} MY_COMMAND;

/* some commands we can have */
#define MY_COMMAND_RESET 1      /* reset heartbeat */

typedef struct
{
  unsigned char inuse;
  int command_echo;
  int command_number_echo;
  unsigned int heartbeat;       /* incremented every cycle */
} MY_STATUS;

#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;

typedef struct
{
  MY_COMMAND command;
  MY_STATUS status;
  MY_ERROR error;
} MY_STRUCT;

/* initialize ring buffer; done once, perhaps in init_module() */
extern int error_init(MY_ERROR *errlog);

/* queue an error at the end */
extern int error_put(MY_ERROR *errlog, const char *error);

/* dequeue the error off the front */
extern int error_get(MY_ERROR *errlog, char *error);

#endif /* SHARED_H */

-----------------------------------
/**  common function declared in one file is as below
---------------------------------------

/*
  SHARED.c

  Code for manipulating ring buffer, shared between Linux and
  RT processes
  */

#include <string.h>
#include "shmh.h"

/* 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;
}


-----------------------------
real time module rtpc.c starts from here
---------------------


*
  rtpc.c

  RT-Linux code for shared memory example
  */


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/errno.h>

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

#include <string.h>

#include "shmh.h"
#include<drivers/mbuff/mbuff.h>






#define RT_TASK_STACK_SIZE 1024
#define RT_TASK_PRIORITY 1
#define RT_TASK_CYCLE_TIME 0.010 /* seconds for each RT cycle */

/* useful conversion from secs to RTIME */
/* RT_TICKS_PER_SEC is 1193180, BTW */
#define SECS_TO_RTIME(secs) ((RTIME) (RT_TICKS_PER_SEC * secs))

/* the task structure */
static RT_TASK task1;
/* the pointer to shared memory, and our local copy */
static MY_STRUCT * my_struct_ptr = 0;
static MY_STRUCT my_struct;

/* the task code, run on a timer */
static void task_code(int t)
{
  char pending_error[ERROR_LEN]; /* spot for composing, transferring errors
*/

  for (;;)
    {
      /* read command */
      if (0 == my_struct_ptr->command.inuse)
        {
          /* copy command in */
          memcpy(&my_struct.command,
                 &my_struct_ptr->command,
                 sizeof(MY_COMMAND));
        }
      /* else just coast on old command */

      /* process command */
    if (my_struct.command.command_number !=
          my_struct.status.command_number_echo)
        {
          /* it's a `new command */

          /* echo command and command number in status */
          my_struct.status.command_echo =
            my_struct.command.command;
          my_struct.status.command_number_echo =
            my_struct.command.command_number;

          /* process it */
          switch (my_struct.command.command)
            {
            case MY_COMMAND_RESET:
              my_struct.status.heartbeat = 0;
              break;

            default:
              error_put(&my_struct.error, "unknown command");
              break;
            }



 }

      /* increment heartbeat */
      my_struct.status.heartbeat++;

      /* write status */
      if (0 == my_struct_ptr->status.inuse)
        {
          memcpy(&my_struct_ptr->status, &my_struct.status,
sizeof(MY_STATUS));
        }
      /* else it's in use, so defer status update */

      /* log error(s) */
      if (0 == my_struct_ptr->error.inuse)
        {
          /* we're queueing errors locally, so pop them off local ring
             and push them on shared memory ring */
          while (my_struct.error.num > 0)
            {
              error_get(&my_struct.error, pending_error);
              error_put(&my_struct_ptr->error, pending_error);
            }
        }


 /* else it's in use, so defer error logging */

      /* and wait on timer interrupt */
      rt_task_wait();
    }
}

/* called by insmod to load the module code and start it */
int init_module(void)
{


  /* set pointer to shared memory */

 my_struct_ptr =  (MY_STRUCT *) mbuff_alloc(SHM_NAME, SHM_SIZE) ;


  /* clear out in-use flags */
  my_struct_ptr->command.inuse = 0;
  my_struct_ptr->status.inuse = 0;
  my_struct_ptr->error.inuse = 0;

  /* clear out error ring buffer */



error_init(&my_struct_ptr->error);

  /* initialize shmem */
  my_struct_ptr->command.command = 0;
  my_struct_ptr->command.command_number = 0;
  my_struct_ptr->status.command_echo = 0;
  my_struct_ptr->status.command_number_echo = 0;
  my_struct_ptr->status.heartbeat = 0;

  /* initialize local copies of command, status, error */
  my_struct.command.command = 0;
  my_struct.command.command_number = 0;
  my_struct.status.command_echo = 0;
  my_struct.status.command_number_echo = 0;
  my_struct.status.heartbeat = 0;
  error_init(&my_struct.error);

  /* stuff a few errors, just to demonstrate queueing; these will
     get dumped to shared memory when task code runs */
  error_put(&my_struct.error, "initializing task...");


       /* initialize task code */
  rt_task_init(&task1,          /* RT_TASK * */
               task_code,       /* task code */
               0,               /* startup arg to task code */
               RT_TASK_STACK_SIZE, /* task stack size */
               RT_TASK_PRIORITY); /* priority */

  error_put(&my_struct.error, "done");
  error_put(&my_struct.error, "scheduling task...");

  /* schedule task code on periodic time interrupt */
  rt_task_make_periodic(&task1,
                        rt_get_time() + SECS_TO_RTIME(0.010),
                        (RTIME) (RT_TICKS_PER_SEC * RT_TASK_CYCLE_TIME));

  error_put(&my_struct.error, "done");

  return 0;
}

/* called by rmmod to remove the module */

void cleanup_module(void)
{

  mbuff_free( SHM_NAME,  (void *)my_struct_ptr   ) ;

  rt_task_delete(&task1);
}


/* end of rt module */
--------------------

--------------------
/* appcication part ( linux user appication) follows)
-----------



/*
  appc.c

  Linux process code for shared memory demonstration
  */

#include <stdio.h>              /* the usual, perror() */
#include <string.h>             /* strcmp(), memcpy() */
#include <unistd.h>             /* open(), close() */
#include <fcntl.h>              /* O_RDONLY */

#include </usr/src/rtlinux-3.0/drivers/mbuff/mbuff.h>

#include "shmh.h"               /* BASE_ADDRESS, error_get() */

#define MAP_FAILED ((void *) -1) /* omitted from Linux mman.h */



/* how many chars user can type */
#define INPUT_LEN 256


int  main()
{
        int fd;
        MY_STRUCT * my_struct_ptr;
        MY_STRUCT my_struct;
        char input[INPUT_LEN];
        char next_error[ERROR_LEN];

/* shared */


        if ((fd = open("/dev/mem", O_RDWR)) < 0)
        {
                printf("open /dev/mem");
                exit(1);
        }



  my_struct_ptr =  ( MY_STRUCT *) mbuff_alloc( SHM_NAME,SHM_SIZE) ;

  if (MAP_FAILED == my_struct_ptr)
    {
      perror("mmap");
      exit(2);
    }

  close(fd);                    /* fd no longer needed */

  /* now talk to user */
  while (! feof(stdin))
    {
      /* print prompt */
      printf("> ");
      fflush(stdout);

      /* get typed input */
      if (NULL == fgets(input, INPUT_LEN, stdin))
        {
          break;
        }

input[strlen(input)-1] = 0;

      /* now process it */
      if (! strcmp(input, "help"))
        {
          printf("reset           -- send reset heartbeat command\n");
          printf("status          -- shows status\n");
          printf("errors          -- shows errors\n");
          printf("quit/^D         -- quits\n");
        }
      else if (! strcmp(input, "reset"))
      {
        /* send reset command */
        my_struct.command.command = MY_COMMAND_RESET;

        /* set this command's in-use flag so it won't clear prematurely */
        my_struct.command.inuse = 1;

        /* stuff incremented command number */

 my_struct.command.command_number++;

        /* set shmem in-use flag directly */
        my_struct_ptr->command.inuse = 1;

        /* copy command to shmem */
        memcpy(&my_struct_ptr->command,
               &my_struct.command,
               sizeof(MY_COMMAND));

        /* clear shmem in-use flag directly */
        my_struct_ptr->command.inuse = 0;
      }
      else if (! strcmp(input, "status"))
        {
          /* set in-use flag */
          my_struct_ptr->status.inuse = 1;

          /* copy status from shmem */
          memcpy(&my_struct.status,
                 &my_struct_ptr->status,

  sizeof(MY_STATUS));

          /* clear in-use flag */
          my_struct_ptr->status.inuse = 0;

          /* print it */
          printf("command:        %d\n", my_struct.status.command_echo);
          printf("command number: %d\n",
my_struct.status.command_number_echo);
          printf("heartbeat:      %d\n", my_struct.status.heartbeat);
        }
      else if (! strcmp(input, "errors"))
        {
          /* set in-use flag */
          my_struct_ptr->error.inuse = 1;

          /* dequeue and print errors from shmem */
          while (my_struct_ptr->error.num > 0)
            {
              error_get(&my_struct_ptr->error, next_error);
              printf("%s\n", next_error);
            }

          /* clear in-use flag */

  my_struct_ptr->error.inuse = 0;
        }
      else if (! strcmp(input, "quit"))
        {
          break;
        }
      else
        {
          printf("? (%s)\n", input);
        }
    }


  mbuff_free(SHM_NAME,(void*) my_struct_ptr);

 exit(0);
}


----------------------------------------------------

Thanks

Chandu
These are of My Personal interests and Openions'



----- Original Message -----
From: Michael Barabanov <baraban@fsmlabs.com>
To: chandu Reddy <chandureddy@hclt.com>
Cc: <support@fsmlabs.com>
Sent: Monday, April 23, 2001 5:23 AM
Subject: Re: RT linux


> I suggest you look at the tracer/ code. It uses mbuff from both RT
> and user space.
>
> Michael.
>
> chandu Reddy (chandureddy@hclt.com) wrote:
> > HI
> >
> >   i   am working in RT linux Shared memory,
> >   ie I tried communiction between  real time task and linux Process.
> >   while running Makefile , its giving error that
> >    " Undefined reference to  shm_allocate( )  in mbuff.h and its giving
some
> > line number"
> >
> >    the same is the case with shm_deallocate().
> >
> >    but actually, i  didn't  use anyware in my code, these functions.
> >    instead i used the calls mbuff_* functions.
> >   what could be the reason.
> >
> >    at the time of compiling my programme,  mbuff driver is already
loaded.
> >
> >     I think problem with loading  mbuff driver.
> >       for this what i did was , just i used " make test"
> >       in the mbuff drivers directory, and i inserted that mbuff.o
> >     what i came to know that i have to modify that   "Makefile",
> >      but i couldn't get i  exactly have to change.
> >
> >   could u pls Help in this regard.
> >
> > Thanks
> > Chandu
> >
> >
> > ----- Original Message -----
> > From: Michael Barabanov <baraban@fsmlabs.com>
> > To: chandu Reddy <chandureddy@hclt.com>
> > Sent: Thursday, April 19, 2001 10:33 PM
> > Subject: Re: RT linux
> >
> >
> > > chandu Reddy (chandureddy@hclt.com) wrote:
> > > > HI
> > > >
> > > >  i am working in RT Linux
> > > >   could u pls let me know, kind of communication between  two real
time
> > tasks.
> > > >    ie since the tasks are  running in the same context as RT linux
> > process,
> > > >    is it possible to acheive communication between  two  Real time
> > tasks.
> > > >     if yes HOW TO?
> > >
> > > - rt-fifos, both same and different modules
> > > - semaphores
> > > - mutexes
> > > - shared memory (all memory is shared)
> > >
> > > >    i don't have plans to  use SMP,
> > > >     if that is the case,  shall i go for  threads.
> > > >
> > > >     i read that  in case of SMP,  rtlinix task is different than
thread.
> > > >      how actually it is different?
> > >
> > > They are the same (pthreads).
> > >
> > > > Doubt 4:
> > > >          is i  it really task is nothing but thread in case of uni
> > processor system??
> > >
> > > Yes.
> > >
> > > Michael.
> > >
>