Interrupt handling and user space notification - linux

I have several registered interrupts assigned to gpios, and application in user space.
How to notify application about occurred interrupt and which interrupt there was?
Possibly fasync is applicable for this goal, but I can find examples how to send information from interrupt handler to user space application.
It will be good if you can present some useful examples.
Thanks in advance.

You don't need fancy kernel to userspace communication. A userspace application has access to GPIOs using Sysfs. Read about it in Documentation/gpio.txt.
First, export a GPIO pin like this (the actual number depends on your setup):
# echo 23 > /sys/class/gpio/export
This will export GPIO pin #23, and thus create /sys/class/gpio/gpio23.
Set its direction:
# echo in > /sys/class/gpio/gpio23/direction
If the hardware GPIO controller supports interrupts generation, the driver should also support it and you will see /sys/class/gpio/gpio23/edge. Write either rising, falling or both to this file to indicate the signal edge(s) that will create a "userspace interrupt". Now, to get interrupted, use the poll(2) system call on /sys/class/gpio/gpio23/value. Then, when the poll call unblocks, read the new value (/sys/class/gpio/gpio23/value), which will be '0' or '1' (ASCII).

dinesh provided a C implementation of eepp's proposed solution, which requires that the application block in poll().
Here is a C++ implementation which abstracts this functionality, and provides callback/interrupt functionality instead. Note the GPIO constructor which takes a callback function as an argument. This provides the capability desired by the OP.
https://github.com/tweej/HighLatencyGPIO

Related

Does we have something to check whether data is available in UART port in embedded linux..?

Is it possible to check from user space application, whether data is available for reading in the UART port. The code is written in C over Embedded Linux Platform.
For Example :
while(isDataAvalable(fileDescriptor)) {
read(fileDescriptor, buffer, 10)
}
I am looking for some function provided by linux, which returns true if there is data to be read from port and false if there is no data. But the function itself should not remove the data from hardware buffer, until the data is read using "read" method.
If there is no such inbuilt function in linux, is there a way to create a wrapper function using the linux system calls to achieve the above functionality, which can be used by the user space application..?
This can be achieved by using poll() in linux.
poll() shall be able to tell whether there is data to read and is very useful in such scenarios. It monitors a set of file descriptors and waits for one of the file descriptor to become ready to perform I/O.
poll() checks whether any desired event(like arrival of data) has occurred. If the requested event has occurred, it shall alert via POLLIN that the event has happened(there is data to read) in the particular file descriptor.
If you could use Qt framework, than the QSerialPort is emitting signal QIODevice::readyRead() when data is available. (you could deploy Qt without gui for your platform to minimize the footprint)

Linux input event interface numbering

In Linux, how do you create an input event interface with a user specified event number and map that to a specific device event?
I'm using the gpio-keys driver to translate key presses from a keypad. I define the keys to be used in my board configuration source file as shown below
static struct gpio_keys_button ev_keys[] = {
[0] = {
.type = EV_KEY,
.active_low = 1,
.wakeup = 0,
.debounce_interval = KEYS_DEBOUNCE_MS,
.code = KEY_MUTE,
.desc = "mute",
.gpio = PUSHBUTTON_MUTE,
}
};
and register this with the kernel.
And I enable the event interface and GPIO buttons when building the kernel.
Device Drivers ---> Input device support --> Event interface
Device Drivers ---> Input device support --> Keyboards --> GPIO buttons
This creates a node to the event at /dev/input/event0 to which the GPIO button events are mapped. In a system that uses only one event interface I can call poll() on the fd to /dev/input/event0 and everything works as expected.
Now, I have second peripheral on my system that uses /dev/input/event0 by default and I need to map the events from the gpio-keys driver to another event. Any suggestions on how I go about creating an event with a number/id I can specify and then map this to the gpio-keys events?
Thanks.
If you mean by "mapping" specifying the name of the /dev/input/eventX 'file', you should use Udev. The kernel assigns the number of the event device, it is a bad idea and probably impossible to try and force this number since you never know which other device may have gotten this number first.
My recommendation would be to let Udev create a symlink that points to your device; you can choose your own name and use that in your program (i.e. /dev/my_first_keypad). For example, my Wacom tablet is assigned /dev/wacom with the following udev rule:
KERNEL=="event*", SUBSYSTEM=="input", SUBSYSTEMS=="input", ATTRS{name}=="Wacom Volito", SYMLINK+="wacom"
The trick is to find the proper set of variables to exactly specify your keypad. If it is USB based, the vender/product ID are a good start. Otherwise, use udevadm info --export-db to get a full dump of the Udev database. Udev rules go in files in /etc/udev/rules.d/ or /lib/udev.d, depending on the Linux distribution you are using.
You can check System.map file for functions that register event interface. The one that comes first, usually gets lowest eventX number and later functions gets eventX number increased by one. IMO, its ok to rely on static device node file for embedded device where device configuration is static and is not going to change during operation, but generally you should use udev for you purposes.

