RTOS study notes

A, RTOS system configuration

        Overall, the general release version of linux are not real-time systems, the general release version of linux precisely time-sharing system, more emphasis on multi-user time-sharing calls.

Dimensional design process, considered more of a concurrent nature of the system, to ensure a timely response task application processing needs of each user. In real-time systems, it is necessary

Ensure real-time tasks to complete the task within the stipulated time, and therefore how to ensure real-time tasks can perform real-time operating system is the core issue of scheduling mechanism. N can thus be preemptive

Scheduling strategy is the operating system kernel scheduling policy options necessary to ensure the real-time task of the highest priority, once ready is completed, regardless of the load on the system, are able to obtain

The right to use the CPU, to ensure real-time task execution.

       Sentence summary is this: Change the kernel configuration, the default sub-time slice scheduling becomes available preemption.

Getting the sources

First, the kernel version should be chosen. After this, take a look if the PREEMPT_RT patch is available for this particular version.

The source of the desired version has to be downloaded (for the Linux kernel as well as for the PREEMPT_RT patch). This example is based on the Linux kernel version 4.4.12.

$ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.4.12.tar.xz
$ wget https://www.kernel.org/pub/linux/kernel/projects/rt/4.4/patch-4.4.12-rt19.patch.xz

After downloading, unpack the archives and patch the Linux kernel:

$ xz -cd linux-4.4.12.tar.xz | tar xvf -
$ cd linux-4.4.12
$ xzcat ../patch-4.4.12-rt19.patch.xz | patch -p1

Configuring the kernel

The only necessary configuration for real-time Linux kernel is the choice of the “Fully Preemptible Kernel” preemption model (CONFIG_PREEMPT_RT_FULL). All other kernel configuration parameters depend on system requirements. For detailed information about how to configure a kernel have a look at Linux kernel documentation.

When measuring system latency all kernel debug options should be turned off. They require much overhead and distort the measurement result. Examples for those debug mechanism are:

  • DEBUG_PREEMPT
  • Lock Debugging (spinlocks, mutexes, etc. . . )
  • DEBUG_OBJECTS

Some of those debugging mechanisms (like lock debugging) produce a randomized overhead in a range of some micro seconds to several milliseconds depending on the kernel configuration as well as on the compile options (DEBUG_PREEMPT has a low overhead compared to Lock Debugging or DEBUG_OBJECTS).

However, in the first run of a real-time capable Linux kernel it might be advisable to use those debugging mechanisms. This helps to locate fundamental problems.

Building the kernel

Building the kernel and starting the kernel works similarly to a kernel without PREEMPT_RT patch.

 

Second, the real-time application development tasks

HOWTO build a simple RT application

The POSIX API forms the basis of real-time applications running under PREEMPT_RT. For the real-time thread a POSIX thread is used (pthread). Every real-time application needs proper handling in several basic areas like scheduling, priority, memory locking and stack prefaulting.

Basic prerequisites

Three basic prerequisites are introduced in the next subsections, followed by a short example illustrating those aspects.

Scheduling and priority

The scheduling policy as well as the priority must be set by the application explicitly. There are two possibilities for this:

  1. Using sched_setscheduler() 
    This funcion needs to be called in the start routine of the pthread before calculating RT specific stuff.
  2. Using pthread attributes 
    The functions  pthread_attr_setschedpolicy() and  pthread_attr_setschedparam()offer the interfaces to set policy and priority. Furthermore scheduler inheritance needs to be set properly to PTHREAD_EXPLICIT_SCHED by using  pthread_attr_setinheritsched(). This forces the new thread to use the policy and priority specified by the pthread attributes and not to use the inherit scheduling of the thread which created the real-time thread.

Memory locking

See here

Stack for RT thread

See here

Example

/*                                                                  
 * POSIX Real Time Example
 * using a single pthread as RT thread
 */
 
#include <limits.h>
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h> #include <sys/mman.h>   void *thread_func(void *data) { /* Do RT specific stuff here */ return NULL; }   int main(int argc, char* argv[]) { struct sched_param param; pthread_attr_t attr; pthread_t thread; int ret;   /* Lock memory */ if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1) { printf("mlockall failed: %m\n"); exit(-2); }   /* Initialize pthread attributes (default values) */ ret = pthread_attr_init(&attr); if (ret) { printf("init pthread attributes failed\n"); goto out; }   /* Set a specific stack size */ ret = pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN); if (ret) { printf("pthread setstacksize failed\n"); goto out; }   /* Set scheduler policy and priority of pthread */ ret = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); if (ret) { printf("pthread setschedpolicy failed\n"); goto out; } param.sched_priority = 80; ret = pthread_attr_setschedparam(&attr, &param); if (ret) { printf("pthread setschedparam failed\n"); goto out; } /* Use scheduling parameters of attr */ ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); if (ret) { printf("pthread setinheritsched failed\n"); goto out; }   /* Create a pthread with specified attributes */ ret = pthread_create(&thread, &attr, thread_func, NULL); if (ret) { printf("create pthread failed\n"); goto out; }   /* Join the thread and wait until it is done */ ret = pthread_join(thread, NULL); if (ret) printf("join pthread failed: %m\n");   out: return ret; }

 

Guess you like

Origin www.cnblogs.com/wuhanlin/p/11782698.html
Recommended