异步通知

发布者:RadiantBreeze最新更新时间:2024-07-31 来源: cnblogs关键字:异步通知  应用程序  键值 手机看文章 扫描二维码
随时随地手机看文章

①轮询:应用程序不断read;驱动程序不断read,占用大量的cpu资源。

②中断:应用程序阻塞在read;驱动程序休眠,只有发生中断时,驱动程序唤醒,读取键值,返回给应用程序;应用程序执行下一步。

③poll:应用程序在一定的时间内(用户定义),不断检测用户设置的flag,超时执行下一步;驱动程序在发生中断时,标记用户设置的flag。

④async:应用程序不会阻塞,不影响当前进程的其他任务的执行,只有在接收到驱动程序发送过来的信号,才去读取键值;在发生中断时,驱动程序发送信

号给应用程序(通过进程号),通知应用程序读取键值。

   

当按键中断发生时,发送信号给应用程序,应用程序再去读取键值,避免进程阻塞在read()函数,提高系统运用效率。

   

实例

driver

1 #include <linux/module.h>
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include gpio.h>
11 #include
12
13
14 static int major;
15
16 static struct class *myKey_class;
17 static struct class_device *myKey_class_dev;
18
19 volatile unsigned long *gpfcon;
20 volatile unsigned long *gpfdat;
21
22 volatile unsigned long *gpgcon;
23 volatile unsigned long *gpgdat;
24
25 static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
26 static volatile int ev_press = 0;
27
28 static struct fasync_struct *button_fasyncq;
29
30 //normal:1; press:0;
31 static unsigned char keyVal = 0;
32
33 struct pin_desc {
34         unsigned int pin;
35         unsigned int key_val;
36 };
37
38 /*
39 * 按键按下键值为0x01,...; 松开键值为0x81,...
40 */
41 struct pin_desc pins_desc[3] = {
42         {S3C2410_GPF0, 0x01},
43         {S3C2410_GPF2, 0x02},        
44         {S3C2410_GPG11, 0x03},        
45 };
46
47
48 static int myKey_open(struct inode *inode, struct file *file);
49 static int myKey_close(struct inode *inode, struct file *file);
50 static ssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos);
51 static int myKey_fasync(int fd, struct file *filp, int on);
52
53
54 static struct file_operations myKey_fops = {
55         .open = myKey_open,
56         .read = myKey_read,
57         .owner = THIS_MODULE,
58         .release = myKey_close,
59         .fasync = myKey_fasync,
60 };
61
62
63 static irqreturn_t handle_buttons(int irq, void *dev)
64 {
65         unsigned int kval;
66         struct pin_desc *pinDesc = dev;
67
68         kval = s3c2410_gpio_getpin(pinDesc->pin);
69         if (kval)        //松开
70         {
71                 keyVal = 0x80 | pinDesc->key_val;
72         }
73         else {                //按下
74                 keyVal = pinDesc->key_val;
75         }
76
77         //唤醒休眠进程
78         ev_press = 1;        //中断发生标志
79         wake_up_interruptible(&button_waitq);
80
81         kill_fasync(&button_fasyncq, SIGIO, POLL_IN);
82
83         return IRQ_RETVAL(IRQ_HANDLED);
84 }
85
86
87 static int myKey_open(struct inode *inode, struct file *file)
88 {
89         request_irq(IRQ_EINT0, handle_buttons, IRQT_BOTHEDGE, 'S2', &pins_desc[0]);
90         request_irq(IRQ_EINT2, handle_buttons, IRQT_BOTHEDGE, 'S3', &pins_desc[1]);
91         request_irq(IRQ_EINT19, handle_buttons, IRQT_BOTHEDGE, 'S5', &pins_desc[2]);
92         
93         return 0;
94 }
95
96
97 static int myKey_close(struct inode *inode, struct file *file)
98 {
99         free_irq(IRQ_EINT0, &pins_desc[0]);
100         free_irq(IRQ_EINT2, &pins_desc[1]);
101         free_irq(IRQ_EINT19, &pins_desc[2]);
102
103         return 0;
104 }
105
106 int myKey_fasync(int fd, struct file *filp, int on)
107 {        
108         printk('driver: fasync_initn');
109         fasync_helper(fd, filp, on, &button_fasyncq);
110
111         return 0;
112 }
113
114 static ssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
115 {
116         //无中断进入休眠
117         wait_event_interruptible(button_waitq, ev_press);
118
119         ev_press = 0;        //清除中断发生标志
120         copy_to_user(buf, &keyVal, 1);
121         return 0;
122 }
123
124 static int __init myKey_init(void)
125 {
126         /* 物理地址映射成虚拟地址 */
127         gpfcon = (volatile unsigned long*)ioremap(0x56000050, 16);
128         gpfdat = gpfcon + 1;
129
130         gpgcon = (volatile unsigned long*)ioremap(0x56000060, 16);
131         gpgdat = gpgcon + 1;
132
133         major = register_chrdev(0, 'myKey', &myKey_fops);
134         
135         myKey_class = class_create(THIS_MODULE, 'myKeyclass');
136         myKey_class_dev = class_device_create(myKey_class, NULL, MKDEV(major, 0), NULL, 'myKey');
137
138         return 0;
139 }
140
141 static void __exit myKey_exit(void)
142 {
143         /* 释放虚拟地址映射 */
144         iounmap(0x56000050);
145         iounmap(0x56000060);
146
147         unregister_chrdev(major, 'myKey');
148
149         class_device_unregister(myKey_class_dev);
150         class_destroy(myKey_class);
151         return;
152 }
153
154 module_init(myKey_init);
155 module_exit(myKey_exit);

   

   

