内核block机制
内核版本:linux2.6.22.6 硬件平台:JZ2440
驱动源码 block_ipc_poll_key_int_drv.c :
#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 <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/poll.h> static struct class *key_int_class;
static struct class_device *key_int_class_device; volatile unsigned long *GPFCON=NULL;
volatile unsigned long *GPFDAT=NULL;
volatile unsigned long *GPGCON=NULL;
volatile unsigned long *GPGDAT=NULL; static struct fasync_struct fasync_key; //定义一个 fsync 结构体 struct pin_desc
{
unsigned int pin;
unsigned int key_val;
}; static unsigned char key_val;
static volatile int ev_press=; static struct pin_desc pin_desc_array[]={{S3C2410_GPF0,0x01},{S3C2410_GPF2,0X02},{S3C2410_GPG3,0x03},{S3C2410_GPG11,0x04}}; static DECLARE_WAIT_QUEUE_HEAD(wait_key); //定义一个信号量
static DECLARE_MUTEX(key_lock); static irqreturn_t key_handler(int irq, void *dev_id)
{
struct pin_desc *pindesc = (struct pin_desc *)dev_id;
unsigned int pinval=; pinval = s3c2410_gpio_getpin(pindesc->pin); if(pinval) key_val = 0x08 | pindesc->key_val;
else key_val = pindesc->key_val; kill_fasync(&fasync_key,SIGIO,POLL_IN); //发生中断后 向结构体里的PID进程 发送 SIGIO 信号 wake_up_interruptible(&wait_key);
ev_press = ;
return IRQ_RETVAL(IRQ_HANDLED);
} static int key_drv_open(struct inode *inode,struct file *file)
{
//获取信号量
down(&key_lock); request_irq(IRQ_EINT0, key_handler,IRQT_BOTHEDGE,"KEY1", &pin_desc_array[]);
request_irq(IRQ_EINT2, key_handler,IRQT_BOTHEDGE,"KEY2", &pin_desc_array[]);
request_irq(IRQ_EINT11, key_handler,IRQT_BOTHEDGE,"KEY3",&pin_desc_array[]);
request_irq(IRQ_EINT19, key_handler,IRQT_BOTHEDGE,"KEY4",&pin_desc_array[]); return ;
} ssize_t key_drv_read(struct file *file,const char __user *buf,size_t count,loff_t *ppos)
{
if (count != )
return -EINVAL; wait_event_interruptible(wait_key,ev_press);
ev_press=;
copy_to_user(buf,&key_val,); return ;
} static int key_drv_close(struct inode *inode,struct file *file)
{
free_irq(IRQ_EINT0, &pin_desc_array[]);
free_irq(IRQ_EINT2, &pin_desc_array[]);
free_irq(IRQ_EINT11, &pin_desc_array[]);
free_irq(IRQ_EINT19, &pin_desc_array[]); //释放信号量
up(&key_lock);
return ;
} unsigned int key_drv_poll(struct file *file,poll_table *wait)
{
unsigned int mask=;
poll_wait(file,&wait_key,wait); if(ev_press) mask |= POLLIN | POLLRDNORM; return mask;
} static int init_fasync(int fd,struct file *file,int on) // 初始化FASYNC 结构体
{
printk("init fasync struct...\n");
return fasync_helper(fd,file,on,&fasync_key);
} static struct file_operations key_drv_mode=
{
.owner = THIS_MODULE,
.open = key_drv_open,
.read = key_drv_read,
.release = key_drv_close,
.poll = key_drv_poll,
.fasync = init_fasync,
}; int major=;
static int key_drv_init(void)
{
major = register_chrdev(,"signal_ipc_poll_key",&key_drv_mode); // /proc/devices key_int_class = class_create(THIS_MODULE,"key_int_class");
key_int_class_device = class_device_create(key_int_class,NULL,MKDEV(major,),NULL,"signal_ipc_poll_key"); // /dev/key_int_drv GPFCON=(volatile unsigned long *)ioremap(0x56000050,);
GPFDAT=GPFCON+;
GPGCON=(volatile unsigned long *)ioremap(0x56000060,);
GPGDAT=GPGCON+; return ;
} static void key_drv_exit(void)
{
unregister_chrdev(major,"signal_ipc_poll_key"); class_device_unregister(key_int_class_device);
class_destroy(key_int_class);
iounmap(GPFCON);
iounmap(GPGCON); } module_init(key_drv_init);
module_exit(key_drv_exit);
MODULE_LICENSE("GPL");
测试应用程序 block_ipc_poll_key_int_drv_test.c :
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h> int fd=; void act_fun(void) // 捕获信号响应函数
{
unsigned char key_val=;
read(fd,&key_val,);
printf("key_val= %d\n",key_val);
} int main(int argc,char **argv)
{
unsigned char key_val=;
int oflags=; int ret;
struct pollfd fds[]; fd = open("/dev/signal_ipc_poll_key",O_RDWR); if(fd <)
{
printf("error: can't open device :/dev/signal_ipc_poll_key\n");
return -;
} signal(SIGIO,act_fun); //捕获信号 fcntl(fd,F_SETOWN,getpid()); //应用程 序用 fcntl 告诉fd驱动 当前应用程序的PID
oflags = fcntl(fd,F_GETFL); // 获取 fd驱动的 状态旗标
fcntl(fd,F_SETFL,oflags|FASYNC);//更新oflags while()
{
sleep();
}
return ;
}
Makefile文件:
KER_DIR=/work/systems/kernel/linux-/linux-2.6.22.6 all:
make -C $(KER_DIR) M=`pwd` modules clean:
make -C $(KER_DIR) M=`pwd` modules clean
rm -fr moudles.order obj-m +=block_ipc_poll_key_int_drv.o
内核block机制的更多相关文章
- Linux内核同步机制--转发自蜗窝科技
Linux内核同步机制之(一):原子操作 http://www.wowotech.net/linux_kenrel/atomic.html 一.源由 我们的程序逻辑经常遇到这样的操作序列: 1.读一个 ...
- Linux 内核同步机制
本文将就自己对内核同步机制的一些简要理解,做出一份自己的总结文档. Linux内部,为了提供对共享资源的互斥访问,提供了一系列的方法,下面简要的一一介绍. Technorati 标签: ...
- Linux内核同步机制之(四):spin lock【转】
转自:http://www.wowotech.net/kernel_synchronization/spinlock.html 一.前言 在linux kernel的实现中,经常会遇到这样的场景:共享 ...
- 锁相关知识 & mutex怎么实现的 & spinlock怎么用的 & 怎样避免死锁 & 内核同步机制 & 读写锁
spinlock在上一篇文章有提到:http://www.cnblogs.com/charlesblc/p/6254437.html 通过锁数据总线来实现. 而看了这篇文章说明:mutex内部也用到 ...
- [内核同步]浅析Linux内核同步机制
转自:http://blog.csdn.net/fzubbsc/article/details/37736683?utm_source=tuicool&utm_medium=referral ...
- Linux内核同步机制
http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环 ...
- Linux内核OOM机制的详细分析(转)
Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典 ...
- Linux内核OOM机制的详细分析
Linux 内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核会把该进程杀掉.典型的 ...
- Linux内核同步机制之(五):Read Write spin lock【转】
一.为何会有rw spin lock? 在有了强大的spin lock之后,为何还会有rw spin lock呢?无他,仅仅是为了增加内核的并发,从而增加性能而已.spin lock严格的限制只有一个 ...
随机推荐
- 稍稍解读下JDK8的HashMap
首先,源码中上来就有一大段注释,但最重要的就是第一句. 大意如下: 本map经常用作一个 binned (bucketed) hash table (下面有解释),但是,当bins很大的时候,它们会被 ...
- Python——特殊属性与方法
Python 对象 中以双下划线开头和结尾的属性称为特殊属性,由于对象的方法也属于属性,因此以双下划线开头和结尾的方法称为特殊方法.对这些对象执行一些特定的运算时,Python会自动视图调用这些实例的 ...
- Mac vim“装逼”配置
配置c++ 等编程语言补全等 from blog http://www.cnblogs.com/xiaobo-Linux/p/8909402.html 1. 安装 macvim brew instal ...
- 浅析C#中的结构体和类
类和结构是 .NET Framework 中的常规类型系统的两种基本构造. 两者在本质上都属于数据结构.封装着一组总体作为一个逻辑单位的数据和行为. 数据和行为是该类或结构的"成员" ...
- [PGM] Markov Networks
6 Markov Networks 系列 因果影响的独立性 noisy-or模型 和 广义线性模型 略,暂时不感兴趣. Pairwise Markov Networks The last col is ...
- CentOS使用virt-what知道虚拟机的虚拟化技术
通常拿到一台vps,提供商可能不会告诉我们具体的虚拟化技术,对于CentOS的系统的vm,可以使用virt-what来知道. 如果提示virt-what命令找不到,则需要安装一下 yum instal ...
- Git工作流程最佳实践总结
Git作为一个目前非常流行的版本管理工具,深受开发者的喜爱.那么怎样才能将Git的作用发挥的更好呢?我根据实际的项目经验,归纳总结了以下Git工作流的最佳实践.这里所谓的最佳,是经过多次项目经验后,根 ...
- 【!Important】Java线程死锁查看分析方法
一.Jconsole Jconsole是JDK自带的图形化界面工具,使用JDK给我们提过的工具JConsole,可以通过cmd打开命令框然后输入Jconsole打开图形工具 然后点击检测死锁就可以查看 ...
- 5.STM32通用定时器TIM3中断
1.通用定时器TIM3中断 #include "timer.h" #include "led.h" void TIM3_Int_Init(u16 arr,u16 ...
- ztree 文件夹类型的 树状图
未套程序的源代码: 链接:http://pan.baidu.com/s/1nuHbxhf 密码:4aw2 已套程序的源代码: css样式: /*发布邮件 选择领导弹窗*/ .xuandao{ disp ...