内核版本: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)
{ if(file->f_flags & O_NONBLOCK)
{
if(down_trylock(&key_lock))
return -EBUSY;
}
else
{
//获取信号量
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; if(file->f_flags & O_NONLOCK)
{
if(!ev_press)
return -EAGAIN;
}
else
{
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(,"block_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,"block_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,"block_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=; int main(int argc,char **argv)
{
unsigned char key_val=;
int oflags=; int ret;
struct pollfd fds[]; fd = open("/dev/block_ipc_poll_key",O_RDWR | O_NONBLOCK); if(fd <)
{
printf("error: can't open device :/dev/block_ipc_poll_key\n");
return -;
} while()
{
ret = read(fd,&key_val,);
printf("key_val= %d ,return= %d\n",key_val,ret);
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 +=signal_ipc_poll_key_int_drv.o

内核ipc机制的更多相关文章

  1. Android之IPC机制

    Android IPC简介 任何一个操作系统都需要有相应的IPC机制,Linux上可以通过命名通道.共享内存.信号量等来进行进程间通信.Android系统不仅可以使用了Binder机制来实现IPC,还 ...

  2. IPC机制--Binder

    文章来自 Android技术内幕 系统卷 转:http://www.linuxidc.com/Linux/2011-08/40508.htm 什么是IPC机制以及IPC机制的种类 在Linux中,是以 ...

  3. IPC 机制简介

    IPC 机制简介 概述 在Unix早期发展中,做出重大贡献的两大主力Bell实验室和伯克利大学(BSD)在IPC(InterProcess Communication)方面的侧重点有所不同.前者对Un ...

  4. Linux内核同步机制

    http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环 ...

  5. pipe()管道最基本的IPC机制

    <h4>进程间通信 fork pipe pie_t 等用法(管道机制 通信)</h4>每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之 ...

  6. [置顶] 深入理解android之IPC机制与Binder框架

    [android之IPC机制与Binder框架] [Binder框架.Parcel.Proxy-Stub以及AIDL] Abstract [每个平台都会有自己一套跨进程的IPC机制,让不同进程里的两个 ...

  7. Android IPC机制全解析<一>

    概要 多进程概念及多进程常见注意事项 IPC基础:Android序列化和Binder 跨进程常见的几种通信方式:Bundle通过Intent传递数据,文件共享,ContentProvider,基于Bi ...

  8. Android开发艺术探索——第二章:IPC机制(上)

    Android开发艺术探索--第二章:IPC机制(上) 本章主要讲解Android的IPC机制,首先介绍Android中的多进程概念以及多进程开发模式中常见的注意事项,接着介绍Android中的序列化 ...

  9. 安卓IPC机制之Binder详解

    IPC(Inter-Process Communication,跨进程通信)是指两个进程之间数据交换的过程,因此我们首先必须了解什么是进程,什么是线程. 进程:进程是正在运行的程序的实例,与程序相比, ...

随机推荐

  1. Android Studio下jni应用

    最近在将一个小应用从eclipse开发迁移到android studio,程序中有native代码实现,在eclipse是靠Android.mk这么个mk文件来组织编译的,但到android stud ...

  2. python中,numeric(数字类型)和integer(整型)的区别

    说明: 在今天做int实现的过程中,官方函数的解释是将numeric转换为integer,就突然不明白,两个有啥区别. numeric-数字类型包括: int,float,bool,complex i ...

  3. [Understanding] Compressive Sensing and Deep Model

    低维模型与深度模型的殊途同归 有助理解核心,陌生概念需要加强理解. 对于做机器学习,和做图像视觉的研究者来说,过去的十年是非常激动人心的十年.以我个人来讲,非常有幸接触了两件事情: 第一件是压缩感知( ...

  4. php 公历阴历互相转换

    <?php /** * Created by PhpStorm. * User: timeless * Date: 17-3-9 * Time: 上午9:32 */ class Lunar { ...

  5. 不可思议的颜色混合模式 mix-blend-mode (转)

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  6. [原]Jenkins(十三)---jenkins用户权限管理

    * 版权声明:本博客欢迎转发,但请保留原作者信息! http://www.cnblogs.com/horizonli/p/5337874.html 两种策略的比较

  7. 一款Redis客户端,可以作为Redis Desktop manager的有效补充或替代

    一.由来 对于redis客户端,我和大多数人一样,都是用Redis Desktop Manager. 但我发现个问题,我的版本是0.9.1.771. 我这个版本有个问题,就是如果value太长的话,不 ...

  8. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验六:数码管模块

    实验六:数码管模块 有关数码管的驱动,想必读者已经学烂了 ... 不过,作为学习的新仪式,再烂的东西也要温故知新,不然学习就会不健全.黑金开发板上的数码管资源,由始至终都没有改变过,笔者因此由身怀念. ...

  9. ubuntu-16.04更好软件源

    author: headsen chen date:2019-03-06  14:01:07 1,修改软件源文件成如下的清华大学的源(亲测可用) root@ubuntu:/var/lib/apt/li ...

  10. 170825、SolrCloud 分布式集群部署步骤

    安装软件包准备 apache-tomcat-7.0.54 jdk1.7 solr-4.8.1 zookeeper-3.4.5 注:以上软件都是基于 Linux 环境的 64位 软件,以上软件请到各自的 ...