app

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7
8 int fd;
9
10 void handle_signal(int signum)
11 {
12         unsigned char keyVal;
13
14         read(fd, &keyVal, 1);
15         printf('keyVal: 0x%xn', keyVal);
16
17         return;
18 }
19
20
21 int main (void)
22 {
23         int oflag = 0;
24
25         printf('test app!n');
26
27         fd = open('/dev/myKey', O_RDWR);
28         if(fd < 0)
29         {
30                 printf('open failed! %dn', fd);
31                 return -1;
32         }
33
34         signal(SIGIO, handle_signal);
35         
36         fcntl(fd, F_SETOWN, getpid());
37         oflag = fcntl(fd, F_GETFL);
38         fcntl(fd, F_SETFL, oflag | O_ASYNC);
39         
40         while(1)
41         {
42                 sleep(5);
43         }
44         return 0;        
45 }

[1] [2]
关键字:异步通知  应用程序  键值 引用地址:异步通知

上一篇:用定时器实现按键消抖
下一篇:同步、互斥、阻塞

推荐阅读最新更新时间:2026-03-20 11:14

Tiny210驱动之按键异步通知
fifth_drv.c驱动源码: #include linux/device.h #include linux/interrupt.h #include linux/module.h #include linux/kernel.h #include linux/fs.h #include linux/init.h #include linux/delay.h #include linux/irq.h #include asm/uaccess.h #include asm/irq.h #include asm/io.h #include mach/gpio.h #include linux/poll.h s
[单片机]
[单片机框架] [kv_sys] 实现一个简易KV键值系统
Env 小型KV数据库,支持 写平衡(磨损平衡) 及掉电保护模式 让Flash变为NoSQL(非关系型数据库)模型的小型键值(Key-Value)存储数据库。在产品上,能够更加简捷的实现 设定参数 或掉电保存的功能。 功能: 简易设置KEY和VAL,自动垃圾回收。至少需要占用两页FLASH空间。 平衡flash读写,提高flash擦写寿命 介绍 资源占用 RAM 16 字节 ROM 约500字节 支持平台 各类单片机 函数简洁 void *kv_get_env(uint8_t key_id); bool kv_del_env(uint8_t key_id); bool kv_set_env(uint8_t ke
[单片机]
[单片机框架] [kv_sys] 实现一个简易KV<font color='red'>键值</font>系统
[单片机框架] [kv_sys] 实现一个简易KV键值系统(升级版)
Env 小型KV数据库,支持 写平衡(磨损平衡) 及掉电保护模式 让Flash变为NoSQL(非关系型数据库)模型的小型键值(Key-Value)存储数据库。在产品上,能够更加简捷的实现 设定参数 或掉电保存的功能。 功能: 简易设置KEY和VAL,自动垃圾回收。至少需要占用两页FLASH空间。 平衡flash读写,提高flash擦写寿命 资源占用 RAM 16 字节 ROM 582字节 支持平台 各类单片机 函数简洁 void kv_gc_env(void); void kv_gc_check(void); void *kv_get_env(uint8_t key_id); bool kv_del_env
[单片机]
[单片机框架] [kv_sys] 实现一个简易KV<font color='red'>键值</font>系统(升级版)
MSP430f149红外接收头—读任意红外遥控器键值并显示于数码管
刚学单片机(msp430f149 DM430-A),试了试红外接头(1838),读取红外遥控器的键值,并以十进制显示在数码管上,如果以后准备将这个遥控器作为其他用途还可以把数码管上的键值化成16进制使用如(74——0x4A)。 如果有哪里不正确,期待大家给我改正,共同进步! (部分代码摘自网络) #include msp430x14x.h #define uchar unsigned char #define uint unsigned int #define ulong unsigned long #define CPU_F ((double)8000000) #define delay_us(x) __delay_
[单片机]
HT6221/2解码成标准的键值
一.HT6221遥控器芯片简介 1. 特征 * 工作电压: 1.8V~3.5V * Dout输出38KHz * 最小发射字: 一个字 * 一个455KHz的陶瓷或晶体 * 16位地址码 * 8位数据码 * ppm代码方式 * 最大活动键 HT6221: 32键 HT6222: 64键 2. 应用 * 电视和录像录音机控制器 * 夜盗警报系统 * 烟火警报系统 * 车门控制器 * 汽车警报系统 * 安全系统 * 其它遥控系统 3. 概述 HT6221/HT6222能编码16位地址码和8位数据码, HT6221/HT6222包含32键(K1~K32)和64键(K1~K64) 4. 引脚图 5. 方框图 6. 引
[单片机]
HT6221/2解码成标准的<font color='red'>键值</font>
键值MC51单片机子程序实例
;取键值程序 ;功能:等待键入,并刷新显示,并返回键值放A ;占用:PSW,A,DPTR,R0,R2,R3,R4,R6,R7 ;入口:无 出口:A ORG 0190H WAT_KB: MOV R0,#3FH WAT_0: ACALL DISP_0 ;刷新显示器 ACALL T_KB JZ WAT_0 ;无键,循环 ACALL KEY_LD ;延时消抖,刷新显示 JZ WAT_0 ;无键,循环 KB_VUL: CLR A CPL A MOV DPTR,#PORT_B MOVX @DPTR,A ;关显示 MOV R2,#0FEH MOV R
[单片机]
矩阵键盘的编程方法——读取键值
矩阵键盘的使用在单品机的学习当中十分广泛,可是对于许多新手,包括本人有时也是搞不明白,昨天晚上和今天早上的思考和同行们的讨论,终于有了点头绪,所以想记录下读取键盘的思路。 在单片机的学习版中,矩阵键盘通常如下图设计: 下面就以按下S16键来讲解其思路: 首先: P3的高位P3.4~P3.7输出为0,低位P3.0~P3.3输出为1;即P3=0x0F,当按下S16键后(有消抖动过程),P3.3的值为0,则P3的值更新为0x07; 其次: P3的高位P3.4~P3.7输出为1,低位P3.0~P3.3输出为0;即P3=0xF0,当按下S16键后(有消抖动过程),P3.4的值为0,则P3的值更新为0xE0; 最后将两个值相加得P3=
[单片机]
矩阵键盘的编程方法——读取<font color='red'>键值</font>
用扫描法读出4×4矩阵键盘,在数码管显示按键值
//电路说明如下。 //单片机:使用51系列兼容的即可; //4 4矩阵键盘:接在P1口; //两位数码显示器: P0口输出七段码,P2口输出位选码。 //============================================================== //C语言程序如下。 /************************************************************* * 文件名: KEY_LED.c * 功能 : 对4 4矩阵键盘进行输出,在数码管后两位显示按键值。 ***************************************************
[单片机]
用扫描法读出4×4矩阵键盘,在数码管显示按<font color='red'>键值</font>
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved