linux中断处理

姓名:郑煜烁  学号:19029100010   学院:电子工程学院

转自:https://blog.csdn.net/u012142460/article/details/79272207

【嵌牛导读】介绍linux系统中如何对突发事件进行处理

【嵌牛鼻子】中断处理

【嵌牛提问】如何进行中断处理

【嵌牛正文】

一、中断介绍

所谓中断是指CPU在执行程序的过程中,出现了某些突发事件需要紧急处理,CPU必须暂时停止当前的工作,转去执行处理突发事件,处理完毕又返回原程序被中断的位置继续执行。

在ARM多核处理器中最常用的中断控制器是GIC,支持三类中断

1、SGI:Software Generated Interrupt,软件产生的中断,用于多核的核间通信

2、PPI:Private Peripheral Interrupt,某个CPU私有外设的中断,这类外设的中断只能发给绑定的那个CPU

3、SPI:Shared Peripheral Interrupt 共享外设中断,这类外设的中断可以路由到任何一个CPU

在proc/interrupts文件可以获得中断信息。

来源 CSDN

二 、中断API

看一下常用的中断相关的API函数

1、申请中断

static inline int __must_check

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,

        const char *name, void *dev)

功能:申请中断

参数:irq:中断号,这个中断号不是硬件手册上的中断号,而是linux的中断号。

        handler:中断处理函数

        flags:标志位            #define IRQF_TRIGGER_RISING0x00000001  上升沿触发

                                          #define IRQF_TRIGGER_FALLING0x00000002  下降沿触发

                                          #define IRQF_TRIGGER_HIGH0x00000004          高电平触发

                      #define IRQF_TRIGGER_LOW 0x00000008          低电平触发    IRQF_SHARED                                                  共享标志,表示该中断可以被多个设备共享

      name:中断的名称

      dev:要传递给中断服务程序的私有数据,一般设置为这个设备的结构体或者为NULL

返回值:成功返回0,返回-EINVAL表示中断号无效或处理函数指针为NULL,返回-EBUSY表示中断已经占用且不能共享。

2、释放中断

void free_irq(unsigned int irq, void *dev_id)

参数与申请中断中的参数一样。

三、中断上下部机制

        中断会打断内核进程中的正常调度,系统对更高吞吐率的追求势必要求中断服务程序尽量短小精悍。但实际上,很多中断程序需要处理很多事务,可能进行大量的耗时操作。

      Linux为了解决这个问题,找出一个平衡点,将中断程序分成了两个部分:顶半部和底半部。顶半部处理紧急事务,底半部处理耗时操作。顶半部和底半部最大不同在于,底半部是可以被其他中断打断的,这样就不会耽误其他中断的进行了。

      顶半部处理紧急事务,一些中断必须的事务在此处理,比如读中断状态,清中断标志等等,这些都是必要但很简单的工作。在底半部主要处理一些不太紧要的工作,必要数据的处理等等。

      尽管上述机制能够改善系统的响应能力,但不能僵化的把所有中断驱动分成两个半部,如果本身处理情况就比较简单,则是完全可以在顶半部来全部完成的。

我们使用tasklet和工作队列来完成顶半部底半部机制

1、tasklet

taskelet实际上是linux中软中断的一种,Linux提供了一系列宏和函数来完成tasklet

DECLARE_TASKLET(name, func, data)

功能:定义一个tasklet对象

参数:name:名称

          func:底半部函数

          data:传递给底半部函数的参数

DECLARE_TASKLET_DISABLED(name, func, data)

功能和上面类似,但还需要调用task_enable使能一下。

static inline void tasklet_schedule(struct tasklet_struct *tasklet)

功能:将指定的tasklet对象添加的加入到tasklet列表中,要执行底半部函数需要先执行这个函数,一般在顶半部函数执行。

2、工作队列

工作队列的方法也可以实现顶半部底半部机制

struct work_struct {

atomic_long_t data;      //传递给工作函数的参数

struct list_head entry;

work_func_t func;        //工作函数,可以理解就是底半部函数。

#ifdef CONFIG_LOCKDEP

struct lockdep_map lockdep_map;

#endif

};

工作队列对象结构体。使用工作队列需要首先定义一个工作队列对象

  INIT_WORK(_work, _func)

功能:将工作队列与底半部函数绑定。

参数: _work,定义的工作队列

          _func,定义的底半部函数,可以简单的理解成将底半部函数赋值给定义的工作队列对象中func变量。

int schedule_work(struct work_struct *work)

功能:将工作队列节点加入到工作队列链表中,和tasklet中的tasklet_schedule函数功能类似,一般在顶半部函数中完成。

参数:work,工作队列对象

3、taskelet与工作队列的异同

        两者有什么区别呢?taskelet是在中断上下文来完成的,而中断中是不能进行进程调度的,所以在tasklet的顶半部和底半部都能进行进程的调度。工作队列是处于进程上下文中的,所以底半部是工作队列时,是可以进程进程调度的

        在使用时,步骤基本一致,绑定工作队列/tasklet和底半部函数,然后在顶半部中执行schedule函数,执行底半部函数。

实例,在迅为4412开发板上,实现按键中断

原理图如下

来源 CSDN

我们只拿一个来做例子,UART_RING,看他对应的GPIO口

来源 CSDN

它对应的是GPIOX1_1

得到中断号有一个API  gpio_to_irq(gpio),三星定义了GPIOX1_1的gpio值为EXYNOS4_GPX1(1),这样就可以得到中断号了。

#include <linux/init.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/interrupt.h>

#include <linux/errno.h>

#include <linux/gpio.h>

#include <mach/gpio-exynos4.h>

#define TASKLET;

int irq1;

#ifdef WORK_QUEUE

struct work_struct  key_wq;  //定义一个工作队列对象

#endif

void key_tasklet_func(unsigned long data);

#ifdef TASKLET

DECLARE_TASKLET(key_tasklet,key_tasklet_func,0); //绑定tasklet对象和函数

#endif

void key_tasklet_func(unsigned long data)

{

printk(KERN_INFO"key_tasklet_func enter...\n");

}

irqreturn_t key_handler(int irq, void *date)

{

printk(KERN_INFO"key1 enter...\n");

#ifdef TASKLET

tasklet_schedule(&key_tasklet);   //执行tasklet底半部

#endif

#ifdef WORK_QUEUE

schedule_work(&key_wq);            //执行工作队列底半部

#endif

return IRQ_HANDLED;

}

static int __init demo_key_init(void)

{

int ret = 0;

irq1 = gpio_to_irq(EXYNOS4_GPX1(1));

ret = request_irq(irq1,key_handler,IRQF_TRIGGER_FALLING,"KEY222",NULL);

if(ret < 0){

printk(KERN_INFO"request_irq fail...%s,%d,ret:%d\n",__func__,__LINE__,ret);

return -EINVAL;

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

#ifdef WORK_QUEUE

INIT_WORK(&key_wq,key_tasklet_func);  //初始化一个工作队列

#endif

return 0;

}

static void  __exit demo_key_exit(void)

{

free_irq(irq1,NULL);

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

}

module_init(demo_key_init);

module_exit(demo_key_exit);

MODULE_LICENSE("GPL");

————————————————

版权声明:本文为CSDN博主「念念有余」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/u012142460/article/details/79272207

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

推荐阅读更多精彩内容