How to set and lock cpu freq in linux - linux

I am working under linux and what I want to do is to lock cpu to a certain frequency, disable cpu automatic freq change.
Could anyone indicate how to do it in driver or kernel ?
Thanks.

what I want to do is to lock cpu to a certain frequency, disable cpu automatic freq change.
You can use kernel modules to do this for you already and there are user space programs that you can run to disable it. Look for Disable Frequency scaling.
on Debian the package can be installed as follows
aptitude install cpufrequtils
The read the docs from there. If you want to get a bit more hands by loading kernel modules, for Intel the one you need to load is...
acpi-cpufreq
If you're running Linux in something like a VirtualBox and trying to load this it will likely fail because acpi will be disabled. You can find out what you need to do here to control this from command line.
http://www.thinkwiki.org/wiki/How_to_make_use_of_Dynamic_Frequency_Scaling
If you want to see how this is done in a kernel module the source code you need can be found here.
http://lxr.free-electrons.com/source/drivers/cpufreq/acpi-cpufreq.c
You would likely need to read the source for one of the governor modules to understand how this works.
If possible I'd control this from userspace.

Related

using BCM2835 with RT-PREEMPT kernel

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!

Embedded Linux Boot Optimization

I am doing project on Pandaboard using Embedded Linux (UBUNTU 12.10 Server Prebuild image) to optimize boot time. I need techniques or tools through which I can find boot time and techniques to optimize the boot time. If anyone can help.
Just remove application which is not required from /etc/init.d/rc file also put echo after every process initialization and check which process is taking much time for starting,
if you find application which is taking more time then debug that application and so on.
There is program that can be helpful to know the approximate boot-up time. Check this link
Time Stamp.
First of all the best you have to do is to compile yourself your own made kernel, get the source on the internet and do a make xconfig and then unselected everythin you don't need.
In a second time create your own root filesystem using Buildroot and make xconfig to select/unselect everything you need or not.
Hope this help.
I had the same problem and do that way, now it's clearly not the same ;)
EDIT: Everything you need will be here
to analyze the boot process, you can use Bootchart2, its available on github: https://github.com/mmeeks/bootchart
or Bootchart, from the Ubuntu packages:
sudo apt-get update
sudo apt-get install bootchart pybootchartgui
There are broadly 3 areas where you can reduce boot time
Bootloader:
Modify the linker script to initialize only the required h/w. Also, if you are using an SD card to boot, merge kernel and bootloader image to save time.
Kernel:
Remove unwanted modules from kernel config. Also try using compressed and uncompressed image. If your CPU is good enough to handle it go compressed image and check uncompression time required for different compression types.
Filesystem:
FS size can be significantly reduced by removing the unwanted bins and libs. Check for dependencies and use only the one's that are required.
For more techniques and information on tools that help in measuring the boot time please refer to the following link.
Refer to Training Material
The basic rule is: the fastest code is code that never gets loaded and
run, so remove everything you don't need:
in U-Boot: don't load and run the full U-Boot at all; use FALCON
mode and have the SPL load the Linux kernel and DTB directly
in Linux: remove all drivers and other stuff you don't really need;
load all drivers that are not essential for your core application as
modules - and load them after your application was started. If you
take this serious, you may even want to start only one CPU core
initially (and start the remaining ones after your application is
running).
in user space: minimize the size of the root file system. throuw
out anything you don't need; configure tools (like busybox) to
contain only the really needed functionality; use efficient code
(for example, link against musl libc instead of glibc) etc.
What can be acchieved by combining all these measures can be seen in
this video - and yes, the complete code for this optimization is
available here.
Optimizing embedded Linux Boot process , needs modifications in three level of embedded Linux design.
Note: you will need the source codes of bootloader and kernel
Boot : the first step in optimizing and reducing boot time of board is optimizing boot loader. first you should know what is your bootloader is. If your bootloader is an opensource bootloader like u-boot than you have the opportunity to modify and optimize it. In u-boot we have a procedure that we can skip unnecessary system check and just upload kernel image to ram and start. the documentation and instruction for this is available in u-boot website. by doing this you will save about 4 ~ 5 second in boot.
Kernel : for having a quicker kernel , you should optimize kernel in many sections. for editing you can use on of Linux config menu. I always use a low graphic menu. it need some dependency you can use it by this command:
$ make menuconfig
our goal for Linux kernel is to have smaller kernel image and less module to load in boot. first change the algorithm of compression from gzip to LZO. the point of this action is gzip algorithm will take much time to extract kernel. by using LZO we have a quicker kernel decompression process. the second , disable any unnecessary driver or module that you don’t have it on your board or you don’t use it any more. by doing this , you will lose some device access and cannot use them in Linux but you will have two positive points: less Ram usage , quicker boot time.
but please remind that some driver are necessary for Linux and by disabling them you will lose some of main features (for example if you disable I2C driver in Linux you will no longer have a HDMI interface) that you need or in worst case you will have a boot problem (such as boot-loop). The third is to disable some of unusable filesystem to reduce kernel size and boot time. The Fourth is to remove some of compression algorithm to have smaller kernel image.
the last thing , If you are using a u-boot bootloader create a uImage instead of zImage. the following steps , are general and main actions , for having quicker boot as 1 second after power attach you should change more option.
after two base layer modifications, now we should optimize boot process in user-space (root file system). depend on witch system are you using , we have different changes to do. in abstract root file system of Linux that have necessary package and system to boot Linux we should use systemd instead of Unix systemv , because systemd have a multi-task init. system and it is faster , after that is udev that you should modify some of loading modules. if you have a graphical user-interface , we can use an easy trick to have a big boot time reduction by initing GUI first and load other module after loading GUI.
if you do all of following tasks , you can have quick boot time and fast system to work with.

