Linux中断子系统-通用框架处理

背景

  1. Kernel版本:4.14

  2. ARM64处理器,Contex-A53,双核

  3. 使用工具:Source Insight 3.5, Visio

1. 概述

《Linux中断子系统(一)-中断控制器及驱动分析》讲到了底层硬件GIC驱动,以及Arch-Specific的中断代码,本文将研究下通用的中断处理的过程,属于硬件无关层。当然,我还是建议你看一下上篇文章。

这篇文章会解答两个问题:

  1. 用户是怎么使用中断的(中断注册)?

  2. 外设触发中断信号时,最终是怎么调用到中断handler的(中断处理)?

2. 数据结构分析

先来看一下总的数据结构,核心是围绕着struct irq_desc来展开:


  • Linux内核的中断处理,围绕着中断描述符结构struct irq_desc展开,内核提供了两种中断描述符组织形式:

  1. 打开CONFIG_SPARSE_IRQ宏(中断编号不连续),中断描述符以radix-tree来组织,用户在初始化时进行动态分配,然后再插入radix-tree中;

  2. 关闭CONFIG_SPARSE_IRQ宏(中断编号连续),中断描述符以数组的形式组织,并且已经分配好;

  3. 不管哪种形式,都可以通过linux irq号来找到对应的中断描述符;

  • 图的左侧灰色部分,主要在中断控制器驱动中进行初始化设置,包括各个结构中函数指针的指向等,其中struct irq_chip用于对中断控制器的硬件操作,struct irq_domain与中断控制器对应,完成的工作是硬件中断号到Linux irq的映射;

  • 图的上侧灰色部分,中断描述符的创建(这里指CONFIG_SPARSE_IRQ),主要在获取设备中断信息的过程中完成的,从而让设备树中的中断能与具体的中断描述符irq_desc匹配;

  • 图中剩余部分,在设备申请注册中断的过程中进行设置,比如struct irqactionhandler的设置,这个用于指向我们设备驱动程序中的中断处理函数了;

  • 中断的处理主要有以下几个功能模块:

    1. 硬件中断号到Linux irq中断号的映射,并创建好irq_desc中断描述符;

    2. 中断注册时,先获取设备的中断号,根据中断号找到对应的irq_desc,并将设备的中断处理函数添加到irq_desc中;

    3. 设备触发中断信号时,根据硬件中断号得到Linux irq中断号,找到对应的irq_desc,最终调用到设备的中断处理函数;

    上述的描述比较简单,更详细的过程,往下看吧。

    3. 流程分析

    3.1 中断注册

    这一次,让我们以问题的方式来展开:先来让我们回答第一个问题:用户是怎么使用中断的?

    1. 熟悉设备驱动的同学应该都清楚,经常会在驱动程序中调用request_irq()接口或者request_threaded_irq()接口来注册设备的中断处理函数;

    2. request_irq()/request_threaded_irq接口中,都需要用到irq,也就是中断号,那么这个中断号是从哪里来的呢?它是Linux irq,它又是如何映射到具体的硬件设备的中断号的呢?

    先来看第二个问题:设备硬件中断号到Linux irq中断号的映射


    • 硬件设备的中断信息都在设备树device tree中进行了描述,在系统启动过程中,这些信息都已经加载到内存中并得到了解析;

    • 驱动中通常会使用platform_get_irqirq_of_parse_and_map接口,去根据设备树的信息去创建映射关系(硬件中断号到linux irq中断号映射);

    • 《Linux中断子系统(一)-中断控制器及驱动分析》提到过struct irq_domain用于完成映射工作,因此在irq_create_fwspec_mapping接口中,会先去找到匹配的irq domain,再去回调该irq domain中的函数集,通常irq domain都是在中断控制器驱动中初始化的,以ARM GICv2为例,最终回调到gic_irq_domain_hierarchy_ops中的函数;

    • 如果已经创建好了映射,那么可以直接进行返回linux irq中断号了,否则的话需要irq_domain_alloc_irqs来创建映射关系;

    • irq_domain_alloc_irqs完成两个工作:

    1. 针对linux irq中断号创建一个irq_desc中断描述符;

    2. 调用domain->ops->alloc函数来完成映射,在ARM GICv2驱动中对应gic_irq_domain_alloc函数,这个函数很关键,所以下文介绍一下;

    gic_irq_domain_alloc函数如下:


    • gic_irq_domain_translate:负责解析出设备树中描述的中断号和中断触发类型(边缘触发、电平触发等);

    • gic_irq_domain_map:将硬件中断号和linux中断号绑定到一个结构中,也就完成了映射,此外还绑定了irq_desc结构中的其他字段,最重要的是设置了irq_desc->handle_irq的函数指针,这个最终是中断响应时往上执行的入口,这个是关键,下文讲述中断处理过程时还会提到;

    • 根据硬件中断号的范围设置irq_desc->handle_irq的指针,共享中断入口为handle_fasteoi_irq,私有中断入口为handle_percpu_devid_irq

    上述函数执行完成后,完成了两大工作:

    1. 硬件中断号与Linux中断号完成映射,并为Linux中断号创建了irq_desc中断描述符;

    2. 数据结构的绑定及初始化,关键的地方是设置了中断处理往上执行的入口;

    再看第一个问题:中断是怎么来注册的?

    设备驱动中,获取到了irq中断号后,通常就会采用request_irq/request_threaded_irq来注册中断,其中request_irq用于注册普通处理的中断,request_threaded_irq用于注册线程化处理的中断;

    在讲具体的注册流程前,先看一下主要的中断标志位:

    #define IRQF_SHARED		0x00000080              //多个设备共享一个中断号,需要外设硬件支持
    #define IRQF_PROBE_SHARED	0x00000100              //中断处理程序允许sharing mismatch发生
    #define __IRQF_TIMER		0x00000200               //时钟中断
    #define IRQF_PERCPU		0x00000400               //属于特定CPU的中断
    #define IRQF_NOBALANCING	0x00000800               //禁止在CPU之间进行中断均衡处理
    #define IRQF_IRQPOLL		0x00001000              //中断被用作轮训
    #define IRQF_ONESHOT		0x00002000              //一次性触发的中断,不能嵌套,1)在硬件中断处理完成后才能打开中断;2)在中断线程化中保持关闭状态,直到该中断源上的所有thread_fn函数都执行完
    #define IRQF_NO_SUSPEND		0x00004000      //系统休眠唤醒操作中,不关闭该中断
    #define IRQF_FORCE_RESUME	0x00008000              //系统唤醒过程中必须强制打开该中断
    #define IRQF_NO_THREAD		0x00010000      //禁止中断线程化
    #define IRQF_EARLY_RESUME	0x00020000      //系统唤醒过程中在syscore阶段resume,而不用等到设备resume阶段
    #define IRQF_COND_SUSPEND	0x00040000      //与NO_SUSPEND的用户共享中断时,执行本设备的中断处理函数
    


    • request_irq也是调用request_threaded_irq,只是在传参的时候,线程处理函数thread_fn函数设置成NULL;

    • 由于在硬件中断号和Linux中断号完成映射后,irq_desc已经创建好,可以通过irq_to_desc接口去获取对应的irq_desc

    • 创建irqaction,并初始化该结构体中的各个字段,其中包括传入的中断处理函数赋值给对应的字段;

    • __setup_irq用于完成中断的相关设置,包括中断线程化的处理:

    1. 中断线程化用于减少系统关中断的时间,增强系统的实时性;

    2. ARM64默认开启了CONFIG_IRQ_FORCED_THREADING,引导参数传入threadirqs时,则除了IRQF_NO_THREAD外的中断,其他的都将强制线程化处理;

    3. 中断线程化会为每个中断都创建一个内核线程,如果中断进行共享,对应irqaction将连接成链表,每个irqaction都有thread_mask位图字段,当所有共享中断都处理完成后才能unmask中断,解除中断屏蔽;

    3.2 中断处理

    当完成中断的注册后,所有结构的组织关系都已经建立好,剩下的工作就是当信号来临时,进行中断的处理工作。

    来回顾一下《Linux中断子系统(一)-中断控制器及驱动分析》中的Arch-specific处理流程:


    • 中断收到之后,首先会跳转到异常向量表的入口处,进而逐级进行回调处理,最终调用到generic_handle_irq来进行中断处理。

    generic_handle_irq处理如下图:


    • generic_handle_irq函数最终会调用到desc->handle_irq(),这个也就是对应到上文中在建立映射关系的过程中,调用irq_domain_set_info函数,设置好了函数指针,也就是handle_fasteoi_irqhandle_percpu_devid_irq

    • handle_fasteoi_irq:处理共享中断,并且遍历irqaction链表,逐个调用action->handler()函数,这个函数正是设备驱动程序调用request_irq/request_threaded_irq接口注册的中断处理函数,此外如果中断线程化处理的话,还会调用__irq_wake_thread()唤醒内核线程;

    • handle_percpu_devid_irq:处理per-CPU中断处理,在这个过程中会分别调用中断控制器的处理函数进行硬件操作,该函数调用action->handler()来进行中断处理;

    来看看中断线程化处理后的唤醒流程吧__handle_irq_event_percpu->__irq_wake_thread


    • __handle_irq_event_percpu->__irq_wake_thread将唤醒irq_thread中断内核线程;

    • irq_thread内核线程,将根据是否为强制中断线程化对函数指针handler_fn进行初始化,以便后续进行调用;

    • irq_thread内核线程将while(!irq_wait_for_interrupt)循环进行中断的处理,当满足条件时,执行handler_fn,在该函数中最终调用action->thread_fn,也就是完成了中断的处理;

    • irq_wait_for_interrupt函数,将会判断中断线程的唤醒条件,如果满足了,则将当前任务设置成TASK_RUNNING状态,并返回0,这样就能执行中断的处理,否则就调用schedule()进行调度,让出CPU,并将任务设置成TASK_INTERRUPTIBLE可中断睡眠状态;

    3.3 总结

    中断的处理,总体来说可以分为两部分来看:

    1. 从上到下:围绕irq_desc中断描述符建立好连接关系,这个过程就包括:中断源信息的解析(设备树),硬件中断号到Linux中断号的映射关系、irq_desc结构的分配及初始化(内部各个结构的组织关系)、中断的注册(填充irq_desc结构,包括handler处理函数)等,总而言之,就是完成静态关系创建,为中断处理做好准备;

    2. 从下到上,当外设触发中断信号时,中断控制器接收到信号并发送到处理器,此时处理器进行异常模式切换,并逐步从处理器架构相关代码逐级回调。如果涉及到中断线程化,则还需要进行中断内核线程的唤醒操作,最终完成中断处理函数的执行。

       

       推荐阅读:

        专辑|Linux文章汇总

        专辑|程序人生

        专辑|C语言

    嵌入式Linux

    微信扫描二维码,关注我的公众号 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467276.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

