Interrupting a user program when user button is pressed

Hi,

I would like to be able to write C code to be executed on BB when I
press the user button. I have tried doing sudo cat /dev/input/event0
and pressing the user button, and some characters appear on the
screen.

Writing a udev rule to run a program with KERNEL==event0 and
SUBSYSTEM==input have proved futile.

Ideally I would prefer a solution that does not make use of udev,
since I would like to execute certain statements in the program
depending on the duration/number of quick successive clicks.

I am using kernel version 2.6.31.5-x5.3.

Thanks and regards,

Gianluca

/dev/input/event0 is the way to go… you can use “od -x /dev/input/event0” rather than cat as its binary formatted data rather than simple text. It provides timing information and key up/down status…

Here’s a simple C program that just dumps event information out to the console:
http://www.pastebin.org/153729

Thanks! I tried it out and it worked. However, do you know how I could
make use of interrupts to signal an interrupt handler to print out the
contents of the file, instead of have it in an infinite loop
(while(1)) always checking whether there is data in the file to print?

I think the interrupt would have to be sent to the interrupt handler
somehow when data is written to /dev/input/event0.

Regards,

Gianluca

That code is just an example of how to access the event file… it performs a blocking read(), so it doesn’t chew CPU and the while loop only iterates around when there are events to be read and processed. The best way of approaching it really depends on the application you are working on, but I would probably just spin another thread to read the events in…

If you want to wait for input on a file descriptor the usual way is to use the select() or poll() function calls… If you let me know a bit more about the application, what its doing then I can probably suggest the best solution…

Well I have written a program for a university assignment that detects
when a USB mass Storage Stick has been inserted, and automatically
backs up data by copying all files in a certain folder called
'Backups' to BB's SD Card. I make use of udev for the detection with
KERNEL==sd[a-z]*. When the program is finished, it switches on the
USER LED on the BB, to signal to the user that the process is
finished. Then I want to allow the user to unmount and remove the USB
stick by pressing the USER button. Another program would then be
triggered to perform the umount and rmdir. Thus if there is a way to
consume less CPU time/power with some form of interrupt, rather than
using a while loop, I would prefer it.

Thanks,

Gianluca

You do not need to use an interrupt as this is all handled deep inside the linux kernel. There is no power or CPU time hit for using the code sample as it blocks at the read() function call and the linux kernel stops the process. This is the joy of using high-level userspace interfaces.

If you really want to interface with interrupts then you would need to use GPIOs, configure the USER key’s GPIO to trigger an interrupt on level change, then tinker with the linux device driver to pass that out to your program as a signal, or more usually as a file inside /sys (which then ends up being the same as the previous paragraph with a userspace program blocked on a file read() operation).

Finally, since the USB drive is only being read from, if you mount it readonly then the user can yank it anytime they like…! I would unmount it immediately after the backup is complete and then flash the USER LED and only stop flashing it once the device eject is seen. No need for the USER button at all…!