关于 exynos 4412 按键中断 异步通知
以下是驱动测试代码:
//内核的驱动代码
#include <linux/init.h>
#include <linux/module.h> //for module_init moudule_exit
#include <linux/fs.h>	  //for MKDEV register_chrdev_region
#include <linux/cdev.h>  //字符设备头文件
#include <linux/device.h>
#include <asm/io.h>  //for ioremap
#include <linux/platform_device.h>   //for  平台设备
#include <linux/of.h>
#include <linux/signal.h>
#include <linux/interrupt.h>
#define  LED_MA   500    //主设备号(那一类设备)
                                    //某些主设备号已经静态地分配给了大部分公用设备。见Documentation/devices.txt 。 这里我们常使用250
#define  LED_MI   2       //次设备号(这类设备当中的具体哪个设备)
//目标:把字符设备改造为平台设备
//1. 把硬件信息,分离出去,放到设备树
//#define LED3CON  0X11000C20
//#define LED3DAT  0x11000c24
struct resource *led_res_con;
struct resource *led_res_dat;
struct resource *key1_res; //devices source pointer
struct fasync_struct *async_queue; /* 异步结构体指针,用于读 */
struct cdev   led;  //定义一个字符设备
#define LED_MAGIC   'L'  //幻数,类似加密,避免误操作
#define LED_ON  _IOW(LED_MAGIC, 1, int)
#define LED_OFF _IOW(LED_MAGIC,2,int)
unsigned int *led3_con;
unsigned int *led3_dat;
int led_open (struct inode *inode, struct file *file)
{
  led3_con  =  ioremap((phys_addr_t)led_res_con,1); //把硬件的物理地址转换为内核的虚拟地址
  if(led3_con == NULL){
     printk("led3_con ioremap fail\n");
     return -1;
  }
  led3_dat  =  ioremap((phys_addr_t)led_res_dat,1);
  if(led3_dat == NULL){
     printk("led3_dat ioremap fail\n");
     return -1;
  }
writel((readl(led3_con) & (~0xf)) | 1,led3_con);//led3 and key2 had use same register;
    writel(1,led3_dat);
printk("led_open ok\n");
   return 0;
}
int led_release(struct inode *inode, struct file *file)
{
 	free_irq(key1_res->start, NULL);
	printk("remove OK\n");
printk("led_release ok\n");
return 0;
}
//实现自定义的个性化操作
long led_ioctl(struct file *file, unsigned int cmd, unsigned long args)
{
switch(cmd)  //解析ioctl 命令
   {
   case  LED_ON:  //点亮灯
   	 printk("led on cmd=%d\n",cmd);
	 writel(1,led3_dat);
   	break;
   case  LED_OFF: //灭灯
   	 printk("led off cmd=%d\n",cmd);
	 writel(0,led3_dat);
   	break;
   default:
   	printk("ioctl cmd no found\n");
   	break;
   }
printk("led_ioctl end\n");
   return 0;
}
irqreturn_t key_interrupt(int irqno, void *devid)
{
kill_fasync(&async_queue, SIGIO, POLL_IN);  //发送SIGIO 异步通知信号
	printk("irqno = %d\n", irqno);
	return IRQ_HANDLED;
}
int key_fasync (int fd,struct file *filp,int mode)
{
    return fasync_helper(fd,filp,mode,&async_queue);//处理标志的变更
}
//3.实现设备的文件操作
struct file_operations  fops={  //设备的文件操作
  .owner = THIS_MODULE,
  .open = led_open,
  .release = led_release,
  .unlocked_ioctl = led_ioctl,
  .fasync = key_fasync,
};
int led_init(struct platform_device *pdev)   //把找到的平台设备的信息传进来
{
    int ret;
    dev_t dev_id= MKDEV(LED_MA, LED_MI); //把主次设备号合并生成设备ID
//1.注册设备号
    ret =register_chrdev_region(dev_id,1,"test_led");
    if(ret<0){
         printk("regiser led fail\n ");
	  return -1;
    }
//2.初始化字符设备
    cdev_init(&led,&fops);  //字符设备初始化
    ret =cdev_add(&led,dev_id,1);  //添加字符设备到系统中
     if(ret<0){
         printk("cdev add led fail\n ");
	  return -1;
    }
led_res_con = pdev->resource[0].start;
    led_res_dat = 	 pdev->resource[1].start;
    printk("led init go  1\n");
/*****************************************************/
	key1_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (key1_res == NULL) {
		printk("No resource !\n");
		return -ENODEV;
	}
ret = request_irq(key1_res->start,  //硬件中断号  对应exynos4412-test4412.dts中test4412-key  interrupts = <1 2>中的1
	                  key_interrupt,  //中断处理函数
	                  key1_res->flags,  //中断标志   IRQF_DISABLED 在表示中断处理时屏蔽掉其它所有中断
	                  "key2",  //中断名称  在cat /proc/interrupts  克看到
	                  NULL);
	if (ret < 0) {
		printk("failed request irq: irqno = irq_res->start");
		return ret;
	}
	printk("key irq init ok\n");
/*********************************************************/
return 0;  //返回值为零表示运行成功 ,负值表示失败
}
void led_exit(void)
{
dev_t dev_id= MKDEV(LED_MA, LED_MI);
    cdev_del(&led);  //删除设备
    unregister_chrdev_region(dev_id, 1);  //取消注册
    printk("led exit go\n");
}
//2.把内核模块的入口,改为platform_driver的入口
//module_init(led_init);
//module_exit(led_exit);
static const struct of_device_id machled[] = {
 { .compatible = "test,led3"},	  //必须和设备树里的设备名字一样
 {},
};
MODULE_DEVICE_TABLE(of, machled);
struct platform_driver led_platform_driver = {
  .driver = {
  	 .name = "test_led",
	 .owner = THIS_MODULE,
	 .of_match_table = of_match_ptr(machled),
  },
  .probe = led_init,
  .remove = led_exit,
};
module_platform_driver(led_platform_driver); //声明led_platform_driver为平台设备驱动的加载入口
MODULE_LICENSE("Dual BSD/GPL");
接下来是测试代码:
#include <stdio.h> 
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#define LED_MAGIC 'L'
//#define LED_ON  1
//#define LED_OFF 2
#define LED_ON  _IOW(LED_MAGIC, 1, int)
#define LED_OFF _IOW(LED_MAGIC,2,int)
int flag = 0;
void input_handler (int signum)
{
printf("receive a signal from globalfifo, signalnum : %d\n",signum);
    flag = 1;
}
int main(int argc, char **argv)
{
        int fd = open("/dev/led", O_RDWR);
if (fd < 0) {
         printf("open /dev/led fail\n");
         return -1;
	    }
int oflags;
    signal(SIGIO, input_handler); //让input_handler()处理SIGIO信号
    fcntl(fd, F_SETOWN, getpid());  //设置设备文件的所有者为本进程
    oflags = fcntl(fd, F_GETFL);    // 会调用 驱动中的 .fasync
    fcntl(fd, F_SETFL, oflags | FASYNC);  //FASYNC  设置支持异步通知模式
while(1)
    {
        sleep(100);
        if (flag)
        {
	        ioctl(fd, LED_OFF);  //ioctl 实现设备的个性化操作(可自定义命令)
            printf("LED_OFF\n");  //注意要加\n 否则打印信息可能没有
flag = 0;
}
    }
}
最后测试下来还是有一些小问题,后续再看;
关于 exynos 4412 按键中断 异步通知的更多相关文章
- Linux 进程间通信 --- 信号通信 --- signal --- signal(SIGINT, my_func); --- 按键驱动异步通知(转)
		