接口测试工具-fiddler的运用

本篇主要介绍一下fiddler的基本运用,包括查看接口请求方式,状态响应码,如何进行接口测试等 一.Fiddler的优点 独立的可以直接抓http请求小巧、功能完善快捷、启动就行代理方便二.什么是Fiddler Fiddler是一个http协议调…

微电子科学与工程要学计算机吗,微电子科学与工程专业就业前景如何 有前途吗...

微电子科学与工程专业就业前景如何?有前途吗?下面小编为大家整理了相关内容,以供参考,一起来看看吧!微电子科学与工程专业就业前景微电子科学与工程专业近年来也逐渐热火起来了,竞争力也很大。微电子专业一…

利用Excel VBA畫出所有圖標

有時候﹐常感覺﹐恰當的使用Excel的VBA做些開發﹐常常收到事半功倍的效果的。從Birdshome的博客中看到這篇貼深有感觸﹐當然﹐自己以前也是使用過一段時間的VBA開發的﹐直到使用.net之后就沒有再搞那玩意兒了﹐唉....﹐感嘆一下先。順便把那里jinta2001的Excel文檔轉上來。呵呵…

我的丈母娘

2020年9月17日12点46分,刚进入新居我终于还是要写这篇文章了,想了很久,我觉得写一篇文章来记录下我的丈母娘。前段时间,小云妈妈骑车不小心把鼻子给摔破了,很严重,二哥马上回家带老人到医院检查并做了手术。…

