Embedded Digital System                             

 

Real Time Linux

 

1.      realtime linux installation

 

1)  Preparing for Installation

 

Downloading Linux Kernel

 

In order to compile the RTLinux kernel, first you need to download the

kernel for which RTLinux was built. To do so, note that there are

patches in the top-level directory by the name kernel_patch*. For

RTLinux 3.1, these files are:

 

  * kernel_patch-2.4.4

 

Where:

 

  * kernel_patch-2.4 is for Linux kernel 2.4.4 which can be found at

    http://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.4.tar.gz

 

In particular, RedHat 7.0 and 7.1 systems tend to have problems with

compiling RTLinux 2.4.x kernels because of wrong gcc versions in these

distributions. If you use a 2.4.x kernel on a recent RedHat system, you

need to change the

 It is in usr/src/linux-2.4 and linux-2.4.2/ Makefiel

CC              = $(CROSS_COMPILE)gcc

in the Linux kernel Makefile to

CC              = kgcc

 

 2) unpack the chosen Linux kernel into this directory:

 

      + rm -rf /usr/src/rtlinux

      + mkdir /usr/src/rtlinux

      + cd /usr/src/rtlinux

      + tar xzf /var/tmp/linux-2.4.4.tar.gz

 

 3) unpack the RTLinux distribution:

 

      + tar xzf /var/tmp/rtlinux-3.1.tar.gz

 

 4) Patch the kernel with the RTLinux patch:

 

      + cd linux

      + patch -p1 < ../rtlinux-3.1/kernel_patch-2.2.19

 

    OR, if you're using a 2.4.xx kernel:

 

      + cd linux

      + patch -p1 < /usr/src/rtlinux/kernel_patch-2.4.4

 

 5) Next, you need to configure the Linux kernel:

 

      + make config OR make menuconfig OR make xconfig

 

           tip===use default type

    Enabling APM support is not recommended. APM BIOS calls may have

    unpredictable effect on real-time performance.

 

    On Alpha machines, you need to enable RTLinux Support

    (CONFIG_RTLINUX). On i386 and PPC, this is done automatically.

 

    Please make sure to specify the correct CPU type for the target

    machine.

 

 6) Compile the Linux kernel and modules:

 

      + make bzImage

      + make modules

 

    Install the Linux kernel and modules:

 

      + make modules_install

      + cp arch/i386/boot/bzImage /boot/rtzImage For non-x86, please

        use procedures appropriate for your boot loader.

 

 7) (x86-only) Configure LILO. To do so, edit /etc/lilo.conf to contain

    the following piece (you only need to do this once):

 

    image=/boot/rtzImage

            label=rtlinux

            read-only

            root=/dev/hda1

 

    WARNING: replace root=/dev/hda1 in the above with your root

    filesystem. The easiest way to find out which filesystem it should

    be, take a look at the existing entry in your /etc/lilo.conf for

    "root=". Alternatively, type "df", and look for the line for "/" in

    the "mounted on" column. The corresponding entry in the

    "Filesystem" column is your root filesystem.

 

 8) Install LILO:

      + /sbin/lilo

 

    Restart the computer:

 

      + /sbin/shutdown -r now

 

    Load the RTLinux kernel: At the LILO: prompt, press "Shift" or

    "Tab". This will give you a listing of the available kernels.

    Enter:

 

      + rtlinux

 

    The RTLinux kernel should boot.

 

    The next step is to compile RTLinux proper.

 

      + cd /usr/src/rtlinux/rtlinux-3.1

      + ln -sf /usr/src/rtlinux/linux linux

 

 9) Configure RTLinux:

      + make config OR make menuconfig OR make xconfig

 

10) Compile RTLinux:

      + make

      + make devices

 

Post Installation and Running RTLinux Programs

 

To be able to run any programs, you must first load the rtlinux

modules. To do so, type:

 

  * cd /usr/src/rtlinux/rtlinux-3.1

·         scripts/insrtl

 

 

            ====finish====

 

 

  

1.    real time

·       fast

·       period

·       time related (timer)

