完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 qq448309212947 于 2015-11-14 12:31 编辑
一、poll机制 1.驱动程序: static unsigned key_poll(struct file *file, poll_table *wait) poll驱动函数 { unsigned int mask = 0; poll_wait(file, &button_waitq, wait); 进入poll等待模式,等待事件发生或超时退出 if(ev_press) mask |= POLLIN | POLLRDNORM; 普通或优先级带数据可读,普通数据可读 return mask; } 2.应用程序: struct pollfd fds[1]; 定义pollfd结构类型的数组 fds[0].fd = fd; 保存文件信息 fds[0].events = POLLIN; 将测试条件设置成普通或优先级带数据可读 while(1) { a = poll(fds, 1, 5000); 调用poll函数,等待5s,只读取一个中断值 if(a == 0) 无中断触发,返回0 { printf("time outn"); } else { read(fd,&x,1); 读取信息:进入读取函数,触发休眠,被唤醒后才会继续执行程序 printf("x = %dn",x); 打印出读取的信息 } } 二、异步通知 1.驱动程序: static struct fasync_struct *button_async; 定义异步通知结构体 static irqreturn_t button_irq(int irq, void *dev_id) 中断服务函数 { struct key_desc * pindesc = (struct key_desc *) dev_id; 取出按键信息 unsigned int pinval; pinval = gpio_get_value(pindesc->pin); 获IO键值 if(pinval) 处理键值 { value = 0x80 | pindesc->value; } else { value = pindesc->value; } kill_fasync(&button_async, SIGIO, POLL_IN); 激发相应的信号 return IRQ_RETVAL(IRQ_HANDLED); } static int key_fasync(int fd, struct file *filp, int on) 异步通知 { return fasync_helper(fd, filp, on, &button_async); 初始化异步通知 } 2.应用程序: # include <fcntl.h> fcntl所需要的头文件 #include <unistd.h> 以上两者都需要的头文件 int fd, oflags; void my_signal_fun(int signum) 异步通知处理函数 { unsigned char key_val; read(fd, &key_val, 1); 读取按键值 printf("key_val = %d n", key_val); } int main(int argc, char **argv) { signal(SIGIO, my_signal_fun); 定义SIGIO为异步通知信号, my_signal_fun为异步通知处理函数 fd = open("/dev/signal",0); if(fd<0) { printf("driver not or dev name notn"); return fd; } fcntl(fd, F_SETOWN, getpid()); 设置异步I/O所有权:节点信息,命令,进程PID oflags = fcntl(fd, F_GETFL); 获取文件状态标记 fcntl(fd, F_SETFL, oflags | FASYNC); 设置文件状态标记,即增加异步状态 FASYNC:当I/O可用的时候,允许SIGIO信号发送到进程组,例如:当有数据可以读的时候 while(1) { sleep(1000); 休眠程序 } return 0; } 三、互斥阻塞 互斥机制:信号量——用于保护临界区的一种常见方法,只有得到信号量的进程才能执行临界区代码 static DECLARE_MUTEX(button_lock); 静态定义和初始化一个互斥锁/信号量 #define __SEMAPHORE_INITIALIZER(name, n) { .lock = __SPIN_LOCK_UNLOCKED((name).lock), .count = n, .wait_list = LIST_HEAD_INIT((name).wait_list), } #define DECLARE_MUTEX(name) struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1) 在OPEN函数中添加: down(&button_lock); 开启互斥锁/获得信号量,无法获得便会进入休眠 在CLOSE函数中添加: up(&button_lock); 关闭互斥锁/释放信号量 开启互斥锁后,其他程序无法访问互斥锁之后的代码,会陷入不可中断的睡眠状态;当之前的进程被杀死时,睡眠的进程就会被唤醒。 阻塞机制:阻塞—执行设备操作时若不能获得资源则挂起进程。直到满足可操作的条件后再进行操作。 被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。 非阻塞—进程在不能进行设备操作时并不挂起,会放弃或者不断的查询,直到可以进行操作为止。 应用程序: fd = open("/dev/open",O_RDWR | O_NONBLOCK); 以非阻塞模式打开 fd = open("/dev/open",O_RDWR ); 以阻塞模式打开 OPEN函数中: if(file->f_flags & O_NONBLOCK) 若为非阻塞模式,则尝试开启互斥,即无法开启不会休眠 { if(down_trylock(&button_lock)) return -EBUSY; } else 若为阻塞模式,则开启互斥,即无法开启则会休眠 { down(&button_lock); } READ函数中: if(file->f_flags & O_NONBLOCK) 若为非阻塞模式,则判断是否有按键按下 { if(!ev_press) return -EAGAIN; } else 若为阻塞模式,则等待按键发生 { wait_event_interruptible(button_waitq,ev_press); } 下面是源代码:
新建文件夹.zip
(8.18 KB, 下载次数: 0
)
|
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
1897个成员聚集在这个小组
加入小组我的项目我做主,使用GN+Ninja来完成构建系统(VSCode开发RT106X)
36307 浏览 0 评论
NXP IMX8应用处理器快速入门必备:技巧、使用、设计指南
4373 浏览 0 评论
6030 浏览 1 评论
6748 浏览 0 评论
NXP i.MX6UL开发板(linux系统烧录+规格+硬件+模块移植)使用手册
4197 浏览 0 评论
605浏览 2评论
求助,S32G上Core M启动后如何让Core A在Flash指定位置加载uboot?
598浏览 2评论
ESP32-WROVER-IE + LAN8720以太网,GPIO0电压只有1.6v,无法正常进入spi flash boot模式如何解决?
589浏览 2评论
求分享适用于PN7160 Android的NFC工厂测试应用程序
678浏览 2评论
772浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-6 01:18 , Processed in 0.817279 second(s), Total 47, Slave 36 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号