Interrupt handling (Linux/General)

On the mainbord we have an interrupt controller (IRC) which acts as a multiplexer between the devices which can raise an interrupt and the CPU:
|--------|
|-----------| | |
-(0)------| IRC _____|______| CPU |
-(...)----| ____/ | | |
-(15)-----|/ | |--------|
|-----------|
Every device is associated with an IRQ (the number on the left). After every execution the CPU senses the interrupt-request line. If a signal is detected a state save will be performed and the CPU loads an Interrupt Handler Routine which can be found in the Interrupt Vector which is located on a fixed address in memory. As far as I can see the Number of the IRQ and the Vector number in the Interrupt Vector are not the same because I have for example my network card registered to IRQ 8. On an Intel Pentium processor this would point to a routine which is used to signal one error condition so there must be a mapping somewhere which points to the correct handler.
Questions:
1) If I write an device driver and register an IRQ X for it. From where does the system know which device should be handled? I can for example use request_irq() with IRQ number 10 but how does the system know that the handler should be used for the mouse or keyboard or for whatever i write the driver?
2) How is the Interrupt Vector looking then? I mean if I use the IRQ 10 for my device this would overwrite an standard handler which is for error handling in the table (the first usable one is 32 according to Silberschatz (Operating System Concepts)).
3) Who initialy sets the IRQs? The Bios? The OS?
4) Who is responsible for the matching of the IRQ and the offset in the Interrupt Vector?
5) It is possible to share IRQS. How is that possible? There are hardware lanes on the Mainboard which connect devices to the Interrupt Controller. How can to lanes be configured to the same Interrupt? There must be a table which says lane 2 and 3 handle IRQ15 e.g. Where does this table reside and how is it called?
Answers with respect to linux kernel. Should work for most other OS's also.
1) If I write an device driver and register an IRQ X for it. From where does the system know which device should be handled? I can for example use request_irq() with IRQ number 10 but how does the system know that the handler should be used for the mouse or keyboard or for whatever i write the driver?
There is no 1 answer to it. For example if this is a custom embedded system, the hardware designer will tell the driver writer "I am going to route device x to irq y". For more flexibility, for example for a network card which generally uses PCI protocol. There are hardware/firmware level arbitration to assign an irq number to a new device when it is detected. This will then be written to one of the PCI configuration register. The driver first reads this device register and then registers its interrupt handler for that particular irq. There will be similar mechanisms for other protocols.
What you can do is look up calls to request_irq in kernel code and how the driver obtained the irq value. It will be different for each kind of driver.
The answer to this question is thus, the system doesn't know. The hardware designer or the hardware protocols provide this information to driver writer. And then the driver writer registers the handler for that particular irq, telling the system what to do in case you see that irq.
2) How is the Interrupt Vector looking then? I mean if I use the IRQ 10 for my device this would overwrite an standard handler which is for error handling in the table (the first usable one is 32 according to Silberschatz (Operating System Concepts)).
Good question. There are two parts to it.
a) When you request_irq (irq,handler). The system really doesn't program entry 0 in the IVT or IDT. But entry N + irq. Where N is the number of error handlers or general purpose exceptions supported on that CPU. Details vary from system to system.
b) What happens if you erroneously request an irq which is used by another driver. You get an error and IDT is not programmed with your handler.
Note: IDT is interrupt descriptor table.
3) Who initialy sets the IRQs? The Bios? The OS?
Bios first and then OS. But there are certain OS's for example, MS-DOS which doesn't reprogram the IVT set up by BIOS. More sophisticated modern OS's like Windows or Linux do not want to rely on particular bios functions, and they re-program the IDT. But bios has to do it initially only then OS comes into picture.
4) Who is responsible for the matching of the IRQ and the offset in the Interrupt Vector?
I am really not clear what you mean. The flow is like this. First your device is assigned an irq number, and then you register an handler for it with that irq number. If you use wrong irq number, and then enable interrupt on your device, system will crash. Because the handler is registered fro wrong irq number.
5) It is possible to share IRQS. How is that possible? There are hardware lanes on the Mainboard which connect devices to the Interrupt Controller. How can to lanes be configured to the same Interrupt? There must be a table which says lane 2 and 3 handle IRQ15 e.g. Where does this table reside and how is it called?
This is a very good question. Extra table is not how it is solved in kernel. Rather for each shared irq, the handlers are kept in a linked list of function pointers. Kernel loops through all the handlers and invokes them one after another until one of the handler claims the interrupt as its own.
The code looks like this:
driver1:
d1_int_handler:
if (device_interrupted()) <------------- This reads the hardware
{
do_interrupt_handling();
return MY_INTERRUPT;
}else {
return NOT_MY_INTERRUPT;
}
driver2:
Similar to driver 1
kernel:
do_irq(irq n)
{
if (shared_irq(n))
{
irq_chain = get_chain(n);
while(irq_chain)
{
if ((ret = irq_chain->handler()) == MY_INTERRUPT)
break;
irq_chain = irq_chain->next;
}
if (ret != MY_INTERRUPT)
error "None of the drivers accepted the interrupt";
}
}