信号 ( signal ) 机制是 UNIX 系统中最为古老的进程间通信机制,很多条件可以产生一个信号. 信号的产生: 1,当用户按下某些按键时,产生信号. 2,硬件异常产生信号:除数为 0 ,无效 ...
 - 嵌入式Linux驱动学习之路(十三)按键驱动-异步通知
		
之前的按键方式: 查询: 极度占用CPU资源 中断: 在读的时候产生休眠,在没有信号的时候永远不会返回. poll机制: 在中断的基础上加上超时时间. 异步通知就是通过信号来传送. 首先在应用程序中有 ...
 - Linux学习 :按键信号 之 异步通知
		
一.异步通知概念: 异步通知是指:一旦设备就绪,则主动通知应用程序,应用程序根本就不需要查询设备状态,类似于中断的概念,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是异步的,一个进 ...
 - 入门级的按键驱动——按键驱动笔记之poll机制-异步通知-同步互斥阻塞-定时器防抖
		
文章对应视频的第12课,第5.6.7.8节. 在这之前还有查询方式的驱动编写,中断方式的驱动编写,这篇文章中暂时没有这些类容.但这篇文章是以这些为基础写的,前面的内容有空补上. 按键驱动——按下按键, ...
 - Linux内核中断引入用户空间(异步通知机制)【转】
		
