Vous êtes sur la page 1sur 44

INTRODUCTION

TO
REAL-TIME PROGRAMMING
IN RT-LINUX
Sections

1. RT-Linux overview
2. Introduction to Real Time Program
3. RT-Linux API
– Thread Programming
– Time Measurement
– FPU
1. Inter-Processes Communication
2. Memory Access
3. Interrupt Programming
4. Sample RT- Program
5. RT-Linux Command Overview
RT-Linux Overview
RT-Linux Concepts

• RT-Linux is a patch/layer over Linux kernel.

• Why it is made as a patch/layer ?


– All aspects of kernel operation that lead to unpredictability can’t be eliminated.
– Easy to maintain.
– Promotes future development in Linux

• RT-Task
– Don’t use virtual memory.
– Don’t execute Linux system calls.
– Privileged
– Don’t have access to FPU.
– Error can bring the system down.
Linux Kernel Architecture

Pitfalls of Linux Kernel


• Gives equal importance to all user processes.
• Process completion time is unpredictable
RT-Linux Kernel Architecture

Priorities Task

Scheduling based purely on priority

Runs Linux processes as low priority task.

Unpredictability avoided by its simple size and limited operations

Introduction to Real Time Program
Real Time Program concepts

• They are Modules (.o files) not stand-alone


applications.
• Major components of RT-Linux Program.
– int init_module()
– void cleanup_module()
• Compile using –c flag argument to gcc.
• To execute, load it into RT-Linux kernel.
• Steps to convert Linux application into RT-Linux
module
– Replace main() with init_module() & cleanup_module().
– Compile it into object file (.o) not as an exe
RT-Linux Application Programming Interface(API)
RT-Linux API Calls for

• Thread programming

• Time Facilities

• Enable Floating Point operations


RT-LINUX API CALLS FOR THREAD
PROGRAMMING
Threads

• Thread Definition: Threads are light-weight processes which


shares same address space.

• Thread are used to increase the processor efficiency by


parallel executions.

• RT-Linux threads shares the Linux kernel address


space.

• Linux kernel threads are also conceptually considered


as RT-Linux thread.
API Calls for RT-Linux Thread programming

Creating RT-Linux thread

int pthread_create(pthread_t *
thread,pthread_attr_t * attr,
void *(*start_routine)(void *),void * arg);

• Header file <pthread.h> should be included for all pthread


functions.
• Only be called from Linux Kernel thread.
• This thread is created using attributes specified in attr thread
attributes object.
• Attributes can be set using the following pthread functions
– pthread_attr_init()
– pthread_attr_setschedparam()
– pthread_attr_getschedparam()
API Calls for RT-Linux Thread programming

Scheduling RT-Linux thread

RT-Linux provides scheduling, which allows thread code to run at


specific times. RT-Linux uses a pure priority-driven scheduler, in
which the highest priority (ready) thread is always chosen to run.

• Functions to set thread priority


– pthread_attr_setschedparam() - To set priority at creation time
– pthread_setschedparam() - To set priority after thread
creation.

• Functions to make thread periodic:


– pthread make periodic np();
– pthread wait np();
API Calls for RT-Linux Thread programming

Waking and Suspending RT-Linux thread

Interrupt-driven RT-Linux threads can be created using


the thread wakeup and suspend functions:

• int pthread_wakeup_np(pthread_t thread);


– awakes the specified thread which is in suspended state.

• int pthread_suspend_np(void);
– Suspends the thread.
– Should be called from within the thread.
Mutual Exclusion

• Definition: 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.

• Need: Without mutual exclusion, the integrity of the


data found in the shared resource could become
compromised.
Methods to achieve Mutual Exclusion

Methods used to achieve Mutual Exclusion in RT-Linux:

• POSIX pthread_mutex_* family of functions.


– Header file <rtl_mutex.h> must be included.
– Following Mutex types are supported.
» PTHREAD MUTEX NORMAL
» PTHREAD MUTEX SPINLOCK

• POSIX semaphores.
API Calls for RT-Linux Thread programming

Terminating RT-Linux thread

Two methods are:

• Use pthread_cancel() & pthread_join() function pair


• Use pthread_delete_np() function
RT-LINUX API CALLS FOR TIME
MEASUREMENTS
RT-Linux Supported Clocks
RT-Linux provides several clocks that can be used for timing
functionality,such as
• Reference for thread scheduling
• Obtaining timestamps.

Currently supported clocks are:

• CLOCK MONOTONIC:
– This POSIX clock runs at a steady rate, and is
never adjusted or reset.
• CLOCK REALTIME:
– This is the standard POSIX RT clock. Currently,it is the same as CLOCK
MONOTONIC. It is planned that in future versions of RTLinux this clock will give
the world time.
• CLOCK RTL SCHED:
– The clock that the scheduler uses for task scheduling.
API Calls for Time Measurement in RT-Linux

Functions to read current clock reading


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

Data Structures description:


