Linux设备驱动之button按键驱动学习与小结

本文详细介绍了Linux设备驱动中关于button按键驱动的学习,涵盖了request_irq函数的使用、中断处理、阻塞与非阻塞方式。通过分析驱动代码,解释了按键驱动的工作流程,包括中断注册、消抖处理、定时器的使用以及阻塞和非阻塞模式的选择。此外,还讨论了内核中的宏和函数,如container_of和timer。
摘要由CSDN通过智能技术生成

button按键驱动,相对于前面的LED驱动来说。增加了中断处理以及阻塞与非阻塞方式等新知识点。

先上学习的驱动代码。

内核:linux3.0

板子:fl2440

本文允许转载,但请注明出处:http://blog.csdn.net/u010944778/article/details/45113687

/*********************************************************************************
 *      Copyright:  (C) 2011 Guo Wenxue<guowenxue@gmail.com>  
 *                  All rights reserved.
 *
 *       Filename:  plat_button.c
 *    Description:  This is the common button driver runs on S3C2440
 *                 
 *        Version:  1.0.0(10/27/2011~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "10/27/2011 11:39:10 AM"
 *                 
 ********************************************************************************/
#include "s3c_driver.h"

#define DRV_AUTHOR                "Guo Wenxue <guowenxue@gmail.com>"
#define DRV_DESC                  "S3C24XX button driver"

/* Driver version*/
#define DRV_MAJOR_VER             1
#define DRV_MINOR_VER             0
#define DRV_REVER_VER             0

#define DEV_NAME                  DEV_BUTTON_NAME

//#define DEV_MAJOR               DEV_BUTTON_MAJOR
#ifndef DEV_MAJOR
#define DEV_MAJOR                 0 /* dynamic major by default */
#endif

#define BUTTON_UP                 0 /* Button status is up */
#define BUTTON_DOWN               1 /* Button status is pushed down */
#define BUTTON_UNCERTAIN          2 /* Button status uncerntain */

#define TIMER_DELAY_DOWN          (HZ/50)   /*Remove button push down dithering timer delay 20ms  */
#define TIMER_DELAY_UP            (HZ/10)   /*Remove button up dithering timer delay 100ms  */

static int debug = DISABLE;
static int dev_major = DEV_MAJOR;
static int dev_minor = 0;


/*============================ Platform Device part ===============================*/
/* Button hardware informtation structure*/
struct s3c_button_info
{
    unsigned char           num;       /*Button nubmer  按键号*/  
    char *                  name;      /*Button nubmer  按键名*/
    int                     nIRQ;      /*Button IRQ number 中断号*/
    unsigned int            setting;   /*Button IRQ Pin Setting 中断引脚配置*/
    unsigned int            gpio;      /*Button GPIO port 对应的IO引脚*/
};

/* The button plaotform device private data structure */
struct s3c_button_platform_data //按键数据结构体
{
    struct s3c_button_info *buttons; //用来访问按键硬件信息的指针
    int                     nbuttons;//按键数量
};

/* Button hardware informtation data*/ //具体的相应按键信息
static struct s3c_button_info  s3c_buttons[] = {
    [0] = {
        .num = 1,
        .name = "KEY1",
        .nIRQ = IRQ_EINT0,//中断号
        .gpio = S3C2410_GPF(0),
        .setting = S3C2410_GPF0_EINT0,//datasheet手册上对应的IO中断口
    },
    [1] = {
        .num = 2,
        .name = "KEY2",
        .nIRQ = IRQ_EINT2,
        .gpio = S3C2410_GPF(2),
        .setting = S3C2410_GPF2_EINT2,
    },
    [2] = {
        .num = 3,
        .name = "KEY3",
        .nIRQ = IRQ_EINT3,
        .gpio = S3C2410_GPF(3),
        .setting = S3C2410_GPF3_EINT3,
    },
    [3] = {
        .num = 4,
        .name = "KEY4",
        .nIRQ = IRQ_EINT4,
        .gpio = S3C2410_GPF(4),
        .setting = S3C2410_GPF4_EINT4,
    },
};

/* The button platform device private data */
static struct s3c_button_platform_data s3c_button_data = {
    .buttons = s3c_buttons,
    .nbuttons = ARRAY_SIZE(s3c_buttons),
};

struct button_device
{
    unsigned char                      *status;      /* The buttons Push down or up status */
    struct s3c_button_platform_data    *data;        /* The buttons hardware information data */

    struct timer_list                  *timers;      /* The buttons remove dithering timers */
    wait_queue_head_t                  waitq;           /* Wait queue for poll()  */
    volatile int                       ev_press;     /* Button pressed event */

    struct cdev                        cdev;           
    struct class                       *dev_class; 
} button_device;

static void platform_button_release(struct device * dev)
{
    return; 
}

static struct platform_device s3c_button_device = {
    .name    = "s3c_button",
    .id      = 1,
    .dev     = 
    {
        .platform_data = &s3c_button_data, 
        .release = platform_button_release,
    },
};

static irqreturn_t s3c_button_intterupt(int irq,void *de_id) //按键中断服务程序
{
    int i;
    int found = 0;
    struct s3c_button_platform_data *pdata = button_device.data;

    for(i=0; i<pdata->nbuttons; i++)
    {
        if(irq == pdata->buttons[i].nIRQ)//找到具体的中断号
        {
            found = 1; 
            break;
        }
    }

    if(!found) /* An ERROR interrupt  */
        return IRQ_NONE;

    /* Onl
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值