历史上的今天

今天是:2024年10月12日(星期六)

正在发生

2018年10月12日 | Tiny210驱动之按键中断实验

发布者:春水碧于天 来源: eefocus关键字:Tiny210驱动  按键中断 手机看文章 扫描二维码
随时随地手机看文章

third_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"

static struct class *thirddrv_class;

volatile unsigned long *gph2con;

volatile unsigned long *gph2dat;

volatile unsigned long *gph3con;

volatile unsigned long *gph3dat;

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

// 中断事件标志, 中断服务程序将它置1,third_drv_read将它清0 

static volatile int ev_press = 0;

struct pin_desc{

    unsigned int pin;

    unsigned int key_val;

};

// 键值: 按下时, 0x01, 0x02, 0x03, 0x04, 0x05 

// 键值: 松开时, 0x81, 0x82, 0x83, 0x84, 0x85 

static unsigned char key_val;

struct pin_desc pins_desc[5] = {

    {S5PV210_GPH2(3), 0x01},

    {S5PV210_GPH3(0), 0x02},

    {S5PV210_GPH3(1), 0x03},

    {S5PV210_GPH3(2), 0x04},

    {S5PV210_GPH3(3), 0x05},

};

// 确定按键值 

static irqreturn_t buttons_irq(int irq, void *dev_id)

{

    struct pin_desc * pindesc = (struct pin_desc *)dev_id;

    unsigned int pinval;

    

    pinval = gpio_get_value(pindesc->pin);

    if (pinval)

    {

        // 松开 

        key_val = 0x80 | pindesc->key_val;

    }

    else

    {

        // 按下 

        key_val = pindesc->key_val;

    }

    ev_press = 1;                           // 表示中断发生了 

    wake_up_interruptible(&button_waitq);   // 唤醒休眠的进程 

    

    return IRQ_RETVAL(IRQ_HANDLED);

}

static int third_drv_open(struct inode *inode, struct file *file)

{

    // 注册中断 

    request_irq(IRQ_EINT(19),  buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, 

                        "K4", &pins_desc[0]);

    request_irq(IRQ_EINT(24),  buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, 

                        "K5", &pins_desc[1]);

    request_irq(IRQ_EINT(25), buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, 

                         "K6", &pins_desc[2]);

    request_irq(IRQ_EINT(26), buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, 

                         "K7", &pins_desc[3]);    

    request_irq(IRQ_EINT(27), buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,

                         "K8", &pins_desc[4]);    

    return 0;

}

ssize_t third_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)

{

    if (size != 1)

        return -EINVAL;

    // 如果没有按键动作, 休眠 

    wait_event_interruptible(button_waitq, ev_press);

    // 如果有按键动作, 返回键值 

    copy_to_user(buf, &key_val, 1);

    ev_press = 0;

    

    return 1;

}

int third_drv_close(struct inode *inode, struct file *file)

{

    free_irq(IRQ_EINT(19), &pins_desc[0]);

    free_irq(IRQ_EINT(24), &pins_desc[1]);

    free_irq(IRQ_EINT(25), &pins_desc[2]);

    free_irq(IRQ_EINT(26), &pins_desc[3]);

    free_irq(IRQ_EINT(27), &pins_desc[4]);

    return 0;

}

static struct file_operations sencod_drv_fops = {

    .owner  =  THIS_MODULE,    // 这是一个宏,推向编译模块时自动创建的__this_module变量 

    .open    =  third_drv_open,     

    .read     =  third_drv_read,       

    .release =  third_drv_close,       

};

int major;

static int third_drv_init(void)

{

    major = register_chrdev(0, "third_drv", &sencod_drv_fops);

    thirddrv_class = class_create(THIS_MODULE, "third_drv");

    device_create(thirddrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); // /dev/buttons 

    gph2con = (volatile unsigned long *)ioremap(0xe0200c40, 16);

    gph2dat = gph2con + 1;

    gph3con = (volatile unsigned long *)ioremap(0xE0200C60, 16);

    gph3dat = gph3con + 1;

    return 0;

}

static void third_drv_exit(void)

{

    unregister_chrdev(major, "third_drv");

    device_destroy(thirddrv_class, MKDEV(major, 0));

    class_destroy(thirddrv_class);

    iounmap(gph2con);

    iounmap(gph3con);

    return 0;

}

module_init(third_drv_init);

module_exit(third_drv_exit);

MODULE_LICENSE("GPL");

===================================================================

thirddrvtest.c测试程序:

#include "sys/types.h"

#include "sys/stat.h"

#include "fcntl.h"

#include "stdio.h"

// thirddrvtest 

int main(int argc, char **argv)

{

    int fd;

    unsigned char key_val;

    

    fd = open("/dev/buttons", O_RDWR);

    if (fd < 0)

    {

        printf("can't open!\n");

    }

    while (1)

    {

        read(fd, &key_val, 1);

        printf("key_val = 0x%x\n", key_val);

    }

    

    return 0;

}


关键字:Tiny210驱动  按键中断 引用地址:Tiny210驱动之按键中断实验

上一篇:Tiny210驱动之按键poll机制
下一篇:Tiny210驱动之KEY测试

推荐阅读

随着《中国制造2025》十年行动纲领和《中国智能制造绿皮书(2017)》的发表,工业机器人这个一直不被资本所重视的行业也逐渐进入了大家的视野。 在此情况下,北极光创投发布了《中国工业机器人行业白皮书》。黄河深耕工业自动化行业十余年,对于撰文的初衷,他说,“我们的意图并不是创建一本大而全的市场研究报告,而是试图通过近十年来在整个工业机器...
  对于初学者来说,要学的知识点很多,到底从哪里下手,人们常常感到非常迷茫。大一学生先从C语言开始入门,在大一阶段由于对计算机还非常陌生,因此不可能写出一个具有完整图形界面的软件,重点以“与硬件无关的计算方法、数据结构”为基础学习C语言,至少练习编写一万行C代码,否则不会找到编程的感觉,也体会不到编程乐趣,很多人就是因为缺乏一定量...
万用表是一种多用途电子测量仪器。万用表的选型需要考虑几个重要的参数,包括精度,年准确度,测量速度等等。每项指标都与我们实际测试的需求及应用相关。DM3058/DM3058E是一款经济型5.5位数字万用表,它针对高精度、多功能、自动测量的测试需求而设计,集自动测量、多种数学变换和任意传感器测量等功能于一身,提供USB、GPIB(仅DM3058)、LAN(仅DM3058...
1. nandflash和norflash的区别我们的nandflash上面只有8条数据线,在数据线上既传输命令又传输数据,但是我们的norflash和内存接口是一样的,有地址线和数据线,norflash可以像内存一样读,但是不能像内存一样写。如果norflash也能像内存那样写的话,那就比较容易被破坏,如果想写norflash,要发出某些特定的命令,需要做一些特殊的操作才能烧写norflash...

史海拾趣

问答坊 | AI 解惑

请教各位模电高手:如何用模拟电路实现附件中的信号波形转换?

请教各位模电高手:如何用模拟电路实现附件中的信号波形转换? 我想把图中蓝色部分的原始信号经过一定的模拟电路的转换后变成红色虚线部分的波形! 谢谢了!…

查看全部问答∨

关于pic单片机的一些问题

最近用pic16f73做两个AD采集,一个开关控制是哪一路进行ad转换,然后将转换结果送入4个8段数码管进行显示。程序已经编写完成并编译通过,现要做板,在硬件电路方面有几个问题不明,再次请教: 1、MCLR端应该怎么接,或者说和仿真器相连应该怎么接 ...…

查看全部问答∨

“简简单单DSP”系列学习活动—第七期事件管理器——通用定时器

“简简单单DSP”系列学习活动—第七期事件管理器学习及使用——通用定时器 事件管理器(EV)强大的功能使它特别适用于运动控制和电机控制领域。DSP有两个相同的事件管理器EVA、EVB。每个事件管理器模块包括通用定时器CP、全比较单元、可编程的死区 ...…

查看全部问答∨

Xilinx ucf和Synplify sdc之间的对应关系

原来用Xilinx的xst做综合,约束也都是在ucf里面的。ucf里面可以用FFS指定全部的DFF,请问在Synplify里面怎么写才能表示FFS的意思呢?我想将到一个点的path全部设为multi-cycle的,想将起点设为FFS。谢谢!…

查看全部问答∨

求救:EBOOT 程序跑飞!!!

求救:EBOOT 程序跑飞!!!求救:我在调试S3C2440 ARM系统,在加载flash后,运行程序,发现在运行eboot时发现程序跑飞,串口打印消息为READ EBOOT OK,然后就不执行了,或者是重复打印以前地信息,我检查了复位信号,单板没有复位。谁遇到过类似问 ...…

查看全部问答∨

ActiveSync与PB4.2

小弟出学WinCE! 请问,要安装pb4.2和vs2003,应该安装ActiveSync的那个版本比较好?…

查看全部问答∨

新版即将来临,庆祝吧!!

早上来上网就开始发现版面有点跟昨天不一样啦,具体哪不一样说不出来,只能怪我平常不注意观察吧,…

查看全部问答∨

stm32printf求助

printf("ADC采样值为 %d\\n",ADC3ConvertedValue);     printf("ADC测量值为 %f\\n",ADC3ConvertedVoltage); 输出效果为: ADC采样值为 990 ADC测量值为 %f 不知道哪出错了求赐教 int  putchar(int ch) { ...…

查看全部问答∨

有人抄过launchpad c2000板子的JTAG部分的板子吗?

launchpad中的JTAG部分很简单,有人炒过这个板吗,是不是仅仅把那几块芯片抄过来就可以用吗? 还需要什么驱动程序?这个对那些没有支撑CCS5软件的朋友,帮助不会小,希望有人做做这方面的 尝试。…

查看全部问答∨

想收一个闲置的STM8L-DISCOVERY开发板

最近在看stm8,想收一个闲置的STM8L-DISCOVERY开发板。 …

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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