struct timespec
{
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
hrtime_t - a single 64-bit number of nanoseconds
API Calls for Time Measurement in RT-Linux

Time Format Conversion Functions:

• struct timespec to hrtime_t:


– hrtime_t timespec_to_ns(const struct timespec *ts);

• hrtime_t to struct timespec:


– struct timespec timespec_from_ns(hrtime_t t)
– const struct timespec * hrt2ts(hrtime_tvalue);
Enabling Floating Point Operation in RT-Task

• The use of floating-point operations in RTL POSIX threads is


prohibited by default. To enable FP operations in the thread.
The following function is used.

int pthread_setfp_np (pthread_tthread, int flag);

• To enable FP operations set the flag to 1.


• To disable FP operations, pass 0.
• It is a RT-Linux specific function.
RT-Linux Inter-process
Communication(IPC)
RT-Linux IPC Methods

• Need for RT-Task and Linux Process communication:

– RT-Linux Portion of an application must be as simple and small as


possible. This implies only critical features be implemented in Real
Time. This necessitates communication between RT-Task and Linux
processes.

• Communication Methods:
– Real Time FIFO.
– Shared Memory.
Real-Time FIFO

• Linux Char Devices with major no. 150.


• Can be read from and written to by both Linux processes
and RT-Linux threads.
• Unidirectional.
• Modules rtl_posixio.o and rtl_fifo.o are needed.
• Maximum No. of RTL FIFOs are configurable during
system compilation.(default : 64).
• Device File for RTL FIFO are in directory /dev/ with names
rtfx. (x - FIFO number (0-63)).
Real-Time FIFO Functions

RT-FIFO Initialization & destruction

• int rtf_create(unsigned int fifo, int size);


– allocates buffer of specified size for the fifo buffer.
– fifo argument corresponds the minor number of the
device.
– Header <rtl_fifo.h> is necessary.
– Can be called only from Linux kernel thread
(init_module).

• int rtf_destroy(unsigned int fifo);


– deallocates the FIFO.
Real-Time FIFO Functions

Accessing RT-FIFO:

• From RT-Linux threads:


– open(), close()
– read(), write()

• From Linux Processes:


– All Unix File I/O Functions can be used.
Shared Memory
• mbuff driver can be used.
• mbuff.o module get loaded into the kernel by giving the
command rtlinux start.
• Header file <mbuff.h> should be included.
• Basic Functions:
void * mbuff_alloc(const char *name, int size);
– Creates shared memory of specified size if shared memory with the
given doesn’t exist.
– If shared memory with given name already exist, returns pointer to
shared memory and increments the ref count.
void mbuff_free(const char *name, void * mbuf);
– Decrements reference count of the shared memory.
– If ref count becomes zero, deallocates the allocated mem buffer.
HARD WARE INTERACTION
Hardware Interaction

Accessing Physical Memory and I/O Ports from RT-


Linux threads are essential for programming
hardware devices.

Methods for accessing Physical Memory:


• Using /dev/mem device.
– rtl_posixio.o module is needed.
– Open mem, mmap it and do read/write operation.
– Can be called only in Linux kernel thread.
• Using ioremap call.
– char *ptr = ioremap(PHYS_AREA_ADDRESS,
PHYS_AREA_LENGTH);
– It is a Linux kernel function.
Accessing I/O Ports in RT-Linux Thread

IO port access functions (specifically for x86


architecture) are as follows:

• Output a byte to a port:


– void outb(unsigned int value, unsigned short port)
– void outb_p(unsigned int value, unsigned short port)
• Output a word to a port:
– void outw(unsigned int value, unsigned short port)
– void outw_p(unsigned int value, unsigned short port)
Accessing I/O Ports in RT-Linux Thread

• Read a byte from a port:


– char inb(unsigned short port)
– char inb_p(unsigned short port)
• Read a word from a port:
– short inw(unsigned short port)
– short inw_p(unsigned short port)

• Functions with the ‘‘ p’’ suffix (e.g., outb p)


provide a small delay after reading or writing
to the port.
• <asm/io.h> header is needed for all these
functions.
INTERRUPT PROGRAMMING
Types of Interrupt in RT-Linux.

Types of interrupts in RT-Linux:

• Hard Interrupts
– Lower latency.
– Very limited set of kernel functions may be called
from the hard interrupt handlers.

• Soft Interrupts.
– Normal Linux kernel interrupts.
– Can call some Linux kernel functions.
– Do not provide hard real time performance.
Hard Interrupts

• int rtl_request_irq(unsigned int irq, unsigned int


(*handler) (unsigned int, struct pt_regs *));
– Used for registering interrupt handler for given IRQ line.

• int rtl_free_irq(unsigned int irq);


– Used for unregistering the ISR registered for IRQ line.
Soft Interrupts
• int rtl_get_soft_irq (void (*handler)(int, void *, struct
pt_regs *),const char * devname);
– allocates a virtual irq number and installs the handler
function for it.

• void rtl_global_pend_irq(int ix);


– Used to trigger the virtual Interrupt.
– Can be called from real time thread and RT ISR.

• void rtl_free_soft_irq(unsigned int irq);


– frees the allocated virtual interrupt.
Sample Real Time Application
Code Listing
#include <rtl.h>
#include <time.h>
#include <pthread.h>

pthread_t thread;
void * start_routine(void *arg);

int init_module(void)
{
return pthread_create (&thread, NULL, start_routine, 0);
}

void cleanup_module(void)
{
pthread_cancel (thread);
pthread_join (thread, NULL);
}
Code (continues..,)
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)
{
pthread_wait_np();
rtl_printf("I’m here; my arg is %x\n", (unsigned) arg);
}
return 0;
}
Essential RT-Linux Commands Overview
RT-Linux Commands

• rtlinux start
– To insert rtlinux only
• rtlinux start mymodule
– To insert rtlinux and mymodule.o module
• rtlinux stop
– To remove rtlinux module only
• rtlinux stop mymodule
– To remove rtlinux and mymodule.o module.
• rtlinux status
– To check status of rtlinux only
• rtlinux status mymodule
– To check status of rtlinux and mymodule
RT-Linux Commands
• insmod mymodule.o
– To insert the module mymodule.o
• modprobe mymodule.o
– To insert the module mymodule.o
– Inserts module intelligently
• rtl-config
--modules
--module_dir
--docs
--linux
--prefix
--arch
--version
--rtlversion
--linuxversion
--cc
RT-Linux Commands

• usleep <time in microsec)


– To sleep for specified micro seconds.
• uname
– To get the current system name.
• sysconf
– To get configuration information at run time.

Vous aimerez peut-être aussi