I'm working on an embedded Linux project, using an arago distribution that is probably around version 3.3.
I have configured a high-resolution Linux timer to wake-up my process once per millisecond. This works ok but there are two issues with the timing:
A jitter in the wake-up time
Variability of the processing time when awake, despite the fact that the processing done by the process is constant.
I attribute these problems to the less-than real-time performance of Linux. But I need to
investigate ways of improving the real-time performance.
I have checked that the kernel is configured with the CONFIG_PREEMPT kernel option, which is good for real-time.
I have also applied the SCHED_FIFO scheduling class to my process:
struct sched_param schedparm;
memset(&schedparm, 0, sizeof(schedparm));
schedparm.sched_priority = 1; // lowest rt priority
sched_setscheduler(0, SCHED_FIFO, &schedparm);
but that made no difference.
I guess that a logical step is to apply the PREEMPT_RT patch to the kernel build, but I haven't identified how to do that yet.
Is there anything else I can do to improve the jitter / duration variability?
Or can anyone suggest an accessible tutorial on how to apply the PREEMPT_RT patch?
It seems PREEMPT_RT is the logical next step. Did you try this tutorial?
https://rt.wiki.kernel.org/index.php/RT_PREEMPT_HOWTO
Update: I suggest you look at how others build a preemptive kernel, e.g. here:
https://aur.archlinux.org/packages/linux-rt/
You can read the PKGBUILD to understand what is done.
If you use Debian testing, or LMDE for that matter, they have a precompiled PREEMPT_RT kernel in the repo for the x86 and amd64 architectures.
apt-get install linux-image-rt-686-pae
or
apt-get install linux-image-rt-amd64
Related
I am making a project which send out 40khz signal from antenna.
I have found the signal is not too accurate so I have decided to try a real-time kernel.
I run Raspbian Jessie on my Raspberry-Pi 2B.
After clean install, the script run without any problem.
bcm2835_delayMicroseconds could be run.
I follow this tutorial http://www.frank-durr.de/?p=203 compiled and installed the RT kernal.
However, the script could no longer be run successfully.
After showing "HIGH SLEEP", and it is held up.
This is the code snippet:
fprintf(stdout , "HIGH\n");
bcm2835_gpio_write(PIN, HIGH);
fprintf(stdout , "SLEEP\n");
bcm2835_delayMicroseconds(12);
fprintf(stdout , "LOW\n");
bcm2835_gpio_write(PIN, LOW);
fprintf(stdout , "SLEEP\n");
bcm2835_delayMicroseconds(12);
Do I miss anything when compiling the kernel?
To use PREEMPT_RT you just have to:
retrieve the configuration of your current kernel
retrieve the kernel sources
patch the kernel sources with the PREEMPT_RT patch (or obtain an already patched kernel)
configure the new kernel as the current kernel (i.e., using make oldconfig)
enable full preemtability in kernel config (e.g., by running make menuconfig).
compile the kernel in the standard way
install the new kernel
Therefore, no particular action is needed.
Then, if performance is still not sufficient, you may want to tune priorities of specific IRQ threads.
From your specific error, it seems that the new kernel has been conpiled with a different configuration than the current kernel (e.g., GPIOs not enabled).
I have just seen and remembered this thread.
About half year ago, I want to generate 40khz from a Raspberry.
But finally I found I am using the wrong tool.
I believe Raspberry cannot handle such a task, since it is running an OS.
I switched to Arduino, and the problem is solved immediately without any problem.
Using the right tool for your task is very important!
I am studying some documents regarding RT linux and qnx and confused about monolithic and microkernel.Some papers are telling that RT linux is monolithic and some are saying that microkernel. I am worried which is right ?? could you please some one answer my question ??
I know QNX is a microkernel Os and confused w.r.t RTlinunx.
Could someone tell me what is the differenec between the two real time operating system and also the below question.
RT linux is monolithic or microkernel ??
IMHO, there is no actual RT Linux1. There are only approaches of adding RT compatibily features² to the official genereal purpose Linux kernel. Examples are RTAI, Xenomai or the PREEMPT_RT patch. Thus, they're all using the same kernel which is definitely a monolithic kernel (and as for Linus this will pretty sure stay this way).
However, a paper³ by Jae Hwan Koh and Byoung Wook Cho about RTAI and Xenomai performance evaluation puts it like this (which indeed sounds more like a separate kernel approach):
RTAI and Xenomai are interfaces for real-time tasks rather than real-time operating systems. Therefore, an OS is needed to use them; Linux is most widely used. In RTAI and Xenomai, the Linux OS kernel is treated as an idle task, and it only executes when there are no real-time tasks to run. The figure below shows the architectures and versions of the real-time embedded Linux used [here]. RTAI and Xenomai are conceptually homogeneous, and they both use a general-purpose Linux kernel and real-time API. However, there is a remarkable contrast.. [in way they handle certain things].
Another picture that if found⁴ supports this point-of-view as well, i.e. having a kernel running on-top of another one as idle task.
1 Having said that, there used to be a OS (kernel) named RTLinux which was working quite similar like the other approaches mentioned in my answer above, ie it runs the entire Linux kernel as a fully preemptive process [1] [2]. RTLinux later merged into the products of Wind River (VxWorks) and did also influenced the work around RTAI. Couldn't find a source about the kernel type.
2 in other words a "real-time extension"
3 "Real-time Performance of Real-time Mechanisms for RTAI and Xenomai in Various Running Conditions", 2013, International Journal of Control and Automation
4 unfortunately I could not determine its source yet.
RT Linux has both linux kernel as well as real time kernel. The real time kernel has higher priority over linux kernel. Please refer following article for details.
http://www.cs.ru.nl/~hooman/DES/RealtimeLinuxBasics.pdf
In my embedded C code, I need to run a function at an accurate 4kHz rate to simulate some waveform. I am running some Linux 3.10 kernel with PREEMPT-RT patch. The question is very similar to this post:
Linux' hrtimer - microsecond precision?
But my particular question is: does the recent PREEMPT-RT kernel provide some user API or some more convenient way for such purpose?
I have just come up with an alternative solution by using Xenomai framework. I built and installed the Xenomai in my Linux and installed Xenomai userspace support. Then there is a simple API rt_task_set_periodic allows you to schedule periodic task precisely.
Here is the example:
https://github.com/meeusr/xenomai-forge/blob/master/examples/native/trivial-periodic.c
In my opinion.. no.
PREEMPT_RT only let the kernel be interrupted if needed. My personal opinion is to try to find a delay routine and trim it whit the oscilloscope.
I had a similar issue and I found that "sleep" and "usleep" are not so accurate, I ended up writing my own delay routine.
Hope this helps.
I have a question about changing kernel frequency.
I compiled kernel by using:
make menuconfig(do some changes in config)
(under Processor type and features->Timer frequency to change frequency)
1.fakeroot make-kpkg --initrd --append-to-version=-mm kernel-image kernel-headers
2.export CONCURRENCY_LEVEL=3
3.sudo dpkg -i linux-image-3.2.14-mm_3.2.14-mm-10.00.Custom_amd64.deb
4.sudo dpkg -i linux-headers-3.2.14-mm_3.2.14-mm-10.00.Custom_amd64.deb
then say if I want to change the frequency of kernel,
what I did is:
I replaced .config file with my own config file
(since I want to do this automatically without opening make menuconfig ui)
then I repeat the step1,2,3,4 again
Is there anyway I do not need repeat the above 4 steps?
Thanks a lot!!!!
The timer frequency is fixed in Linux (unless you build a tickless kernel - CONFIG_NO_HZ=y - but the upper limit will still be fixed). You cannot change it at runtime or at boot time. You can only change it at compile time.
So the answer is: no. You need to rebuild the kernel when you want to change it.
The kernel timer frequency (CONFIG_HZ) is not configurable at runtime - you will have to compile a new kernel when you change the setting and you will have to reboot the system with the new kernel to see the effects of any change.
If you are doing this a lot, though, you should be able to create a little shell script to automate the kernel configure/build/install process. For example it should not be too hard to automate the procedure so that e.g.
./kernel-prep-with-hz 100
would rebuild and install a new kernel, only requiring from you to issue the final reboot command.
Keep in mind though, that the timer frequency may subtly affect various subsystems in unpredictable ways, although things have become a lot better since the tickless timer code was introduced.
Why do you want to do this anyway?
Maybe this will help. As the articale says, you can change the frequency between the available frequency that your system supports. (Check if CPUfreq is already enabled in your system)
Example, mine.
#cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
2000000 1667000 1333000 1000000
#echo 1000000 > cpu0/cpufreq/scaling_min_freq
http://www.ibm.com/developerworks/linux/library/l-cpufreq-2/
What scheduling algorithms does Linux kernel use?
Where can I get more info about linux's kernel? (OS first course... student level)
The linux kernel has several different available scheduling algorithms both for the process scheduling and for I/O scheduling. Download it from www.kernel.org and call
make menuconfig
You will get a full list of all available options with a built-in help.
One guy that once came up with his O(1) scheduler is Con Kolivas. Definitively have to have a look at what he did. I was once a great break-through.
Note: As Abdullah Shahin noted, this answer is about IO queing scheduler, not for processes.
If you just want to check what scheduler your linux system is using and which are available you can run the following command:
cat /sys/block/sda/queue/scheduler
The one between the [] is the one it's using at the moment. The other ones are available.
To change it:
sudo bash -c 'echo deadline > /sys/block/sda/queue/scheduler'
Be carefull to set it back to default though, unless you know what you are doing and want.
Default (in newer Ubuntu distros at least) is CFQ (Completely Fair Scheduling):
http://en.wikipedia.org/wiki/CFQ
Interview with the creator (Jens Axboe):
http://kerneltrap.org/node/7637
As others have already mentioned, there are several scheduling algorithms available, according to the intended use.
Check this article if you want to learn more about scheduling in Linux.
i believe "completely fair scheduler" is in use with latest kernels. I think you can good amount of information if you just search for it in google.
link : http://en.wikipedia.org/wiki/Completely_Fair_Scheduler
A new addition to Linux Kernel is EDF (Earliest Deadline First) for guaranteed RealTime support
http://lkml.org/lkml/2009/9/22/186
http://www.evidence.eu.com/content/view/313/390/
I think the Linux kernel actually has a few different schedulers you can choose from at compile-time. To find out more about the Linux kernel, you can download the kernel source code (or browse it online) and look in the Documentation directory. For example, the scheduler subdirectory might be helpful. You can also just look at the code itself, obviously.
Modern GNU/Linux distributions use CFS (Completely Fair Scheduler). You may read more on that in the 4th chapter of this book:
Linux Kernel Development 3rd Edition by Robert Love
You will find many interesting and easy to understand explanations there. I enjoyed a lot.
Linux Kernel allows three different scheduling algorithms mainly
shortest job first
Round Robin Scheduling
Priority based preemptive scheduling algorithm.
The third scheduling method which it differs with lower version of Linux versions such as 2.4