2.    Why real time OS

           1) Twenty years ago, applications needing hard realtime were simple and were usually placed on dedicated, custom, isolated hardware. . Modern realtime applications must control systems such as factory floors connected to supply databases, telescopes connected to the Internet, cell phones generating graphical displays, routers, and telephone switches.

          2) For example, serious use of networked video and audio requires software that can maintain streams of data with hard realtime guarantees. As another example, variations in network transmit times for loosely coupled stand-alone servers on relatively slow networks has not been a problem, but a server cluster on 10G ethernet in which there are tightly connected distributed applications is a very different situation and one where real-time networking capabilities become an issue.

          3) The problem here is that to deliver the tight worst case timing performance needed for hard realtime, operating systems need to be simple, small, predictable - and optimized to minimize worst case performance.

3.    What is real time linux

1) RTLinux is a small, fast operating system, following the POSIX 1003.13 "minimal realtime operating system" standard.

2) RTLinux is a hard realtime operating system that coexists with the Linux OS. With RTLinux, it is possible to create realtime POSIX.1b threads that will run at precisely specified moments of time.

       3) Rtlinux put realtime components in a single, multithreaded, realtime process running on a bare machine. Applications are threads and signal handlers. This realtime process is simple, fast, predictable and optimized to minimize worst case performance.

      4) "virtual interrupt controller" prevents the low priority thread from blocking interrupts aimed at realtime signal handlers. the realtime components are never forced to wait for operations of the non-realtime thread. But non-rt thread must

 

       POSIX ------Portable Operating System Interface

 

4.    files system

1)   file “rtl.config” for compile and link for default compile

(1)            rtlinux directory

(2)            modules directory. /usr/rtlinux/modules contains the core RTLinux modules

(3)            include file.   /usr/rtlinux/include contains all the include files necessary for development projects.

(4)            library file.

(5)            Scripts and utility. /usr/rtlinux/bin contains RTLinux scripts and utilitie

(6)            man. /usr/doc/rtlinux/man contains the manual pages for RTLinux

  • /usr/rtlinux/include contains all the include files necessary for development projects.

  • /usr/rtlinux/examples contains the RTLinux example programs, which illustrate the use of much of the API.

  • /usr/doc/rtlinux/man contains the manual pages for RTLinux.

  • /usr/rtlinux/modules contains the core RTLinux modules.

  • /usr/rtlinux/bin contains RTLinux scripts and utilities

(7)             

2)   make file and rtl.mk.

           you must include the file

5.    Schedule the thread instead of process.

1)   Thread and process. Process contains the thread, but thread has same memory with its “parent”. Process does not. So thread  can schedule faster. Thread is small, less time is required compared with the Process.     

2)   In RTLinux, all threads share the Linux kernel address space.

6.    RT_linux and linux communication.

      three standard interfaces between realtime tasks and Linux.

1)                       Rtfifos

2)                       Share memory

3)                       pthread signal mechanism to allow realtime threads to generate soft interrupts for Linux.

 

 

7.    kernel between linux and Rtlinux

 

linux kernel.

      

 

 1)  Linux kernel separates the hardware from user-level tasks. The kernel has the ability to suspend any user-level task

 

RT-linux

1)   the RT-Linux is running between the hardware and linux kernel with real time tasks. 

2)   RT-Linux kernel action like hardware.  

3)   It introduces its own fixed-priority scheduler. This scheduler assigns the lowest priority to the standard Linux kernel, which then runs as an independent task. Then it allows the user to both introduce and set priorities for any number of realtime tasks.

4)   It intercepts all hardware interrupts.

5)   Hardware interrupts not related to realtime activities are held and then passed to the Linux kernel as software interrupts when the RTLinux kernel is idle and the standard Linux kernel runs.

6)   realtime interrupt service routine (ISR) is run. The RTLinux executive is itself nonpreemptible. It runs faster due to its small size and limited operation.

7)   This scheduler assigns the lowest priority to the standard Linux kernel, which then runs as an independent task. Then it allows the user to both introduce and set priorities for any number of realtime tasks.

8.    RT-linux Api ----------init_module and thread

1)    int init_module()and  void cleanup_module() instead of main(). It create object *.o file, 
instead of *.x  
2)    Threads are light-weight processes which share a common address space with linux kernel.
3)    To create a new realtime thread, we use the pthread_create(3) function. 
This function must only be called from the Linux kernel thread (i.e., using init_module()): 
                     #include <pthread.h>
                     int pthread_create(pthread_t * thread,
                    pthread_attr_t * attr,
                    void *(*start_routine)(void *),
                    void * arg);  
              
 

