simply write a small program to understand the mechanism of some signals
Although the combination of blocking and non-blocking operations and the Select method is sufficient for querying the device for most of the time
Enough, some situations cannot be solved effectively by the technology we have seen so far.
Let's imagine a process that performs a long computation cycle on a low priority, but needs to be as fast as possible
The processing input data. If this process responds to a new report from some data acquisition peripherals, it
You should immediately know when new data is available. This application may be written to call poll with regular
To check the data, however, there are better ways to do so in many cases. By enabling asynchronous notification, this should be
A program may accept a signal whenever the data is available and does not need to be queried by itself.
A user program must perform 2 steps to enable asynchronous notifications from the input file. First, they specify
A process as the owner of a file. When a process uses the FCNTL system call to emit F_setown
The ID of the command, the owner process, is saved in Filp->f_owner for later use. This step to
The kernel knows who is necessary to notify. In order to really enable asynchronous notifications, the user program must set the Fasync
The flag is in the device, through the F_SETFL fcntl command.
After these 2 calls have been executed, the input file can request a SIGIO signal, whenever
New data arrives. Signals are sent to processes stored in filp->f_owner (or process groups, such as
value is negative).
For example, the code in the following user program can be asynchronously notified to the current process, giving the stdin a
Into the file:
Signal (SIGIO, &input_handler); /* Dummy sample; Sigaction () is better */
Fcntl (Stdin_fileno, F_setown, Getpid ());
Oflags = Fcntl (Stdin_fileno, F_GETFL);
Fcntl (Stdin_fileno, F_SETFL, Oflags | Fasync);
This program named Asynctest in the source code is a simple program that reads stdin. It is available
To test the asynchronous capabilities of the Scullpipe. This program is similar to cat but does not end in file endings;
It responds only to input, not without input.
Note, however, that not all devices support asynchronous notifications, and you can choose not to provide it. Application
Programs often assume that asynchronous capabilities are available only to sockets and TTY.
The input notification has one remaining issue. When a process receives a SIGIO, it does not know which input
The file is provided with new data. If more than one file is enabled to asynchronously notify the process of the pending input, you should
The program must still rely on poll or select to find out what happened.
#include <linux/module.h>#include<linux/kernel.h>#include<linux/miscdevice.h>#include<linux/fs.h>#include<linux/interrupt.h>#include<linux/gpio.h>#include<mach/gpio.h>#include<asm-generic/ioctl.h>#include<asm/uaccess.h>#include<linux/wait.h>#include<linux/sched.h>#include<asm/atomic.h>#include<linux/semaphore.h>#defineMAGIC ' B '#defineGet_btn_val _ior (MAGIC, 1, unsigned long)typedefstruct{unsignedintGpio; unsignedintbtn; unsignedintIRQ; Char*name;} Irq_typedef;StaticIrq_typedef irqsource[] ={{exynos4_gpx3 (2),1,0,"BTN1"}, {exynos4_gpx3 (3),2,0,"btn2"}, {exynos4_gpx3 (4),3,0,"Btn3"}, {exynos4_gpx3 (5),4,0,"Btn4"}};D Efine_semaphore (Btn_sem);D eclare_wait_queue_head (btn_wait_que);Static intcondition;StaticUnsignedLongBtn_num;StaticIrqreturn_t Gpio_irq_handler (intIrqvoid*Dev) {Irq_typedef* Curdev = (IRQ_TYPEDEF *) Dev; PRINTK ("%s\n",curdev->name); PRINTK ("btn (DRV):%d\n",curdev->btn); Btn_num= curdev->btn; Condition=1; WAKE_UP (&btn_wait_que); return 0;}Static intBtn_open (structInode *inod,structFile *fil) { if(!down_interruptible (&Btn_sem)) {Up (&Btn_sem); return-eintr; } return 0;}Static intBtn_release (structInode *inod,structFile *fil) {Up (&Btn_sem); return 0;}Static LongBtn_ioctl (structFile *fil, unsignedintCMD, unsignedLongArg) {unsignedLongret; void__user *ARGP = (void__user *) Arg; Wait_event_interruptible (Btn_wait_que, condition); Condition=0; Switch(cmd) { CaseGet_btn_val:ret= Copy_to_user ((void__user *) ARGP, (void*) &btn_num,4); //Put_user (btn_num, (unsigned int __user *) ARGP); Break; default:return-EINVAL; } returnret;}Static structFile_operations Btn_irq_fops ={. Owner=this_module,. Open=Btn_open,. Release=btn_release,. Unlocked_ioctl=Btn_ioctl,};Static structMiscdevice Btn_irq_misc ={. Minor=255,. Name="btn",. FoPs= &Btn_irq_fops,};Static__initintBtn_irq_init (void){ intI,ret; Misc_register (&Btn_irq_misc); for(i=0;i<4; i++) {IRQSOURCE[I].IRQ=Gpio_to_irq (Irqsource[i].gpio); RET= Request_irq (Irqsource[i].irq,gpio_irq_handler,irqf_trigger_falling,irqsource[i].name, &Irqsource[i]); } returnret;}Static__exitvoidBtn_irq_exit (void){ inti; for(i=0;i<4; i++) Free_irq (IRQSOURCE[I].IRQ,&Irqsource[i]); Misc_deregister (&btn_irq_misc);} Module_init (Btn_irq_init); Module_exit (Btn_irq_exit); Module_license ("GPL");
#include <stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<stdlib.h>#include<sys/ioctl.h>#defineMAGIC ' B '#defineGet_btn_val _ior (MAGIC, 1, unsigned long)intMainintargcChar*argv[]) { intBtn_fd,btn_val=0; if(argc!=2) {printf ("usage:<%s> </dev/?node>\n", argv[0]); return-1; } btn_fd= Open (argv[1],o_rdonly); if(btn_fd<0) return-1; while(1) { //IOCTL (btn_fd,get_btn_val,btn_val);IOCTL (btn_fd,get_btn_val,&btn_val); //sleep (1);printf ("Btn_val (IRQ):%d\n", Btn_val); }}
Obj-m += = arm-linux-==/file/samsung/linux-3.5#CURDIR = $ (shell pwd) CURDIR = ' pwd '. Phony:module Cleanall:module $ (source:.o=) module: -C $ (kerndir) m=$ (CURDIR) modules$ ( SOURCE:.O=): $ (SOURCE) -o [email protected] $^%.o:%. C-a $< clean: -C $ (kerndir) m=$ (CURDIR) Clean RM $ (SOURCE:.O=)
Linux kernel signal