• 中断系统中的设备树__Linux对中断处理的框架及代码流程简述


    1 异常向量入口: arch\arm\kernel\entry-armv.S

        .section .vectors, "ax", %progbits
    .L__vectors_start:
        W(b)    vector_rst
        W(b)    vector_und
        W(ldr)  pc, .L__vectors_start + 0x1000
        W(b)    vector_pabt
        W(b)    vector_dabt
        W(b)    vector_addrexcptn
        W(b)    vector_irq
        W(b)    vector_fiq

    2 中断向量: vector_irq

    /*
     * Interrupt dispatcher
     */
        vector_stub irq, IRQ_MODE, 4   // 相当于 vector_irq: ..., 
                                       // 它会根据SPSR寄存器的值,
                                       // 判断被中断时CPU是处于USR状态还是SVC状态, 
                                       // 然后调用下面的__irq_usr或__irq_svc

        .long   __irq_usr               @  0  (USR_26 / USR_32)
        .long   __irq_invalid           @  1  (FIQ_26 / FIQ_32)
        .long   __irq_invalid           @  2  (IRQ_26 / IRQ_32)
        .long   __irq_svc               @  3  (SVC_26 / SVC_32)
        .long   __irq_invalid           @  4
        .long   __irq_invalid           @  5
        .long   __irq_invalid           @  6
        .long   __irq_invalid           @  7
        .long   __irq_invalid           @  8
        .long   __irq_invalid           @  9
        .long   __irq_invalid           @  a
        .long   __irq_invalid           @  b
        .long   __irq_invalid           @  c
        .long   __irq_invalid           @  d
        .long   __irq_invalid           @  e
        .long   __irq_invalid           @  f

    3 __irq_usr/__irq_svc  

    这2个函数的处理过程类似:
       保存现场
       调用 irq_handler
       恢复现场

    4 irq_handler: 将会调用C函数 handle_arch_irq

        .macro  irq_handler
    #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
        ldr r1, =handle_arch_irq  //handle_arch_irq 是个C函数
        mov r0, sp
        badr    lr, 9997f
        ldr pc, [r1]
    #else
        arch_irq_handler_default
    #endif
    9997:
        .endm

    5 handle_arch_irq的处理过程

    handle_arch_irq 里面会读取寄存器来分辨是哪个中断发生了, 然后去调用对应的中断处理函数, 我们可以看一下handle_arch_irq 这个函数是在哪里设置的,

     调用set_handle_irq这个函数来设置handle_arch_irq,

    读取寄存器获得中断信息: hwirq
       把hwirq转换为virq
       调用 irq_desc[virq].handle_irq
    对于S3C2440, s3c24xx_handle_irq 是用于处理中断的C语言入口函数,在分析内核对中断的处理流程之前先看一下下面的图。

    我们的中断控制器有32位,每一位代表一种中断,中断控制器可以向CPU发出32种中断,每一种中断的处理函数都不一样,那么在Linux内核中,我们怎么管理这32种中断以及他们的处理函数呢,最简单的方法我们创建一个数组,数组的每一项用来保存每一种中断以及他们的处理函数,内核确实也是这么做的,

     从上图中我们可以看到,irq_desc里面有一个handle_irq了,然后在action链表中还有一个handle,实际使用时,我们的handle_irq会调用action链表中我们提供的具体的处理函数handler,然后handle_irq再清中断,这样处理的好处是这个handler_irq帮我们处理了中断,然后我们提供的handler处理函数不需要清除中断只需要专注于需要处理的事情就可以了,

    从上图中我们可以看到,irq_desc里面还有一个irq_data,然后irq_data里面还有个chip,然后irq_chip里面有一堆的函数,然后这里面的 函数就是用来屏蔽中断,使能中断,清除中断的, 
       
    中断处理流程:
    假设中断结构如下:
    sub int controller ---> int controller ---> cpu

    发生中断时,
    cpu跳到"vector_irq", 保存现场, 调用C函数handle_arch_irq

    handle_arch_irq:
    a. 读 int controller, 得到hwirq
    b. 根据hwirq得到virq
    c. 调用 irq_desc[virq].handle_irq

    如果该中断没有子中断, irq_desc[virq].handle_irq的操作:
    a. 取出irq_desc[virq].action链表中的每一个handler, 执行它
    b. 使用irq_desc[virq].irq_data.chip的函数清中断

    如果该中断是由子中断产生, irq_desc[virq].handle_irq的操作:
    a. 读 sub int controller, 得到hwirq'
    b. 根据hwirq'得到virq
    c. 调用 irq_desc[virq].handle_irq

  • 相关阅读:
    yolov5系列-[2]-数据标注、参数设置、训练优化
    MAC M1大数据0-1成神篇-30 kafka-ha环境搭建
    python输出数据类型
    [解题报告] CSDN竞赛第五期
    在cmd命令中利用SQL语句创建、删除、修改和查看数据表
    excel公式怎么完全复制到另一列?
    首篇大模型压缩论文综述
    安装Redis
    01-Android平台的虚拟机是基于栈的吗?
    跨平台编译QWT、安装QWT(Windows、Linux、MacOS环境下编译与安装)
  • 原文地址:https://blog.csdn.net/u013171226/article/details/128131864