·          The ID of the newly created thread is stored in the location pointed to by ``thread''. 
The function pointed to by start_routine is taken to be the thread code. 
It is passed the ``arg'' argument to the start_rountine. 
 

 

4)    Cancel a tread 
1)    pthread_cancel(pthread thread)

2)    should join the thread in cleanup_module with pthread_join() 
for its resources to be deallocated
5)    fdsa

 

9.    RTL API--------------time

1)      provides several clocks that can be used for timing functionality, such as as referencing for thread scheduling and obtaining timestamps

2)      function

#include <rtl_time.h>

       int clock_gettime(clockid_t clock_id, struct timespec *ts);
       hrtime_t clock_gethrtime(clockid_t clock);
 

           struct timespec {
           time_t tv_sec; /* seconds */
           long tv_nsec; /* nanoseconds */
            };

3)   dfa

 

10.                       API-----schedules

1)      RTLinux provides scheduling, which allows thread code to run at specific times. RTLinux uses a pure priority-driven scheduler, in which the highest priority (ready) thread is always chosen to run

2)   FUNCTION

           int pthread_setschedparam(pthread_t thread,
                           int policy,
                           const struct sched_param *param);
 

·         The policy argument is currently not used in RTLinux, for futhure
·         The structure sched_param contains the sched_priority member. 
Higher values correspond 
to higher priorities.

             sched_get_priority_max(3) ,

 

·         fds 
 

 

      int pthread_make_periodic_np(pthread_t thread,
                              const struct itimerspec *its);
             struct itimerspec {
               struct timespec it_interval; /* timer period */
               struct timespec it_value;    /* timer expiration */
               };
 

      int pthread_wait_np(void);
        The actual execution timing is performed by this function. This function suspends the 
execution of the calling thread until the time specified by:  pthread_make_periodic_np(3) 
 

3)   DFA

 

11.                       examples program  ----thread

#include <rtl.h>
#include <time.h>
#include <pthread.h>
 

pthread_t thread;
void * start_routine(void *arg) {
   struct sched_param p;
   p . sched_priority = 1;
   pthread_setschedparam (pthread_self(), SCHED_FIFO, &p);
   pthread_make_periodic_np (pthread_self(), gethrtime(),
                             500000000);
 

   while (1) {           ////2 thread running time                        
     pthread_wait_np();
     rtl_printf("I'm here; my arg is %x\n", (unsigned) arg);
            }
   return 0;
}
 

int init_module(void) {
////   1 thread create

   return pthread_create (&thread, NULL, start_routine, 0);  
}
 

void cleanup_module(void) {
   pthread_cancel (thread);  ///3 thread terminate 
   pthread_join (thread, NULL);
}

 

 

12.                       How to compile and run

1)   edit Makfile.

All: hello.o

Include rtl.mk

 

2)   cd /usr/../rtlinux-3.1

type ./scripts/insrtl   or ./scripts/rmrtl to remove rtl

why it is in this directory---- it need the files in ./module/

3)   cd the directory where you have the object file

example ./hello/ ,    then type insmod hello.o or rmmod hello to remove it.

13.                       examples for hardware realtime

           1) isa card

#include <rtl.h>

#include <rtl_sync.h>

#include <time.h>

#include <pthread.h>

#include <asm/io.h>

#include <linux/kd.h>

 

pthread_t thread;

unsigned int intr_handler(unsigned int irq, struct pt_regs *regs)

{

 

  rtl_printf("real time interrupt from EISA \n");

                       

  rtl_hard_enable_irq(9);     //<-- if got an irq, reenable irq

 

  return 0;

}

 

void * start_routine(void *arg)

{

struct sched_param p;

      

   p.sched_priority = 1;

   pthread_setschedparam (pthread_self(), SCHED_FIFO, &p);

 

  // pthread_make_periodic_np (pthread_self(), gethrtime(), 100000); 

   //100000ns = 10 kHz

  

   while (1)

     {    

     pthread_wait_np();       //creates a periodic output of

      }

   return 0;

}

 

