linux简单按键驱动程序

一、混杂设备模型

1.1、混杂设备概念

在linux系统中,存在一类字符设备,它们拥有相同的主设备号(10),但次设备号不同,我们称这类设备为混杂设备(miscdevice)。所有的混杂设备形成一个链表,对设备访问时,内核根据次设备号查找相应的混杂设备。

1.2、设备描述

Linux中使用 struct miscdevice来描述一个混杂设备。

struct miscdevice {
    int minor;   /* 次设备号 */
    const char *name; /* 设备名 */
    const struct file_operations *fops; /* 文件操作 */
    struct list_head list;
    struct device *parent;
    struct device *this_device;
}

1.3、设备注册

linux中使用 misc_register 函数来注册一个混杂设备驱动。使用 misc

int misc_register(struct miscdevice *misc)
int misc_deregister(struct miscdevice *misc)

1.4、简单代码编写示例

#include <linux/module.h>
#include <linux/init.h>
#include <linux/miscdevice.h>

int key_open(struct inode *node, struct file *filp)
{

    return 0 ;
}

struct file_operations key_fops = {
    .open = key_open,
};

struct miscdevice key_miscdev = {
    .minor = 200 ,
    .name  = "key",
    .fops  = &key_fops,
};

static int key_init()
{
    misc_register(&key_miscdev);
}

static void key_exit()
{
    misc_deregister(&key_miscdev);
}

module_init(key_init);
module_init(key_exit);

二、linux 中断处理程序

2.1、裸机中断处理流程

事先需要通过相关寄存器的初始化,并且将中断处理程序进行注册,裸机发生中断的时候,CPU先跳到中断向量表,再根据中断源编号,跳转到中断处理函数。期间可能会有现场保护与环境恢复等问题。

2.2、linux 中断处理流程分析

irq.svc 拿到产生中断号,根据中断号找出 irq_desc 结构中 action (存放用户事先填写的中断处理函数等) 来运行。

2.3、Linux 中断处理程序设计

2.3.1、中断注册

request_irq函数用于注册中断。返回0表示成功,或者返回一个错误码。

int request_irq(unsigned int irq,void (*handler)(int,void*,struct pt_regs *),unsigned long flags,const char * devname, void *dev_id)
// 中断号
unsigned int irq
//中断处理函数
void (*handler)(int,void*,struct pt_regs *);
//与中断管理有关的各种选项
unsigned long flags
//设备名
const char * devname
//共享中断时使用
void *dev_id

在flags 参数中,可以选择一些与中断管理有关的选项,如:

IRQF_DISABLEED (SA_INTERRUPT)
//如果设置该位,表示一个“快速”中断处理程序;如果没有设置该位,那么是一个“慢速”中断处理程序。
IRQF_SHARED(SA_SHIRQ)
//该位表明该中断号是多个设备共享的。

快/慢速中断的主要区别在于:快速中断保证中断处理的原子性(不被打破),而慢速中断则不保证。换句话说,也就是“开启中断”标志位(处理器IF)在运行快速中断处理程序时是关闭的,因此在服务该中断时,不会被其他类型的中断打断;而调用慢速中断处理时,其他类型的中断仍可以得到服务。

共享中断:多个硬件共享同一个中断号。裸机中也时常有。

2.3.2 中断处理程序

中断处理程序的特别之处是在中断上下文中运行的,它的行为受到某些限制:

  1. 不能使用可能引起阻塞的函数。(死循环,信号量这类)
  2. 不能够使用可能引起调度的函数。

中断处理程序的一般流程:

  1. 检测设备是否发生中断。
  2. 清除中断产生标识。
  3. 相应的硬件操作。

2.3.3 注销中断

当设备不再需要使用中断的时候(通常在驱动卸载的时候),应当把他们注销,使用函数:

void free_irq(unsigned int irq, void *dev_id)

根据不同的 中断号和devid 进行注销中断。

2.3.4 完善上节课代码

#include <linux/module.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/fs.h>

#define GPFCON 0x56000050
irqreturn_t key_int(int irq, void *dev_id)
{
    // 1.检测是否发生了按键中断(非共享不用检查)
    // 2.清除已经发生了按键中断(CPU内部寄存器,系统已经清除)
    // 3.打印按键值
    printk("key down !\n");
    return 0 ;
}

void key_hw_init()
{
    unsigned int * gpio_config;
    unsigned int short delta;
    gpio_config = ioremap(GPFCON,4);
    delta = readw(gpio_config);
    delta &= ~0b11;
    dalta |= 0b10 ;
    writew(data,gpio_config);
}
int key_open(struct inode *node, struct file *filp)
{

    return 0 ;
}

struct file_operations key_fops = {
    .open = key_open;
};

struct miscdevice key_miscdev = {
    .minor = 200 ,
    .name  = "key",
    .fops  = &key_fops,
};

static int key_init()
{
    misc_register(&key_miscdev);
    //注册中断处理程序
    request_irq(IRQ_EINT0,key_int, IRQF_TRIGGER_FALLING, "key" , 0 );
    //按键初始化
    key_hw_init();
    return 0 ;
}

static void key_exit()
{
    misc_deregister(&key_miscdev);
    //卸载中断处理程序
    free_irq(irqno,0);
}

module_init(key_init);
module_init(key_exit);

三、编写相关makefile

obj-m := key.o
KDIR:=/home/driver/key_2440

all:
    make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
clean:
    rm -rf *.ko *.o

注意:相关代码来自国嵌。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容