您的位置:首页 > 其它

[国嵌攻略][120][按键驱动硬件操作实现]

2016-03-08 17:16 387 查看
中断类型对应中断号

1.在内核代码中找到irqs.h(.../s3c2410.h)对应的中断号,Linux系统中用的中断号是中断类型编号(INTOFFSET)加上基数偏移得到的。

2.其中的宏就是中断类型所对应的中断号

#define S3C2410_CPUIRQ_OFFSET (16)

#define S3C2410_IRQ(x) ((x) + S3C2410_CPUIRQ_OFFSET)

#define IRQ_EINT0 S3C2410_IRQ(0)

说明:

S3C2410_CPUIRQ_OFFSET对应的前16是留给软中断的,硬件中断从16开始。

3.中断号用来查找irq_desc描述结构

在entry-macro.S中ldr \irqnr,[\base, #INTOFFSET]获取中断类型编号,然后通过adds \irqnr, \irqnr, #IRQ_EINT0来加上偏移,得到对应的irq_desc描述结构的编号。

头文件

<linux/interrupt.h>

<linux/io.h>

<linux/fs.h>

keydev.c

/********************************************************************
*头文件
*********************************************************************/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/fs.h>

/********************************************************************
*宏定义
*********************************************************************/
#define GPGCON 0x56000060   //控制寄存器物理地址

/********************************************************************
*全局变量
*********************************************************************/
unsigned int *keyCon;   //控制寄存器指针

/********************************************************************
*中断处理
*********************************************************************/
//处理中断
irqreturn_t key_irq(int irq, void *dev_id){
printk("key down!\n");

return 0;
}

/********************************************************************
*设备方法
*********************************************************************/
//打开设备
int key_open(struct inode *node, struct file *filp){
return 0;
}

//关闭设备
int key_close(struct inode *node, struct file *filp){
return 0;
}

//设备方法
struct file_operations key_fops = {
.open      = key_open,
.release   = key_close
};

/********************************************************************
*模块安装
*********************************************************************/
struct miscdevice misdev = {
.minor = 200,        //次设备号
.name  = "keydev",   //设备名称
.fops  = &key_fops   //设备方法
};

//初始硬件
void handware_init(void){
unsigned short keyTmp;

keyCon = ioremap(GPGCON, 4);   //虚拟地址映射

keyTmp = readw(keyCon);   //获取GPGCON值
keyTmp &= ~(0x3<<0);      //GPG0[1:0]:00
keyTmp |=  (0x2<<0);      //GPG0[1:0]:EINT[8]
writew(keyTmp, keyCon);   //设置GPGCON值
}

//安装模块
static int key_init(void){
//注册混杂设备
misc_register(&misdev);

//注册中断处理
request_irq(IRQ_EINT8, key_irq, IRQF_TRIGGER_FALLING, "keyirq", 0);   //下降沿触发,IRQ_EINT8定义在irqs.h文件中

//初始硬件设备
handware_init();

return 0;
}

//卸载模块
static void key_exit(void){
//注销混杂设备
misc_deregister(&misdev);

//注销中断处理
free_irq(IRQ_EINT8, 0);
}

/********************************************************************
*模块声明
*********************************************************************/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("D");
MODULE_DESCRIPTION("");
MODULE_VERSION("v1.0");

module_init(key_init);
module_exit(key_exit);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: