这是以前的浅析 :
http://blog.csdn.net/leesagacious/article/details/50500096
http://blog.csdn.net/leesagacious/article/details/50491819
http://blog.csdn.net/leesagacious/article/details/78679903

注册中断

int request_threaded_irq(unsigned int irq, irq_handler_t handler,irq_handler_t thread_fn, unsigned long irqflags,const char *devname, void *dev_id)
{/*函数中一上来就声明的结构体,其地位都是非常重要的,作者一上来就想到、就要声明它,大都是该体系中的核心数据结构,如下的两个结构体蕴含丰富,用到了在说吧,*/struct irqaction *action;struct irq_desc *desc;int retval;/*绝对不推荐使用共享中断,1 : SOC支持的中断源数量很多,如 : 256 - 32 = 224个 如果还不够你用, 那你可以选择级联的中断控制器的SOC了2 : 遍历共享中断处理函数形成的irqaction链表,执行每一个ISR查看各自的状态寄存器看是否是自己发生了中断,清中断(163 sts中断在读取该状态寄存器的时候,就被清理了,164 mo中断一定要手动清理(真是一个辣鸡!),否则中断风暴要来了参见上图)这延迟了中断处理的时间了吧,与"上半部分执行的越快越好"的理念是违背的为什么 “上半部分执行的越快越好”,这涉及到了上、下半部分诞生的原因了,下面说dev_id 是ISR向被中断的进程开了一扇窗,可传一个值,暴力的Interrupt也有温柔的一面,哈哈!    请不要再联想dev_id与共享中断的事情了,说什么free_irq()释放时唯一性的那些东西,因为不推荐共享中断,加上这个do....while() 是为了处理共享中断情况的,大多数情况下,只会执行一次,因为只有共享中断,链表上才会有多个irqaction,否则只有一个 请移步: http://blog.csdn.net/leesagacious/article/details/51884483do {res = action->handler(irq, action->dev_id);  你写的ISR被调用.....action = action->next;  下一个} while (action);*/if ((irqflags & IRQF_SHARED) && !dev_id)return -EINVAL;/*从Radix Tree中 找到中断描述符 struct irq_desc上面声明的,下面肯定会有对应的响应的,念念不忘,必有回响,哈哈!可能会说,不是从数组中根据软件中断号irq对应的数组下标来找到的吗,以前的kernel确实是用数组来管理的,这又涉及到初始化的部分了,还是下面在说,关于是 "描述符"的东西 都绝对是核心的东西了,你可能又联想到USB的那些很多描述符了吧,那么 这里的 irq_desc 描述了哪些属性 ? 你想一下吧,它应该描述哪些东西 return radix_tree_lookup(&irq_desc_tree, irq);用基数树来管理比用数组来管理有哪些优势 ? 那个惯用的数组下标的经典手法又一次体现出来了*/desc = irq_to_desc(irq);if (!desc)return -EINVAL;/*中断描述符是一种资源,预先分配好的,这个不像 进程的ID 使用延迟重用算法 和 文件描述符fd 那样的动态分配的了,有些是不可以用的,       源码 : return !(desc->status_use_accessors & _IRQ_NOREQUEST);return desc->status_use_accessors & _IRQ_PER_CPU_DEVID;irq_desc是怎么被初始化的,下面说,这里先把这个函数流程执行完成*/if (!irq_settings_can_request(desc) || WARN_ON(irq_settings_is_per_cpu_devid(desc)))return -EINVAL;/*handler你不给,thread_fn你也不给,你让Interrupt做什么呢?如果鱼与熊掌偏偏都给你了,下面看看Interrupt是怎么做的 ?好,这里就是 该函数的核心的地方了 !*/if (!handler) {if (!thread_fn)return -EINVAL;/*return IRQ_WAKE_THREAD;就一句话,它要唤醒中断线程.那么要问了,1 : 中断线程是在什么时机被二号进程 kthreadd 产生的 ?2 : 又是再什么时机被唤醒的多说一句,内核线程大都是这个样子,一上来就睡,对应的条件出发了,再去唤醒它,就像Hub的驱动 khubd内核线程一样,hub上的port被接入了usb设备后,它就被唤醒了来枚举Port上的设备了,但是,这个内核线程来头可不一般 !*/  handler = irq_default_primary_handler;}/*分配内存空间吧,这里就是 irqaction的起点了.终点在哪 ? 当然是 free_irq()了,有分配,必有释放,哈哈!*/action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);if (!action)return -ENOMEM;/*利用传入的参数 给它赋值,然后挂入链表这里想到了signal挂入链表的情景,但是,这里的是单链表,且在执行的时候,无需查找链表节点的,而是一次全部触发(共享中断)看,上面是一大串校验,这里才开始实际的工作.*/action->handler = handler;action->thread_fn = thread_fn;action->flags = irqflags;      // 关注这个 flags这个值,做一个标记.action->name = devname;action->dev_id = dev_id;chip_bus_lock(desc);/*主角 终于要粉墨登场了!*/retval = __setup_irq(irq, desc, action);chip_bus_sync_unlock(desc);if (retval)kfree(action);
}
/**这个函数很长,做的事情很多 @irq       : 软件中断号,  @desc      : 中断源描述符     @irqaction : 中断动作描述符 ,既然是动作描述符,那么一定会有pointer指向你写的ISR.
*/
static int __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
{struct irqaction *old, **old_ptr;unsigned long flags, thread_mask = 0;int ret, nested, shared = 0;cpumask_var_t mask;
}

