(十一) 中断驱动开发

1.中断基础知识

  中断对于学习过微机以及单片机并不陌生,下面就中断的基础知识做一下简单介绍。
  中断是指CPU 在执行程序的过程中,出现突发事件去处理,CPU 需要停止当前程序的执行,转去处理突发事件,处理完成之后再返回原程序部分。(相关信息翻阅微机原理等)

2.中断编程流程

linux中的中断在使用前,都需要申请。中断申请函数是“request_irq”,在linux目录中,使用命令”vim inlcude/linux/interrupt.h”:

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
             const char *name, void *dev)
 {
         return request_threaded_irq(irq, handler, NULL, flags, name, dev);
 }

其中函数入口参数:irq是中断号;handler是向系统登记的处理函数;flags是触发标志位;name是中断名称,可以通过注册之后可以通过”cat /proc/interrupts”查看。dev是设备。和上面中断对应的中断函数是free_irq,卸载驱动的时候需要调用。

extern void free_irq(unsigned int, void *);

  产生中断之后,会调用中断处理函数irqreturn_t,这个函数也是在头文件”include/linux/interrupt.h”:

extern irqreturn_t no_action(int cpl, void *dev_id);

  中断函数类型为irqreturn_t;参数int cpl:中断号;参数void *dev_id:设备。
  

3.程序清单

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <mach/regs-gpio.h>
#include <asm/io.h>
#include <linux/regulator/consumer.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irq.h>

#define IRQ_DEBUG
#ifdef IRQ_DEBUG
#define DPRINTK(x...) printk("IRQ_CTL DEBUG:" x)
#else
#define DPRINTK(x...)
#endif

#define DRIVER_NAME "intrp"



static irqreturn_t eint9_interrupt(int irq, void *dev_id) {

        printk("%s(%d)\n", __FUNCTION__, __LINE__);


        return IRQ_HANDLED;
}

static irqreturn_t eint10_interrupt(int irq, void *dev_id) {

        printk("%s(%d)\n", __FUNCTION__, __LINE__);

        return IRQ_HANDLED;
}

static int irq_probe(struct platform_device *pdev)
{
        int ret;
        char *banner = "intrp Initialize\n";

        printk(banner);



        ret = gpio_request(EXYNOS4_GPX1(1), "EINT9");
        if (ret) {
                printk("%s: request GPIO %d for EINT9 failed, ret = %d\n", DRIVER_NAME,
                        EXYNOS4_GPX1(1), ret);
                return ret;
        }

        s3c_gpio_cfgpin(EXYNOS4_GPX1(1), S3C_GPIO_SFN(0xF));
        s3c_gpio_setpull(EXYNOS4_GPX1(1), S3C_GPIO_PULL_UP);
        gpio_free(EXYNOS4_GPX1(1));

        ret = gpio_request(EXYNOS4_GPX1(2), "EINT10");
        if (ret) {
                printk("%s: request GPIO %d for EINT10 failed, ret = %d\n", DRIVER_NAME,
                        EXYNOS4_GPX1(2), ret);
                return ret;
        }

        s3c_gpio_cfgpin(EXYNOS4_GPX1(2), S3C_GPIO_SFN(0xF));
        s3c_gpio_setpull(EXYNOS4_GPX1(2), S3C_GPIO_PULL_UP);
        gpio_free(EXYNOS4_GPX1(2));

        ret = request_irq(IRQ_EINT(9), eint9_interrupt,
                        IRQ_TYPE_EDGE_FALLING /*IRQF_TRIGGER_FALLING*/, "eint9", pdev);
        if (ret < 0) {
                printk("Request IRQ %d failed, %d\n", IRQ_EINT(9), ret);
                goto exit;
        }

        ret = request_irq(IRQ_EINT(10), eint10_interrupt,
                        IRQ_TYPE_EDGE_FALLING /*IRQF_TRIGGER_FALLING*/, "eint10", pdev);
        if (ret < 0) {
                printk("Request IRQ %d failed, %d\n", IRQ_EINT(10), ret);
                goto exit;
        }

        return 0;

exit:
        return ret;
}

static int irq_remove (struct platform_device *pdev)
{
        free_irq(IRQ_EINT(9),pdev);
        free_irq(IRQ_EINT(10),pdev);

        return 0;
}

static int irq_suspend (struct platform_device *pdev, pm_message_t state)
{
        DPRINTK("irq suspend:power off!\n");
        return 0;
}

static int irq_resume (struct platform_device *pdev)
{
        DPRINTK("irq resume:power on!\n");
        return 0;
}

static struct platform_driver irq_driver = {
        .probe = irq_probe,
        .remove = irq_remove,
        .suspend = irq_suspend,
        .resume = irq_resume,
        .driver = {
                .name = DRIVER_NAME,
                .owner = THIS_MODULE,
        },
};

static void __exit intrp_exit(void)
{
        platform_driver_unregister(&irq_driver);
}


static int 
    __init intrp_init(void)
{
        return platform_driver_register(&irq_driver);
}

module_init(intrp_init);
module_exit(intrp_exit);

MODULE_LICENSE("Dual BSD/GPL");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值