学法语,加油!

我家小猪又折腾法语了.在大学的时候她就不学无术,当我专心治学的时候,她总是手捧闲书作认真状;正儿八经上课时间,大部分还是可以认真度过,但是逢到计算机课,她就全傻了,是的,她是计算…

华南理工大学广州学院计算机二级,华南理工大学广州学院学子在第三届“泰迪杯”数据分析职业技能大赛中荣获佳绩...

12月19日,第三届泰迪杯数据分析职业技能大赛落下帷幕并公示了获奖名单。华南理工大学广州学院获得国家二等奖一项,国家三等奖两项的好成绩,这是我华南理工大学广州学院首次有组织地参与该赛事。本次竞赛由计算机工程学院组织,同时…

OpenGL程序运行提示“glut32.dll丢失问题”

调试环境: Win10 (x64) ,VS2015 解决方案 (1)将gult32.dll,glut.dll复制到C:\WINDOWS\SysWOW64 (如果是32位操作系统,则是WINDOWS\system32这个文件下) (2)将GL文件夹的路径添加到vs…

华为突然宣布,对物联网下手了!

5G时代到来物联网技术的应用离我们越来越近智慧交通、智能家庭、智慧园区越来越多的融入到我们的生活当中但国内物联网人才短缺每年人才缺口达百万之多作为5G技术的先锋华为云特别推出【IoT物联网开发全栈成长计划】三大阶段,从学习到实践全流程提升物联网开发技能还…