Cyclictest for RT patched Linux Kernel

Hello I patched the Linux kernel with the RT-Patch and tested it with the Cyclinctest which monitors latencies. The Kernel isn't doing good and not better than the vanilla kernel.
https://rt.wiki.kernel.org/index.php/Cyclictest
I checked the uname for RT, which looks fine.
So I checked the requirements for the cyclinctest and it states that I have to make sure that the following is configured within the kernel config:
CONFIG_PREEMPT_RT=y
CONFIG_WAKEUP_TIMING=y
CONFIG_LATENCY_TRACE=y
CONFIG_CRITICAL_PREEMPT_TIMING=y
CONFIG_CRITICAL_IRQSOFF_TIMING=y
The Problem now arising is that the config doesn't contain such entries. Maybe there are old and the they may be renamed in the new patch versions (3.8.14)?
I found options like:
CONFIG_PREEMPT_RT_FULL=y
CONFIG_PREEMPT=y
CONFIG_PREEMPT_RT_BASE=y
CONFIG_HIGH_RES_TIMERS=y
Is that enought in the 3.x kernel to provide the required from above? Anyone a hint?
There's a lot that must be done to get hard realtime performance under PREEMPT_RT. Here are the things I am aware of. Entries marked with an asterisk apply to your current position.
Patch the kernel with PREEMPT_RT (as you already did), and enable CONFIG_PREEMPT_RT_FULL (which used to be called CONFIG_PREEMPT_RT, as you correctly derived).
Disable processor frequency scaling (either by removing it from the kernel configuration or by changing the governor or its settings). (*)
Reasoning: Changing a core's frequency takes a while, during which the core does no useful work. This causes high latencies.
To remove this, look under the ACPI options in the kernel settings.
If you don't want to remove this capability from the kernel, you can set the cpufreq governor to "performance" to lock it into its highest frequency.
Disable deep CPU sleep states
Reasoning: Like switching frequencies, Waking the CPU from a deep sleep can take a while.
Cyclictest does this for you (look up /dev/cpu_dma_latency to see how to do it in your application).
Alternatively, you can disable the "cpuidle" infrastructure in the kernel to prevent this from ever occurring.
Set a high priority for the realtime thread, above 50 (preferably 99) (*)
Reasoning: You need to place your priority above the majority of the kernel -- much of a PREEMPT_RT kernel (including IRQs) runs at a priority of 50.
For cyclictest, you can do this with the "-p#" option, e.g. "-p99".
Your application's memory must be locked. (*)
Reasoning: If your application's memory isn't locked, then the kernel may need to re-map some of your application's address space during execution, triggering high latencies.
For cyclictest, this may be done with the "-m" option.
To do this in your own application, see the RT_PREEMPT howto.
You must unload the nvidia, nouveau, and i915 modules if they are loaded (or not build them in the first place) (*)
Reasoning: These are known to cause high latencies. Hopefully you don't need them on a realtime system :P
Your realtime task must be coded to be realtime
For example, you cannot do file access or dynamic memory allocation via malloc(). Many system calls are off-limits (it's hard to find which ones are acceptable, IMO).
cyclictest is mostly already coded for realtime operation, as are many realtime audio applications. You do need to run it with the "-n" flag, however, or it will not use a realtime-safe sleep call.
The actual execution of cyclictest should have at least the following set of parameters:
sudo cyclictest -p99 -m -n

How to change kernel Timer frequency

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/

Change linux kernel timer

I have to run a latency sensitive application and I have been asked to change the timer resolution to 1000 Hz or more. I searched on the net a bit and found pages about CONFIG_HZ etc.
However, there are what seem to be several other related settings in the file as well, so I want to be sure that I don't mess the settings up. I am posting some output here
$cat /boot/config-2.6.28-11-generic | grep HZ
# CONFIG_HZ_1000 is not set
# CONFIG_HZ_300 is not set
CONFIG_MACHZ_WDT=m
CONFIG_NO_HZ=y
CONFIG_HZ=250
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
So does the second line, "# CONFIG_HZ_1000 is not set", mean that 1000Hz is not supported? Do I have to change just CONFIG_HZ and not CONFIG_HZ-250?
PS: I'm using the 2.6 kernel (ubuntu jaunty) on a Geode processor.
EDIT1: I ran some code from http://www.advenage.com/topics/linux-timer-interrupt-frequency.php on my desktop machine and the development machine. The code supposedly is an accurate measure of how fast a timer the system can sustain. The output was approximately 183 Hz (on the development machine). So will changing the timer be meaningful?
Don't edit .config directly, unless you're a Kbuild expert (and if you're asking this, you're not a Kbuild expert). Instead run make menuconfig or make xconfig to load the menu-based configuration system. Alternately, make config will do a line-based configuration process (where it asks you several hundred questions about what to configure - not recommended). The relevant option is under "Processor type and features" as "Timer frequency".
That said, this may not be necessary. Modern Linux can use high-resolution event timers (CONFIG_HIGH_RES_TIMERS) to acheive low-latency timers even without increasing the timer frequency. With a tickless system (CONFIG_NO_HZ) , the timer frequency has little effect at all.
On the other hand, I'm not sure what timer support Geode CPUs have. You may want to run cyclictest with various kernel configurations to see what you need to get low latency performance. The test you ran tests maximum dispatch frequency, not dispatch latency, so comparing with cyclictest results would be interesting. If you need really low latency, the CONFIG_PREEMPT_RT patchset may also be of interest.
To change the timer setting you need to recompile the kernel. Change the option in some standard menu configuration tool, rather than the text file.
/boot/config... files only tell you what is installed in the specific kernel binary. This is not a configuration file you can change.
does the second line, # CONFIG_HZ_1000 is not set, mean that 1000Hz is not supported?
When a config option is not available it's just not present in the .config file.
For instance, those kernel options:
# CONFIG_HZ_1000 is not set
# CONFIG_HZ_300 is not set
are available for you to set.
To set them, the safest is to use a menu based interface like make menuconfig.
In menuconfig, to find out the location of a given kernel config parameter, type / to open the search box.

Resources