using BCM2835 with RT-PREEMPT kernel - linux

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!

Related

How to set and lock cpu freq in 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.

How to read the external timer counter on the BeagleBone Black?

I need to count the transitions of a 50KHz binary signal using a BBB. I think using the TIMER4 triggered by the external signal connected to the pin P8.07 would be the easiest way.
So, I issued the following commands to load the proper cape and setup the pin as a timer :
./config-pin overlay cape-universaln
./config-pin P8.07 timer
Everything seems to work and nothing appears in dmesg.
My question is : How can I read the value of TIMER4 ? I looked in SysFs and find nothing interesting. Nothing in /dev as well. How can I retrieve the value of the timer counter I just setup ? I'm open to a C/C++ solution as well, but I would like to avoid doing kernel-space programming.
I'm using the latest Ubuntu Linux for BeagleBone, kernel 4.1.10-ti-r21.
With a little googling I see a pps driver for the AM335x DMTimer subsystem here: https://github.com/ddrown/pps-gmtimer
It looks like it hasn't been merged upstream and the README gives instructions on building it into the 3.8 kernel - you could revert back to 3.8, or you could adapt that for 4.1, in which case you may need to tweak the Device Tree overlay as well for the newer version of the dtc compiler that's in 4.1.
You could also write a pulse counter firmware for the PRU (with only a 50KHz input it wouldn't need to be very optimized at all to catch every pulse). You could send a signal to the ARM every so often and catch that in your userspace program.
Another option would be to directly access the DMTimer registers from userspace using mmap to map the /dev/mem file (example of this method for GPIO here), but that's a pretty "hacky" way to do it, and it's generally frowned upon in the GNU/Linux world to do that sort of stuff from userspace instead of from kernal space.

Difficulties backporting Linux kernel driver

I'm trying to backport a Linux kernel driver (the PCF85063 RTC, specifically) from the 3.17+ kernel into a 3.14 kernel I'm using, and I'm running into a few issues. I don't have any experience with adding/modifying kernel drivers, so I'm not sure if what I've done so far is correct:
I took the rtc-pcf85063.c file from the newer kernel, and added it to my drivers/rtc/ directory in the kernel source.
I added the following line to drivers/rtc/Makefile:
obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o
I added this snippet to drivers/rtc/Kconfig
config CONFIG_RTC_DRV_PCF85063
tristate "NXP PCF85063"
help
If you say yes here, you get support for the NXP PCF85063 RTC.
From my understanding, that should be all it takes to add driver support for the new RTC. When I execute make menuconfig, I can see my new RTC entry under Device Drivers > Real Time Clock, labeled as NXP PCF85063 with the correct help information. So it's clear that the third step above was successful.
The problem is, when I include this driver (by selecting it in menuconfig and saving/exiting) in my kernel build, it doesn't actually get built in. If I deploy the kernel and read /lib/modules/3.14.17/modules.builtin, the new driver is nowhere to be found. Also, if I check drivers/rtc/ after building the kernel, there are object files for every RTC driver included through menuconfig except the new one; the kernel isn't even compiling the driver.
I found one interesting thing that might give some hint as to what's going on. When I go to include/config in the linux source after running menuconfig, I have a bunch of directories, some of which correspond to drivers. There's an rtc directory, and when I navigate to include/config/rtc/drv, there's a header file for every RTC driver included in the build except the one I added.
The thing is, the header file corresponding to the new driver is in include/config; it's hidden away in include/config/config/rtc/drv. It looks like menuconfig isn't treating the new driver as a regular RTC driver.
I know this is a pretty specific problem, but I was hoping that someone might notice that I'm missing a step or going about this the wrong way. Thanks.

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.

Upgrade a specific Linux Kernel Subsystem?

Is it possible to upgrade only a specific sub-system, say I2C, of the Linux Kernel.
For example:
Is it possible to include "Support for multiplexed I2C bus topologies (introduced in Kernel 2.6.36)" in the Kernel version 2.6.31.1.
No this is not possible.
A kernel module or 'subsystem' (eg the i2c module) is build for a specific kernel image, you cannot combine different kernel(module) versions.
If you are feeling lucky (depending on your kernel skills), you could:
download the source code of your kernel
Install compiler and friends
add the updated ic2 driver
Try to compile the module for your kernel version
Cross your fingers and load it into your own kernel...\
I do not have any experience with this, so I do not know whether this works or not. Of course, if the ic2 module requires other (updated) modules, you could be ending up with updating (almost) the complete kernel...

Resources