Interrupt 架构之美 -- Linux Kernel 实现欣赏相关推荐

  1. 论 SPI 架构(hw+sw) --- Linux kernel 实现欣赏

    /** spi的传输是可以从硬件上做优化的. 本文从软件.硬件上来分析* ok, 我们来欣赏一下.* 该函数最终调用了 spi_controller 提供的transfer_one()函数来进行数据的 ...

  2. pcie ecam --- Linux kernel 实现欣赏

  3. linux kernel中local_irq_disable()、local_irq_enable()代码解读

    在armv8-arch64架构下,控制cpu是否响应IRQ,FIQ,SERROR,DEBUG中断,是由PSTATUS(daif寄存器)控制的. 在armv8-arch32或armv7架构下,控制cpu ...

  4. Linux kernel panic 问题解决方案

    ===================================================== arm linux系统启动相关文章列表: arm linux系统启动流程 http://bl ...

  5. linux kernel的异常量表介绍(irq,fiq,swi,svc...)

    文章目录 1.linux kernel - arch64的异常向量表-(irq,fiq,svc......) 2.linux kernel - arch的异常向量表-(irq,fiq,swi..... ...

  6. linux kernel iio 架构

    linux kernel iio 架构讲解 Linux IIO(Industrial I/O)架构是Linux内核提供的一种用于支持各种类型传感器和数据采集设备的子系统,包括温度.压力.湿度.加速度. ...

  7. [architecture]-ARMV7架构下Linux Kernel的Userspace进程切换时保存和恢复哪些寄存器

    ★★★ 个人博客导读首页-点击此处 ★★★ . 文章目录 1.armv7的通用寄存器简介 2.寄存器的保存和恢复 3.Linux Kernel参考代码 1.armv7的通用寄存器简介 ARMV7处理器 ...

  8. (DT系列五)Linux kernel 是怎么将 devicetree中的内容生成plateform_device【转】

    转自:https://blog.csdn.net/lichengtongxiazai/article/details/38942033 Linux kernel 是怎么将 devicetree中的内容 ...

  9. Linux Kernel 5.14 arm64异常向量表解读-中断处理解读

    ★★★ 个人博客导读首页-点击此处 ★★★ . 说明: 在默认情况下,本文讲述的都是ARMV8-aarch64架构,linux kernel 5.14 文章目录 1.armv8-aarch64的异常向 ...

最新文章

  1. docker打包镜像出现python安装包超时的现象
  2. Python运行异常 Original error was: DLL load failed:
  3. Spring入门图解(体系结构-IOC-DI-AOP)
  4. 物联网智能网关应用系统的一般设计方法
  5. SQL server 表copy 到别一张表
  6. jquery --- DOM操作、表单元素的初始化
  7. 从基于Maven的Web应用程序获取版本字符串
  8. 手游极品飞车无限狂飙链接服务器失败,极品飞车无极限无法联网是什么原因 联网失败原因分析及解决方法...
  9. 2008年12月31日,博客园开博
  10. 记一次海外大型SLG游戏服务器进程被OOM的修复经历
  11. 智能物流给力零售业跨越式发展
  12. c 语言 循环判断语句,C值循环语句(七)
  13. 开源GIS(二)——openlayers加载Arcgis和geoserver在线离线切片
  14. 160809312 王仲超 第四次作业
  15. 1.爬虫系统学习--爬虫应知知识(后续还会更新)
  16. conda的environment未被激活解决方案
  17. Html5 视频播放之video标签的使用(包含注意事项,例如视频无法正常展示,只显示音频等问题)
  18. 瑞幸咖啡第四季营收24亿:同比增80.7% 门店总数超6000家
  19. android开启照相功能,Android--启动拍照功能并返回结果
  20. 一步一步学RMAN第五篇 RMAN基础知识补充 一

热门文章

  1. 音乐播放器:打开文件对话框
  2. Conditions 关键字代码的意思
  3. python刷票脚本在哪_可以挂在服务器的 12306 刷票脚本
  4. iOS开发 HealthKit初步探索
  5. MATLAB s-function 额外参数
  6. 剑鱼论坛(JianYuLunTan)开源轻论坛 v2.5.0
  7. 开发中常见的架构模式
  8. Anaconda打不开This application failed to start because it could not find or load the QT platform....
  9. 反应式编程,让程序自由的翱翔
  10. 文件上传FileUpload