int init_module(void) {       //this init module will enable

int status;             //your interrupt

rtl_irqstate_t f;

  

   rtl_no_interrupts(f);

  

   status = rtl_request_irq(9, intr_handler);   //if IRQ-handler is OK

   if(!status)

   {

     rtl_printf("rtl_request_irq is ok\n"); //disp on the screem

   }                      

 

   outb_p(0x20, 0x20);

   //0x20 is the addres of OCW2, VALUE 20 is for nonspecific EOI

  

   rtl_hard_enable_irq(9);

 

   rtl_restore_interrupts(f);

 

   return pthread_create (&thread, NULL, start_routine, 0);

 

}

 

void cleanup_module(void) {   //this cleanup module disables

   rtl_free_irq(9);           //your interrupt

   pthread_delete_np (thread);

}

 

2)           print

#include <rtl.h>

#include <rtl_sync.h>

#include <time.h>

#include <pthread.h>

#include <asm/io.h>

#include <linux/kd.h>

 

pthread_t thread;

unsigned int intr_handler(unsigned int irq, struct pt_regs *regs)

{

   //outb(0, 0x378);          //this is our interrupt handler

  rtl_printf("real time interrupt from lpt \n");

                        //which resets the output of 5V on pin 2

  rtl_hard_enable_irq(7);     //<-- if got an irq, reenable irq

 

  return 0;

}

 

void * start_routine(void *arg)

{

struct sched_param p;

      

   p . sched_priority = 1;

   pthread_setschedparam (pthread_self(), SCHED_FIFO, &p);

 

   pthread_make_periodic_np (pthread_self(), gethrtime(), 1000000000000); 

   //100000ns = 10 kHz

 

   while (1)

     {                        //we have a periodic trigger which

     pthread_wait_np();       //creates a periodic output of

     outb(3, 0x378);          //+5V on pins 2 & 3.

     }

   return 0;

}

 

int init_module(void) {       //this init module will enable

int status;             //your interrupt

rtl_irqstate_t f;

  

   rtl_no_interrupts(f);

  

   status = rtl_request_irq(7, intr_handler);   //if IRQ-handler is OK

   if(!status)

   {rtl_printf("rtl_request_irq is ok "); //this will output 0

   }                                //on your console

   /* enbable parallel port interrupt */

   outb_p(inb_p(0x37A) | 0x10, 0x37A);

   // 0x10 ===the porta is for input

 

   outb_p(inb_p(0x21) & (~0x80), 0x21);

  //0X21 is the addr for OCW1, ~80 IS for enable M7,

  // M7 is for IR7, and ir7 is for printer, chek 80x86 p433

 

   outb_p(0x20, 0x20);

   //0x20 is the addres of OCW2, VALUE 20 is for nonspecific EOI

   rtl_hard_enable_irq(7);

 

   rtl_restore_interrupts(f);

  

   outb(0, 0x378); //before we start reset any output on the parallel port

  

   return pthread_create (&thread, NULL, start_routine, 0);

}

 

void cleanup_module(void) {   //this cleanup module disables

   rtl_free_irq(7);           //your interrupt

   pthread_delete_np (thread);

}

 

 14.                       RTLinux Inter-Process Communication (IPC)

1)      Why IPC

     The general philosophy of RTLinux requires the realtime component of an application to be lightweight, small and simple. Big program need to split into small ones, the IPC is required to communicate between them and linux thread.

2)   FIFO

(1)               Realtime FIFOs are First-In-First-Out queues that can be read from and written to by Linux processes and RTLinux threads.

(2)            To use the FIFOs, the system/rtl_posixio.o and fifos/rtl_fifo.o Linux modules must be loaded in the kernel

(3)            RT-FIFOs are Linux character devices with the major number of 150. Device entries in /dev are created during system installation. The device file names are /dev/rtf0, /dev/rtf1, etc., through /dev/rtf63

