Where can I find IRQF_NODELAY flag in Linux kernel? - linux

I got an error when I built a device driver with IRQF_NODELAY in Linux 3.0.9.
And I found that IRQF_NODELAY was disappeared since somewhere after 2.6.x.
For the realtime job, I need an ISR that is not working as a thread.
Because I patched vanilla kernel with RT-Linux, the default ISR mode is not a real ISR but a thread.
Is IRQF_NODELAY deprecated? Can I use some flag equivalent to IRQF_NODELAY?

IRQ_NODELAY was replaced by IRQF_NO_THREAD. It works fine, I have used it for one project. You can pass it as third argument in the request_irq function.

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!

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.

Debugging kernel hang because of IOCTL calls

I am trying to make a kernel module which is working on 2.6.32 kernel to work on 3.6 kernel. We use IOCTL calls to update structures in Linux Kernel Module. These calls are working fine in 2.6.32 kernel.
When I try the same in 3.6 kernel I am facing kernel hang whenever ioctl calls are made from user-space application. Its a socket based interface not a file based interface hence we use the ioctl under struct proto_ops.
How can I debug this scenario as there is no core dump generated. To copy data from userspace I am using copy_from_user command.
Any pointers for debugging this scenario would be very helpful
ioctl() is one of the remaining parts of the kernel which runs under the Big Kernel Lock (BKL). In the past, the usage of the BKL has made it possible for long-running ioctl() methods to create long latencies for unrelated processes.
Follows an explanation of the patch that introduced unlocked_ioctl and compat_ioctl into 2.6.11. The removal of the ioctl field happened a lot later, in 2.6.36.
Explanation: When ioctl was executed, it took the Big Kernel Lock (BKL), so nothing else could execute at the same time. This is very bad on a multiprocessor machine, so there was a big effort to get rid of the BKL. First, unlocked_ioctl was introduced. It lets each driver writer choose what lock to use instead. This can be difficult, so there was a period of transition during which old drivers still worked (using ioctl) but new drivers could use the improved interface (unlocked_ioctl). Eventually all drivers were converted and ioctl could be removed.
compat_ioctl is actually unrelated, even though it was added at the same time. Its purpose is to allow 32-bit userland programs to make ioctl calls on a 64-bit kernel. The meaning of the last argument to ioctl depends on the driver, so there is no way to do a driver-independent conversion.
Reference: The new way of ioctl() by Jonathan Corbet

Linux how to debug OS freeze issue

I am working on a kernel module and a user-space application to test that module.
The problem is that during testing my system hangs/freeze.
I have placed lots of debug prints in the code.
The last message that is printed is just before linux select call in my user-space application. Does select somehow freeze the system?
So, How can i debug that where is problem? whether the problem is on user-space application or kernel module?
As n.m mentioned, your userspace program can't freeze Linux, so its an error in your kernel module. The best way to debug this is to use a kernel debugger, and figure out what your module is doing wrong.
Common errors are uninitialized pointers that your module passes to the kernel or locking issues, so take a close look at those.
A userspace program cannot, by definition, freeze Linux. There's a bug in the kernel.

How to use systemcalls in linux modules

I attempted to use systemcalls such as sys_sendto when programming a kernel module. But the compiler warned me that the symbol 'sys_sendto' is undefined. I'm sure I have inculded the header file syscalls.h, so please help me and thank you. P.S: My linux version is 2.6.32
For a module to link to a symbol in the kernel like sys_sendto(), it has to be exported by the kernel. Not all system calls are exported. See here
http://www.ibm.com/developerworks/linux/library/l-system-calls/
Here's a whole explanation on writing them and using them. They're not used by direct method calls because they have to be executed in kernel mode. The processor loads the syscall number into a register and then issues a hardware interrupt which the kernel processes and handles to execute your system call.

Resources