Linux内核品读 /基础组件/ 模块机制快速入门

哈喽,我是杰克吴,继续记录我的学习心得。一、关于兴趣的几点思考1. 享受不是兴趣,愿意付出才是:兴趣很容易跟享受混淆。享受是被动的,无需付出;而兴趣则要求你甘愿为了这件事情付出努力。2.任何事情&#x…

台式计算机时间不准,每天开机电脑时间都不正确怎么办?试试这个办法!

原标题:每天开机电脑时间都不正确怎么办?试试这个办法!上面电脑运用时间长了,经常会出现开机提示时间不正确,在系统上设置好时间后,第二天开机电脑时间还不正确,是什么原因呢?无论是…

Ajax与WebGIS

现在越来越多的桌面应用转向Web平台,而人们也一直希望日益丰富的Web应用能够做到简单易用、高效并具有良好的交互性能。随着Google推出Google Maps、GMail等一系列服务让人们看到了曙光,感受到一种全新的Web使用体验。这种体验的显著特点就是无需下载、安…

剑指offer(20)包含min函数的栈

题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。 题目分析 首先一开始我们分析得到最小值肯定要比较嘛,和栈里面的数据一一比较,但是栈这种数据结构,你又只能和栈顶弹出来的数据进行比较&#xff0…

杀除橙色八月的病毒

特征:在c 目录下发现了一个这样的文件0A5021.exe,而且在启动里也存在。即使你在安全模式下,他还是自动运行起来的,而且这个程序把你的杀毒软件禁止掉,不能运行杀毒软件。解决方案:删除一下文件: C:\Program…

c语言从1打印到100再打印到1该如何编写?

我觉得这是一个送分题,奈何知乎人才太多了,给出了各种古怪的写法,如果是做项目的话,我比骄建议一些正常的写法,就是大家都能看得懂的,不要搞什么花里胡哨,不过你要是交流的话,既然是…

南京大学2021计算机考研复试线是多少,34所自划线院校2021考研复试分数线-2021南京大学考研分数线已公布...

2021南京大学考研复试分数线已公布!点击查看>>34所自划线院校2021考研复试分数线。2021考研分数线变化趋势会是怎样的呢?战过初试•赢过复试>>中公考研陪你决战考研复试场​南京大学2021年硕士研究生复试基本分数线一、学术学位报考学科门类…

有人知道 I3C 吗?

我们知道I2C、SPI、UART、但是应该很少有人知道I3C,不过它确实是存在的。在完善的I2C接口标准之后,I3C即将进入嵌入式市场。I3C标准由MIPI联盟开发,现已扩展到更广泛的市场,该标准将I2C,UART和SPI组合为10Mbit / s&…

清华北大计算机考研报录比,2020年考研,清华北大报考人数对比,占考研总人数14%...

原标题:2020年考研,清华北大报考人数对比,占考研总人数14%2020年考研341万人同进考场,考研报名人数超过300万人,创造历史新高。因此2020年考研被公认为考研难度最大的一年。341万考研人,有多少人报考清华北…

洛谷树剖模板题 P3384 | 树链剖分

原题链接 对于以u为根的子树,后代节点的dfn显然比他的dfn大,我们可以记录一下回溯到u的dfn,显然这两个dfn构成了一个连续区间,代表u及u的子树 剩下的就和树剖一样了 1 #include<cstdio>2 #include<algorithm>3 #include<cstring>4 #define N 1000105 typedef…

我同学

周六在朋友圈提到的&#xff0c;我有一个在三星工作、从事camera方向研究的同学&#xff0c;他在去三星之前已经做了很多年camera了&#xff0c;之前在知识星球也给大家推荐了他的技术公众号&#xff0c;对喜欢或者从事camera研究的会非常有帮助&#xff0c;建议大家关注一下。…

学教育成空中楼阁 巨额学费背后却是失业风险

央视国际 [url]www.cctv.com[/url]  2006年11月13日 09:22 来源&#xff1a; 大学的病&#xff0c;其病在学。现在的大学&#xff0c;大家都很忙&#xff0c;但大学要教什么&#xff0c;怎么教&#xff0c;其实没人操心。这样教出的学生&#xff0c;不会做人&#xff0c;也不…