转自:http://blog.csdn.net/kingdragonfly120/article/details/10858647 版权声明:本文为博主原创文章,未经博主允许不得转载. 当Linux内 ...
 - liunx驱动----异步通知
		
查询:消耗资源 中断:read 一直要去读 poll :指定起始时间 异步通知 signal 测试程序 include <stdio.h> include <signal.h> ...
 - Linux驱动之异步通知的应用
		
前面的按键驱动方式都是应用程序通过主动查询的方式获得按键值的: 1.查询方式 2.中断方式 3.poll机制 下面介绍第四种按键驱动的方式 4.异步通知:它可以做到应用程序不用随时去查询按键的状态,而 ...
 - Linux之异步通知20160702
		
异步通知,主要说的是使用信号的方式,同时使用信号也是实现进程之间通信的一种方式. 多的不说,我们直接看代码: 首先应用程序的: #include <sys/types.h> #includ ...
 - linux驱动的异步通知(kill_fasync,fasync)---- 驱动程序向应用程序发送信号
		
应用程序 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include < ...
 
随机推荐
- 切比雪夫定理(Chebyshev's theorem)与经验法则(Empirical Rule)
			
切比雪夫定理(Chebyshev's theorem):适用于任何数据集,而不论数据的分布情况如何. 与平均数的距离在z个标准差之内的数值所占的比例至少为(1-1/z2),其中z是大于1的任意实数. ...
 - uni-app 图片上传实战
			
uni.uploadFile()将本地资源上传到开发者服务器客户端发起一个post请求content-type multipart/form-data 通过uni.chooseImage获取一个本地资 ...
 - JQuery的Ajax标准写法
			
Ajax的标准写法 $.ajax({ url:"http://www.xxx",//请求的url地址 dataType:"json",//返回的格式为json ...
 - 在Visual Studio中直接编译Fluent的UDF(修正)
			
原文见:http://blog.sina.com.cn/s/blog_14d64daa10102xkg4.html 主要是修正几个问题: 首先是头文件填入的顺序需要严格按照我前文给出的顺序填写,否则可 ...
 - 【Alpha】“北航社团帮”小程序v1.0发布声明
			
我们的"北航社团帮"小程序发布啦!!! Alpha版本功能 功能列表和详情图 模块 功能 登录 授权登录,游客模式,无需填写信息 活动展示 首页轮播热度最高的四个活动,查看活动详情 ...
 - CloudFlare上线了新的Proxy Anything选项, 支持转发TCP连接
			
https://www.nicho1as.wang/articles/cf-proxy-anything.html 申请地址:https://goo.gl/forms/Oc2jyyo0kXsrMyw3 ...
 - odoo开发笔记 -- 触发机制/埋点设置
			
场景描述: 项目需求中,经常会需要,当某个字段处某个特定状态时候,触发执行特定的方法:或者创建某条记录的时候,同时做另一个操作:如何实现类似的需求? 实现方式: odoo中提供了几种触发方式: 1. ...
 - MQTT研究之EMQ:【EMQX使用中的一些问题记录(4)】
			
最近比较忙,有些关于EMQ的使用问题,没有时间记录了,趁这个周末抽点时间,将最近遇到的,觉得比较有价值的一个问题,分享给大家吧. 这里是针对前面的一篇博客,做的一个深入研究,关于订阅系统总线判断设备上 ...
 - 查看当前页面的jsp文件【我】
			
方法一:可以通过看html类型的请求 方法二:对于有些嵌入的子页面,也可以通过,鼠标右键——此框架——查看框架源代码的方式,直接找到对应的jsp 直接就可以看到对应的jsp:
 - 设置ESXi宿主机开机自动启动虚拟机
			
转载于 https://blog.csdn.net/Form_/article/details/71170813 在百度上面找了一圈都是讲ESXi6.0之前的版本,在VMware vSphere Cl ...