(4)            Api CALL

                   Before a realtime FIFO can be used, it must be initialized and must only be called from the Linux kernel thread (i.e., from init_module()

           #include <rtl_fifo.h>
           int rtf_create(unsigned int fifo, int size);
           int rtf_destroy(unsigned int fifo);

                      rtf_create allocates the buffer of the specified size for the fifo buffer. The fifo argument corresponds to the minor number of the device. rtf_destroy deallocates the FIFO.

         After the FIFO is created, the following calls can be used to access it from RTLinux threads: open(2) , read(2) , write(2) and close(2).  You can also use the RTLinux-specific functions rtf_put (3) and rtf_get (3) .

 

 

(5)         ./Examples/frank/

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

#include "control.h"

 

 

#define BUFSIZE 70

 

char buf[BUFSIZE];

 

int main()

{

      fd_set rfds;

        struct timeval tv;

        int retval;

      int fd0, fd1, ctl;

      int n;

      int i;

      struct my_msg_struct msg;

     

      if ((fd0 = open("/dev/rtf1", O_RDONLY)) < 0) {

            fprintf(stderr, "Error opening /dev/rtf1\n");

            exit(1);

      }

 

      if ((fd1 = open("/dev/rtf2", O_RDONLY)) < 0) {

            fprintf(stderr, "Error opening /dev/rtf2\n");

            exit(1);

      }

 

      if ((ctl = open("/dev/rtf3", O_WRONLY)) < 0) {

            fprintf(stderr, "Error opening /dev/rtf3\n");

            exit(1);

      }

 

      /* now start the tasks */

      msg.command = START_TASK;

      msg.task = 0;

      msg.period = 500000;

      if (write(ctl, &msg, sizeof(msg)) < 0) {

            fprintf(stderr, "Can't send a command to RT-task\n");

            exit(1);

      }

      msg.task = 1;

      msg.period = 200000;

      if (write(ctl, &msg, sizeof(msg)) < 0) {

            fprintf(stderr, "Can't send a command to RT-task\n");

            exit(1);

      }

 

      for (i = 0; i < 100; i++) {

            FD_ZERO(&rfds);

            FD_SET(fd0, &rfds);

            FD_SET(fd1, &rfds);

            tv.tv_sec = 1;

            tv.tv_usec = 0;

 

            retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);

            if (retval > 0) {

                  if (FD_ISSET(fd0, &rfds))  ///check if there is data

                        {

                        n = read(fd0, buf, BUFSIZE - 1);

                        buf[n] = 0;

                        printf("FIFO 1: %s\n", buf);

                  }

                  if (FD_ISSET(fd1, &rfds)) {

                        n = read(fd1, buf, BUFSIZE - 1);

                        buf[n] = 0;

                        printf("FIFO 2: %s\n", buf);

                  }

            }

 

       }

       fprintf(stderr, "frank_app: now sending commands to stop RT-tasks\n");

      /* stop the tasks */

      msg.command = STOP_TASK;

      msg.task = 0;

      if (write(ctl, &msg, sizeof(msg)) < 0) {

            fprintf(stderr, "Can't send a command to RT-task\n");

            exit(1);

      }

      msg.task = 1;

      if (write(ctl, &msg, sizeof(msg)) < 0) {

            fprintf(stderr, "Can't send a command to RT-task\n");

            exit(1);

      }

      return 0;

}

 

 

 

3)   mutex

Mutual exclusion refers to the concept of allowing only one task at a time (out of many) to read from or write to a shared resource. Without mutual exclusion, the integrity of the data  found in that shared resource could become compromised.

 ( 1) RTLinux supports the POSIX pthread_mutex_ family of functions (include/rtl_mutex.h). Currently the following functions are available:

·   pthread_mutexattr_getpshared(3)

·   pthread_mutexattr_setpshared(3)

·   pthread_mutexattr_init(3)

·   pthread_mutexattr_destroy(3)

·   pthread_mutexattr_settype(3)

·   pthread_mutexattr_gettype(3)

·   pthread_mutex_init(3)

·   pthread_mutex_destroy(3)

·   pthread_mutex_lock(3)

·   pthread_mutex_trylock(3)

·   pthread_mutex_unlock(3)

See examples/mutex for a test program.

  

15.                       Soft and Hard Interrupts

                 #include <rtl_core.h>
                  int rtl_request_irq(unsigned int irq,
                     unsigned int (*handler) (unsigned int,
                     struct pt_regs *));
                 int rtl_free_irq(unsigned int irq);
 

                 int rtl_get_soft_irq(
         void (*handler)(int, void *, struct pt_regs *),
         const char * devname);
         void rtl_global_pend_irq(int ix);
         void rtl_free_soft_irq(unsigned int irq);
          
        Handler 
       unsigned int intr_handler(unsigned int irq, struct pt_regs *regs)

 

TOP  HOME

Embedded  Digital System Co.,Ltd. CANADA 嵌入数码系统公司 Email:embedigital@yahoo.com

copy right © 2002 All Rights Reserved