ARM LPC1751 pins configured as I/O

How can I configure one pin for input and another for the output?
If I am not wrong this could be done with GPIO registers that controlls device pins that are not connected to peripherical functions.
Look in UM10360.PDF, Chapter 9: GPIO. There you can find the description for the FIOxDIR direction registers, as well as the reigisters for querying, setting and clearing GPIO pins.
I also strongly recommend looking at the CMSIS Standard Peripherial Driver Library that NXP offers for 175x/176x, look in microcontroller support documents. Edit: There are lots of sample code in this Library.
https://github.com/dwelch67
I have a number of lpc based examples. You are looking for the IODIR register, depending on the port and flavor of LPC, there are now what they call fast I/O registers. a one in a bit location means that pin is an output, a zero an input.

linux netfilter pass the packet content to user space socket app

I want to write a Linux 2.6 netfilter module, which can check the incoming IP packet information, such as dest-ip, source-ip. After that pass these information to user space app which (i.e Socket app) will handle these information as soon as the packet reach the HOOKs.
I want to try two ways:
1 . Inside the netfilter module, make a fifo struct line, every time the packet reach the hook, put the packet information to the fifo. and with the help of /proc/example filesystem . every time the user space app read the /proc/example file , will get a packet information from the fifo head .
I'm a newbie of kernel program, this program crash my kernel several times. -_-!
I wonder is this way possible?
2 . Inside the netfilter module, make a char device, the user space app read packet information from this char device. But I still don't know how to make sure to get the packet as soon as possible, is there any way when the packet reach the netfilter hook, kernel will send some signal to info user space app, then the user space app come to pick the packet information?
Thank you very much.
My way of doing this:
Create a kernel module to get hooked to your network activity.
Then use Netlink which can talk to user space from the kernel to pass the data IPC.
Option 1 is possible and workable what is the problem? But I usually use to communicate between user-space and kernel space using netlink
netlink_kernel_create
netlink_kernel_release
nl_sk = netlink_kernel_create(&init_net, 17, 0, recv_cmd, NULL, THIS_MODULE);
netlink_kernel_release(nl_sk);
netlink_unicast
What do you mean by as soon as possible? Do you have some actual hard/soft realtime requirements?
If you select option 2 you should be able to get new data rather quickly by opening the character device non-blocking and select()ing on the read fd. I've done something similar with a kernel level socket, where socket data was presented to a user level process via a character driver. I saw very little latency as long as I serviced the socket in a timely manner. The driver was used in an environment that had some soft realtime requirements and we didn't have any problem meeting those requirements with run-of-the-mill kernel facilities.
Have a look at Linux Device Drivers, 3rd Edition.
I'm not sure about the first method, but using the second, your user space app could use a select() call with the char device as the only target - as soon as select() returns, you'll have data to read. Just make sure to read it all, and not just assume one packet's worth of data.

Resources