ARM架构与编程(六)后续(09_GIC介绍与编程10_实战_GPIO中断编程(IMX6ULL))

09_GIC介绍与编程

GIC介绍与编程

参考资料:ARM® Generic Interrupt Controller Architecture Specification Architecture version 2.0(IHI0048B_b_gic_architecture_specification_v2).pdf

1.1 GIC介绍

ARM体系结构定义了通用中断控制器(GIC),该控制器包括一组用于管理单核或多核系统中的中断的硬件资源。GIC提供了内存映射寄存器,可用于管理中断源和行为,以及(在多核系统中)用于将中断路由到各个CPU核。它使软件能够屏蔽,启用和禁用来自各个中断源的中断,以(在硬件中)对各个中断源进行优先级排序和生成软件触发中断。它还提供对TrustZone安全性扩展的支持。GIC接受系统级别中断的产生,并可以发信号通知给它所连接的每个内核,从而有可能导致IRQ或FIQ异常发生。

你可以把 ​​ARM的通用中断控制器(GIC)​​ 想象成一个 ​​公司的全能调度中心​​,专门负责接收各种设备(比如按键、传感器、网卡等)的“紧急呼叫”(中断请求),然后根据优先级、安全等级、目标处理部门(CPU核心)等规则,快速分派任务。以下是通俗解释:


一、​​GIC的核心功能​
  1. ​统一接听所有“电话”​

    • 公司有很多部门(外设),每个部门有事都会打“电话”给调度中心(GIC)。比如按键按下、传感器报警、网卡收到数据,都会发送中断信号。GIC统一接收这些请求,避免设备直接“轰炸”老板(CPU核心)导致混乱。
  2. ​智能分派任务​

    • ​优先级排序​​:火灾警报(高优先级)比打印机缺纸(低优先级)更紧急,GIC会优先处理。
    • ​路由规则​​:有些任务只能给特定部门处理(比如财务问题只能转给财务部),对应多核系统中将中断路由到指定CPU核心。
  3. ​安全隔离​

    • 调度中心有“保密部门”(TrustZone安全扩展),机密任务(如指纹识别)只能交给安全部门处理,普通员工(非安全模式)无权接触。

二、​​GIC的“分派流程”​
  1. ​接收请求​

    • 外设触发中断 → GIC检测到信号(如按键电平变化)→ 记录在“待办清单”(挂起寄存器)中。
  2. ​分类处理​

    • ​普通电话(IRQ)​​:常规任务,比如处理传感器数据。
    • ​紧急电话(FIQ)​​:最高优先级任务,比如硬件故障,必须立刻处理。
  3. ​分派给CPU核心​

    • 调度中心(Distributor)根据预设规则,将任务分给空闲的“员工”(CPU核心)。例如:
      • 核心A处理网卡数据(高负载任务)
      • 核心B处理按键输入(低负载任务)。
  4. ​任务完成确认​

    • CPU处理完中断后,必须通知GIC“任务已完成”(清除中断标志),否则GIC会反复提醒。

三、​​GIC支持的“电话类型”​
​中断类型​​通俗比喻​​技术作用​
​SGI​​内部对讲机​​:员工之间沟通(如核A通知核B处理任务)软件生成的中断,用于多核协作(如任务分配、数据同步)。
​PPI​​部门专线​​:财务部的报销专线(仅财务部能接听)每个CPU核心独有的中断(如本地定时器),不与其他核共享。
​SPI​​公共热线​​:客户服务电话(如400热线)共享外设中断(如网卡、硬盘),可路由到任意CPU核心处理。
​LPI​​VIP直通专线​​:重要客户直接联系高层(如PCIe设备中断)基于消息的中断,配置灵活(GICv3及以上支持),适合高性能场景。

四、​​为什么需要GIC?​
  1. ​减轻CPU负担​

    • 没有GIC时,所有设备直接找CPU,CPU会疲于应付。GIC像秘书一样先过滤、排序请求,让CPU专注处理核心任务。
  2. ​支持多核协作​

    • 调度中心可动态分配任务给多个核心(比如让大核处理复杂计算,小核处理实时任务),提升系统效率。
  3. ​安全与实时性​

    • 安全中断(如支付验证)与非安全中断(如游戏画面渲染)隔离,防止敏感操作被干扰。

一句话总结

​“GIC就像公司的全能调度员:统一接收所有设备的‘紧急呼叫’,按优先级和安全规则精准分派给CPU核心,既保证火警优先处理,又能让多核团队高效协作!”​
通过这套机制,ARM系统可以同时处理数百个中断请求,兼顾性能、实时性和安全性,是手机、服务器、物联网设备的“中枢神经”。

从软件角度来看,GIC具有两个主要功能模块,简单画图如下:

这张图展示了 ​​ARM通用中断控制器(GIC)​​ 的工作原理,可以类比为 ​​一家公司的电话总机系统​​,专门负责接听各部门的“紧急电话”(中断请求),并按规则转接给对应的负责人(CPU核心)。以下是分步解析:


一、​​核心角色与流程​
  1. ​来电方(各种中断)​

    • ​比喻​​:公司各部门(外设)遇到紧急事件时会拨打电话。例如:
      • 键盘部门:按键被按下(需要CPU处理输入)。
      • 网络部门:网卡收到数据包(需要CPU转发)。
      • 传感器部门:温度超标(需要CPU触发警报)。
  2. ​总机接线员(Distributor)​

    • ​核心作用​​:接收所有来电,分类、排序、分配。
    • ​具体工作​​:
      • ​分类​​:区分普通电话(IRQ)和加密电话(TrustZone安全中断)。
      • ​优先级排序​​:火灾报警电话(高优先级)比打印机缺纸电话(低优先级)优先处理。
      • ​安全检查​​:加密电话只能转接给保密部门(安全模式CPU核)。
      • ​分配规则​​:根据预设策略,将电话转给空闲的部门负责人(CPU核心)。
  3. ​部门对接员(CPU Interface 0~N)​

    • ​比喻​​:每个部门(CPU核心)有专属对接员,负责接收总机转来的电话,并确认处理结果。
    • ​工作流程​​:
      • 接收总机分配的任务(中断)。
      • 提醒负责人(CPU核心)处理任务(触发IRQ/FIQ异常)。
      • 任务完成后,通知总机“电话已接听”(清除中断标志)。
  4. ​部门负责人(Processor 0~N)​

    • ​比喻​​:公司的各部门经理(CPU核心),专注处理分配到的任务。
    • ​分工举例​​:
      • ​Processor 0​​:处理实时任务(如电机控制)。
      • ​Processor 1​​:处理后台任务(如数据备份)。

二、​​GIC的工作流程(以按键触发中断为例)​
  1. ​来电接入​​:

    • 按键按下 → 键盘部门拨打电话(产生中断信号)→ 总机(Distributor)接听。
  2. ​总机处理​​:

    • ​分类​​:识别为普通电话(非安全中断)。
    • ​排序​​:优先级设为中等(高于温度传感器,低于硬件故障)。
    • ​分配​​:转接给当前最空闲的对接员(如CPU Interface 0)。
  3. ​对接员转接​​:

    • CPU Interface 0通知Processor 0:“有按键任务待处理”。
  4. ​负责人处理​​:

    • Processor 0暂停当前工作,执行按键处理程序(如更新屏幕显示)。
  5. ​任务确认​​:

    • Processor 0处理完成后,通知对接员 → 对接员反馈总机“任务完成”。

三、​​为什么需要GIC?​
  1. ​避免混乱​​:

    • 没有总机时,所有电话直接打给老板(CPU核心),老板会被频繁打断。
    • ​GIC的作用​​:总机先过滤、排序,只转接必要电话,让老板专注核心任务。
  2. ​多核协作​​:

    • 总机可动态分配任务给多个老板(多核CPU),提升效率(如大核处理复杂任务,小核处理简单任务)。
  3. ​安全隔离​​:

    • 保密电话(如指纹识别)只能转给保密部门(安全模式CPU核),防止信息泄露。

一句话总结

​“GIC像公司的电话总机系统:接线员(Distributor)接听所有部门来电,按优先级和安全规则转接给对应负责人(CPU核心),既避免电话轰炸,又让多核团队高效协作!”​
通过这张图,可以清晰理解中断如何从外设传递到CPU核心,以及GIC在实时性、安全性和多核调度中的核心作用。

① 分发器(Distributor) 系统中的所有中断源都连接到该单元。可以通过仲裁单元的寄存器来控制各个中断源的属性,例如优先级、状态、安全性、路由信息和使能状态。 分发器把中断输出到“CPU接口单元”,后者决定将哪个中断转发给CPU核。

② CPU接口单元(CPU Interface) CPU核通过控制器的CPU接口单元接收中断。CPU接口单元寄存器用于屏蔽,识别和控制转发到CPU核的中断的状态。系统中的每个CPU核心都有一个单独的CPU接口。 中断在软件中由一个称为中断ID的数字标识。中断ID唯一对应于一个中断源。软件可以使用中断ID来识别中断源并调用相应的处理程序来处理中断。呈现给软件的中断ID由系统设计确定,一般在SOC的数据手册有记录。

要理解ARM的中断控制器GIC中的 ​​分发器(Distributor)​​ 和 ​​CPU接口单元(CPU Interface)​​,可以用一个 ​​公司电话系统​​ 来比喻:


一、​​分发器(Distributor)——总机接线员​

​核心作用​​:统一接收所有“紧急电话”(中断请求),分类、排序后分派给对应部门(CPU核心)处理。
​通俗解释​​:

  1. ​接收所有来电​

    • 公司所有部门(外设)遇到问题都会拨打总机电话(产生中断),比如键盘部门报告按键被按下(SPI中断)、财务部门申请报销(PPI中断)等。
  2. ​分类与规则设置​

    • ​优先级排序​​:火灾报警(高优先级中断)比打印机缺纸(低优先级)优先处理。
    • ​目标分配​​:报销电话只能转给财务部(PPI中断只能发给特定CPU核心),客户投诉电话可转给任意部门(SPI中断可路由到任意核心)。
    • ​安全隔离​​:机密电话(安全中断)只能转接给保密部门(安全模式CPU核)。
  3. ​状态管理​

    • ​记录来电状态​​:
      • ​未接电话(挂起状态)​​:记录在“待办清单”(Pending状态)。
      • ​正在通话(活动状态)​​:转接给部门后标记为处理中(Active状态)。

​技术细节​​:

  • 分发器通过寄存器(如GICD_前缀)配置每个中断的触发方式(电平/边沿)、优先级、目标CPU列表等。
  • 支持1020个中断ID(0~1019),其中0~31为私有中断(SGI/PPI),32~1019为共享外设中断(SPI)。

二、​​CPU接口单元(CPU Interface)——部门对接员​

​核心作用​​:接收总机转接的“电话”(中断),提醒部门负责人(CPU核心)处理,并确认任务完成。
​通俗解释​​:

  1. ​接收并提醒处理​

    • 总机转来报销申请(PPI中断)→ 对接员(CPU接口)通知财务部经理(CPU核心):“有任务待处理!”。
  2. ​屏蔽与优先级过滤​

    • ​设置门槛​​:财务部只处理金额超过100元的报销(设置优先级掩码,低于阈值的中断不转交)。
    • ​紧急插队​​:若火灾报警(高优先级中断)到来,对接员会打断当前报销处理(中断抢占)。
  3. ​处理完成确认​

    • 财务部处理完报销后,对接员需向总机反馈:“任务完成!”(写入EOI寄存器清除中断标志)。

​技术细节​​:

  • 每个CPU核心有独立的接口单元(如GICC_前缀寄存器),负责中断确认、优先级掩码设置等。
  • 中断处理完成后需分两步操作:优先级下降(允许其他中断抢占)和状态清除(标记为Inactive)。

三、​​中断处理全流程(以按键触发中断为例)​
  1. ​按键按下​​:键盘部门拨打总机(产生SPI中断)→ 分发器接收并标记为Pending。
  2. ​总机处理​​:根据优先级和目标列表,转接给最空闲的对接员(CPU Interface 0)。
  3. ​对接员转达​​:通知技术部负责人(CPU核心0):“有按键任务待处理!”→ 触发IRQ异常。
  4. ​处理与反馈​​:
    • 技术部处理按键输入(更新屏幕显示)→ 写入EOI寄存器通知对接员。
    • 对接员清除中断状态,总机更新记录为Inactive。

一句话总结

​“分发器像总机接线员:统一接听所有设备的中断请求,按优先级和安全规则分派任务;CPU接口像部门对接员:确保中断精准送达CPU核心,并跟踪处理结果。两者配合,让多核系统高效响应外设需求!”​
通过这套机制,GIC实现了中断的优先级管理、多核协作和安全隔离,是手机、服务器等设备稳定运行的关键。

中断可以有多种不同的类型:

① 软件触发中断(SGI,Software Generated Interrupt) 这是由软件通过写入专用仲裁单元的寄存器即软件触发中断寄存器(ICDSGIR)显式生成的。它最常用于CPU核间通信。SGI既可以发给所有的核,也可以发送给系统中选定的一组核心。中断号0-15保留用于SGI的中断号。用于通信的确切中断号由软件决定。

② 私有外设中断(PPI,Private Peripheral Interrupt) 这是由单个CPU核私有的外设生成的。PPI的中断号为16-31。它们标识CPU核私有的中断源,并且独立于另一个内核上的相同中断源,比如,每个核的计时器。

③ 共享外设中断(SPI,Shared Peripheral Interrupt) 这是由外设生成的,中断控制器可以将其路由到多个核。中断号为32-1020。SPI用于从整个系统可访问的各种外围设备发出中断信号。

中断可以是边沿触发的(在中断控制器检测到相关输入的上升沿时认为中断触发,并且一直保持到清除为止)或电平触发(仅在中断控制器的相关输入为高时触发)。

中断可以处于多种不同状态:

① 非活动状态(Inactive)–这意味着该中断未触发。 ② 挂起(Pending)–这意味着中断源已被触发,但正在等待CPU核处理。待处理的中断要通过转发到CPU接口单元,然后再由CPU接口单元转发到内核。 ③ 活动(Active)–描述了一个已被内核接收并正在处理的中断。 ④ 活动和挂起(Active and pending)–描述了一种情况,其中CPU核正在为中断服务,而GIC又收到来自同一源的中断。

中断的优先级和可接收中断的核都在分发器(distributor)中配置。外设发给分发器的中断将标记为pending状态(或Active and Pending状态,如触发时果状态是active)。distributor确定可以传递给CPU核的优先级最高的pending中断,并将其转发给内核的CPU interface。通过CPU interface,该中断又向CPU核发出信号,此时CPU核将触发FIQ或IRQ异常。

作为响应,CPU核执行异常处理程序。异常处理程序必须从CPU interface寄存器查询中断ID,并开始为中断源提供服务。完成后,处理程序必须写入CPU interface寄存器以报告处理结束。然后CPU interface准备转发distributor发给它的下一个中断。

在处理中断时,中断的状态开始为pending,active,结束时变成inactive。中断状态保存在distributor寄存器中。

你可以把ARM的中断系统想象成 ​​一个快递分拣中心​​,里面有快递员(中断源)、分拣机器人(GIC分发器)和派送员(CPU接口)。以下是通俗解释:


一、​​三种“快递包裹”(中断类型)​
  1. ​SGI(内部快递)​

    • ​比喻​​:同事之间的小纸条,用于核间通信。比如核A让核B处理任务,写个纸条(触发SGI)扔到核B的工位上。
    • ​特点​​:
      • 中断号0-15,像公司内部的16个快递柜编号。
      • 软件触发,无需硬件连线,类似微信消息。
  2. ​PPI(私人快递)​

    • ​比喻​​:每个员工的专属快递柜。比如核A的定时器到期,快递只能放进核A的柜子(中断号16-31)。
    • ​特点​​:
      • 仅对特定CPU核有效,如私人事务(如本地计时器、传感器报警)。
      • 每个核的PPI独立,互不干扰。
  3. ​SPI(公共快递)​

    • ​比喻​​:全公司的公共快递站。比如网卡收到数据,快递员把包裹放在公共区(中断号32-1020),分拣机器人决定派给哪个员工。
    • ​特点​​:
      • 外设共享,可路由到任意核(如USB设备、传感器)。
      • 触发方式分两种:​​边沿触发​​(按一次门铃)或​​电平触发​​(门铃一直响)。

二、​​快递的“物流状态”(中断状态)​
  1. ​非活动(Inactive)​

    • 快递未发出,包裹还在仓库里躺着。
  2. ​挂起(Pending)​

    • 快递已发出,但分拣中心还没分拣。比如按键按下后,GIC检测到信号但未处理。
  3. ​活动(Active)​

    • 快递正在派送中,员工已签收(CPU开始处理中断)。
  4. ​活动且挂起(Active and Pending)​

    • 员工正在拆快递,快递员又送来一个同款包裹。比如传感器连续触发两次中断。

三、​​分拣中心的工作流程​
  1. ​分拣机器人(Distributor)​

    • ​核心任务​​:
      • ​优先级排序​​:火灾警报(高优先级)比打印机缺纸(低优先级)优先处理。
      • ​路由规则​​:公共快递(SPI)分给最闲的员工(CPU核)。
      • ​状态管理​​:标记包裹状态(Pending→Active)并更新物流信息。
  2. ​派送员(CPU Interface)​

    • ​具体工作​​:
      • 接收分拣好的包裹(最高优先级中断)。
      • 通知员工:“有你的快递!”(触发IRQ/FIQ异常)。
      • 员工签收后,撕掉快递单(清除中断标志)。
  3. ​员工处理(CPU核)​

    • ​步骤​​:
      • 暂停手头工作,查快递单号(读取中断ID)。
      • 拆包裹(执行中断处理程序)。
      • 处理完通知分拣中心:“任务完成!”(写EOI寄存器)。

四、​​为什么需要这套系统?​
  1. ​避免混乱​​:

    • 没有分拣中心,所有快递直接堆到员工桌上,员工会被频繁打断。
  2. ​多核协作​​:

    • 分拣中心动态分配任务,大核处理复杂计算,小核处理实时任务。
  3. ​实时性与安全​​:

    • 高优先级中断(如硬件故障)插队处理,机密任务(如指纹识别)隔离到安全核。

一句话总结

​“ARM的中断系统像快递分拣中心:分拣机器人(Distributor)按优先级派送包裹(中断),派送员(CPU Interface)确保快递精准送达员工(CPU核),既避免包裹堆积,又让多核团队高效协作!”​
掌握这套机制,就能理解手机、服务器如何快速响应按键、网络数据等事件,同时避免系统卡顿或崩溃。

下图是GIC控制器的逻辑结构:

这张图展示的是 ​​ARM通用中断控制器(GIC)​​ 的架构,可以把它想象成一个 ​​国际快递分拣中心​​,负责接收全球各地(外设、软件、虚拟机)的包裹(中断请求),分拣后派送到对应的国家(CPU核心)或跨国分公司(虚拟机)。以下是逐层解析:


一、​​核心角色与流程​
1. ​​分拣中心(Distributor)​
  • ​功能​​:统一接收所有包裹(中断请求),分类、标记、排序。
  • ​处理流程​​:
    • ​接收包裹​​:
      • ​本地快递(PPI/SGI)​​:员工私人包裹(如核0的定时器中断、核1发来的内部通知)。
      • ​国际快递(SPI)​​:跨国包裹(如网卡数据、USB设备中断)。
      • ​跨国分公司快递(Virtual)​​:虚拟机的包裹(如虚拟机监控程序发来的请求)。
    • ​贴标签​​:每个包裹贴上唯一ID(中断号0~1019),记录优先级和安全等级(如机密/普通)。
    • ​分拣规则​​:
      • 优先级最高的包裹(如火灾警报)优先派送。
      • 机密包裹(安全中断)只能派给指定国家(安全模式CPU核)。
2. ​​国家分拣站(CPU Interface)​
  • ​功能​​:每个国家(CPU核心)有自己的分拣站,负责接收总部分拣的包裹,并通知本地快递员(CPU核心)签收。
    • ​例如​​:
      • ​分拣站0ICC_0)​​:对应核0,处理本地包裹(PPI)和分派的国际包裹(SPI)。
      • ​分拣站7(GICC_7)​​:对应核7,支持虚拟化包裹(GICV_7)。
3. ​​跨国分公司通道(Virtual Interface)​
  • ​功能​​:处理跨国分公司(虚拟机)的包裹。
    • ​虚拟监控分拣站(GICH)​​:跨国总部的分拣员,负责接收虚拟机请求(如虚拟机需要访问硬件)。
    • ​虚拟分拣站(GICV)​​:分公司的本地分拣员,处理虚拟机内部的中断(如虚拟机中的APP触发请求)。

二、​​快递类型与标签(中断分类)​
​快递类型​​通俗比喻​​技术细节​
​SGI(0~15号包裹)​​公司内部文件​​:员工A给员工B发通知(如核0让核1处理任务)。软件触发,用于多核通信(如核间任务分配)。
​PPI(16~31号包裹)​​私人包裹​​:每个员工的专属快递(如核0的本地定时器到期)。每个核独享,不与其他核共享。
​SPI(32~1019号包裹)​​国际包裹​​:全球可送达的公共快递(如网卡、硬盘中断)。可路由到任意CPU核心,优先级由分发器动态分配。
​虚拟包裹(VFIQ/VIRQ)​​跨国分公司快递​​:虚拟机内部的需求(如虚拟机中的APP请求访问硬件)。通过虚拟接口(GICV/GICH)与物理CPU核心通信。

三、​​分拣中心的“黑科技”​
  1. ​优先级与抢占​

    • ​插队规则​​:高优先级包裹(如硬件故障)会打断低优先级任务(如音乐播放),类似急救车优先通行。
    • ​多核负载均衡​​:自动将包裹分给最空闲的国家(CPU核心),提升整体效率。
  2. ​安全隔离(TrustZone)​

    • ​机密包裹​​:安全中断(如指纹识别)只能派送给“保密国家”(安全模式CPU核),普通员工(非安全模式)无权接触。
  3. ​虚拟化支持(GICV/GICH)​

    • ​跨国分公司管理​​:虚拟机监控程序(Hypervisor)像跨国总部,通过虚拟接口协调虚拟机的中断请求。
    • ​示例流程​​:
      1. 虚拟机中的APP触发中断 → 虚拟分拣站(GICV)接收并标记为“虚拟包裹”。
      2. 虚拟监控分拣站(GICH)将包裹转发给物理分拣站(GICC)。
      3. 物理CPU核心处理完成后,通过虚拟接口返回结果给虚拟机。

四、​​分拣中心的“物流状态”​
  1. ​包裹状态​

    • ​未分拣(Pending)​​:包裹在分拣中心等待处理。
    • ​派送中(Active)​​:包裹已派送给某个国家(CPU核心),但未签收。
    • ​已签收(Inactive)​​:包裹被处理完成,状态清除。
  2. ​异常情况​

    • ​重复包裹(Active and Pending)​​:员工正在拆包裹,分拣中心又收到同款包裹(如传感器连续触发两次中断)。

一句话总结

​“GIC像一个国际快递分拣中心:分发器(Distributor)是总部,接收全球包裹(中断)并按规则分派;CPU接口是国家分拣站,确保包裹精准送达;虚拟接口是跨国通道,协调虚拟机的中断请求——整套系统让手机、服务器能同时处理上千个任务,既高效又安全!”​

1.1.1 配置

GIC作为内存映射的外围设备,被软件访问。所有内核都可以访问公共的distributor单元,但是CPU interface是备份的,也就是说,每个CPU核都使用相同的地址来访问其专用CPU接口。一个CPU核不可能访问另一个CPU核的CPU接口。

Distributor拥有许多寄存器,可以通过它们配置各个中断的属性。这些可配置属性是:

  • 中断优先级:Distributor使用它来确定接下来将哪个中断转发到CPU接口。

  • 中断配置:这确定中断是对电平触发还是边沿触发。

  • 中断目标:这确定了可以将中断发给哪些CPU核。

  • 中断启用或禁用状态:只有Distributor中启用的那些中断变为挂起状态时,才有资格转发。

  • 中断安全性:确定将中断分配给Secure还是Normal world软件。

  • 中断状态。

    Distributor还提供优先级屏蔽,可防止低于某个优先级的中断发送给CPU核。 每个CPU核上的CPU interface,专注于控制和处理发送给该CPU核的中断。

你可以把 ​​GIC(通用中断控制器)​​ 想象成一个 ​​大型快递分拣中心​​,负责接收来自全球各地(外设、软件、虚拟机)的包裹(中断请求),并精准分发给每个快递员(CPU核心)。以下是通俗解释:


一、​​分拣中心(Distributor)——公共总控台​

​功能​​:统一管理所有包裹(中断),决定分发给谁、按什么规则分发。
​通俗比喻​​:

  • ​分拣中心​​是公共的,所有快递员(CPU核心)都可以查看总控台的规则,但无法修改其他快递员的专属设置。
  • ​关键配置​​:
    1. ​包裹优先级​​:火灾包裹(高优先级)比普通包裹优先处理。
    2. ​包裹类型​​:
      • ​边沿触发​​:按一次门铃就记录(如按键按下一次)。
      • ​电平触发​​:门铃一直响才记录(如传感器持续高温)。
    3. ​目标快递员​​:指定包裹只能给张三或李四(如核0处理实时任务,核1处理网络数据)。
    4. ​安检规则​​:机密包裹(安全中断)只能交给保密部门(安全模式CPU核)。
    5. ​包裹状态​​:记录包裹是否已签收(中断是否处理完成)。

​技术细节​​:

  • Distributor通过寄存器配置每个中断的优先级(0-255,数值越小优先级越高)、触发方式、目标核列表等[]。
  • 高优先级中断可抢占低优先级任务(如消防车优先通行)。

二、​​专属快递站(CPU Interface)——每个快递员的私人柜台​

​功能​​:接收分拣中心分配的包裹,并确保快递员(CPU核心)能专注处理。
​通俗比喻​​:

  • 每个快递员有​​独立柜台​​,只能处理自己的包裹,无法查看他人柜台。
  • ​关键操作​​:
    1. ​设置门槛​​:只接收重要包裹(如屏蔽优先级低于50的中断)。
    2. ​签收确认​​:快递员处理完包裹后,必须向分拣中心反馈“已签收”(写EOI寄存器清除中断标志)。
    3. ​紧急插队​​:若新包裹更紧急(高优先级中断),快递员会暂停当前任务,优先处理新包裹。

​技术细节​​:

  • 每个CPU核的接口单元独立控制中断屏蔽、优先级过滤和抢占逻辑。
  • 中断处理完成后需两步操作:优先级降级(允许其他中断抢占)和状态清除(标记为Inactive)。

三、​​分拣流程示例(以网络数据中断为例)​
  1. ​包裹到达​​:网卡收到数据 → 分拣中心标记为“待处理”(Pending状态)。
  2. ​分拣规则​​:
    • 优先级设为80(高于按键中断,低于硬件故障)。
    • 目标核设为核1(负责网络任务)。
  3. ​派送通知​​:分拣中心将包裹转给核1的快递站 → 触发IRQ异常。
  4. ​处理与反馈​​:
    • 核1处理数据转发 → 写入EOI寄存器通知分拣中心。
    • 分拣中心更新状态为“已签收”(Inactive)。

一句话总结

​“GIC像快递分拣系统:分拣中心(Distributor)统一管理所有中断规则,专属快递站(CPU Interface)确保每个核专注处理自己的任务。高优先级中断插队,安全中断隔离,多核协作高效稳定!”​
通过这套机制,手机、服务器能同时处理上千个中断请求,兼顾实时性与安全性。

1.1.2 初始化

Distributor和CPU interface在复位时均被禁用。复位后,必须初始化GIC,才能将中断传递给CPU核。 ​ 在Distributor中,软件必须配置优先级、目标核、安全性并启用单个中断;随后必须通过其控制寄存器使能。 ​ 对于每个CPU interface,软件必须对优先级和抢占设置进行编程。每个CPU接口模块本身必须通过其控制寄存器使能。 ​ 在CPU核可以处理中断之前,软件会通过在向量表中设置有效的中断向量并清除CPSR中的中断屏蔽位来让CPU核可以接收中断。 ​ 可以通过禁用Distributor单元来禁用系统中的整个中断机制;可以通过禁用单个CPU的CPU接口模块或者在CPSR中设置屏蔽位来禁止向单个CPU核的中断传递。也可以在Distributor中禁用(或启用)单个中断。 ​ 为了使某个中断可以触发CPU核,必须将各个中断,Distributor和CPU interface全部使能,并

将CPSR中断屏蔽位清零,如下图:

可以把ARM的中断控制器(GIC)想象成一个 ​​国际快递分拣中心​​,而CPU核是各个国家的快递员。​​复位状态相当于整个分拣中心停电关机​​,所有包裹(中断)都无法处理。要让快递系统运作起来,需要一步步开启设备、设置规则。以下是通俗分步解释:


一、​​分拣中心重启:Distributor的初始化​
  1. ​停电重启(复位后状态)​

    • ​比喻​​:分拣中心停电Distributor和CPU Interface被禁用),所有包裹堆积在仓库,无法派送。
    • ​技术细节​​:复位后GIC默认关闭所有中断传递功能。
  2. ​制定派送规则(配置中断属性)​

    • ​优先级标签​​:火灾包裹(高优先级)比普通包裹优先派送 - ​​目标国家​​:指定包裹只能发给美国(CPU核0)或中国(CPU核1)。
    • ​安全等级​​:机密包裹(安全中断)只能派给保密部门(安全模式核)。
    • ​启用包裹通道​​:逐个开启允许派送的包裹类型(启用单个中断)。
    • ​技术操作​​:通过Distributor寄存器(如GICD_ICENABLER禁用所有中断,再通过GICD_ISENABLER启用特定中断)[^^5]。
  3. ​启动分拣中心(使能Distributor)​

    • ​比喻​​:按下总电源开关,分拣机器人开始工作。
    • ​技术操作​​:设置GICD_CTLR寄存器的使能位(如写入1)。

二、​​各国快递站激活:CPU Interface的配置​
  1. ​设置接单门槛(优先级过滤)​

    • ​比喻​​:美国快递站只接收价值超过100美元的包裹(设置优先级掩码)。
    • ​技术操作​​:通过GICC_PMR寄存器设置CPU核的优先级阈值(如0xF0表示仅处理优先级高于16的中断)。
  2. ​允许插队规则(抢占设置)​

    • ​比喻​​:急救车(高优先级包裹)可打断当前派送任务。
    • ​技术操作​​:通过GICC_BPR设置抢占级别(如设置为2,允许两级抢占)。
  3. ​开启快递站电源(使能CPU Interface)​

    • ​比喻​​:各国快递站通电,准备接收包裹。
    • ​技术操作​​:设置GICC_CTLR寄存器的使能位。

三、​​快递员准备接单:CPU核的启动​
  1. ​设置接单热线(中断向量表)​

    • ​比喻​​:快递员需要知道包裹处理流程(如火灾包裹拨打119)。
    • ​技术操作​​:在内存中设置中断向量表,指向中断处理函数地址。
  2. ​摘掉“请勿打扰”牌子(清除CPSR屏蔽位)​

    • ​比喻​​:快递员摘掉“休息中”的牌子,开始接电话。
    • ​技术操作​​:清除CPU核的CPSR寄存器中的中断屏蔽位(如IRQ/FIQ位)。

四、​​中断触发全链路:缺一不可的条件​

只有当以下条件​​全部满足​​时,中断才能送达CPU核:

  1. ​包裹已贴标签​​:中断在Distributor中启用。
  2. ​分拣中心通电​​:Distributor全局使能。
  3. ​快递站通电​​:目标CPU核的Interface使能。
  4. ​快递员在线​​:CPU核的CPSR屏蔽位已清除。
    ​任一环节关闭,包裹都会被拦截​​(如禁用Distributor相当于切断全球物流)。

五、​​灵活的中手段​
  1. ​全局关停​​:禁用Distributor(切断所有包裹派送)。
  2. ​单个国家拒收​​:禁用某个CPU核的Interface(如美国快递站罢工)。
  3. ​屏蔽特定包裹​​:在Distributor中禁用单个中断(如拒收所有来自键盘的包裹)。

一句话总结

​“GIC像快递分拣系统:分拣中心(Distributor)制定规则并启动物流,各国快递站(CPU Interface)设置接单门槛,快递员(CPU核)打开接单热线。只有全链路打通,中断才能精准送达!”​
通过这套机制,手机、服务器能高效处理实时事件,同时支持多核协作与安全隔离。

1.1.3 GIC中断处理

当CPU核接收到中断时,它会跳转到中断向量表执行。 ​ 顶层中断处理程序读取CPU接口模块的Interrupt Acknowledge Register,以获取中断ID。除了返回中断ID之外,读取操作还会使该中断在Distributor中标记为active状态。一旦知道了中断ID(标识中断源),顶层处理程序现在就可以分派特定于设备的处理程序来处理中断。 ​ 当特定于设备的处理程序完成执行时,顶级处理程序将相同的中断ID写入CPU interface模块中的End of Interrupt register中断结束寄存器,指示中断处理结束。除了把当前中断移除active状态之外,这将使最终中断状态变为inactive或pending(如果状态为inactive and pending),这将使CPU interface能够将更多待处理pending的中断转发给CPU核。这样就结束了单个中断的处理。 ​ 同一CPU核上可能有多个中断等待服务,但是CPU interface一次只能发出一个中断信号。顶层中断处理程序重复上述顺序,直到读取特殊的中断ID值1023,表明该内核不再有任何待处理的中断。这个特殊的中断ID被称为伪中断ID(spurious interrupt ID)。 ​ 伪中断ID是保留值,不能分配给系统中的任何设备。

可以把CPU处理中断的过程想象成 ​​快递员处理包裹(中断)的标准化流程​​,每个环节都有明确的操作步骤和规则。以下是通俗解释:


一、​​收到包裹:跳转到“分拣中心”(中断向量表)​
  • ​比喻​​:快递员(CPU核)收到包裹(中断请求),立刻跑到分拣中心(中断向量表)查看包裹类型对应的处理流程。
  • ​技术细节​​:
    • 中断向量表是内存中的一张“地址清单”,每个中断ID对应一个处理程序的入口地址(类似“火灾包裹处理区”或“键盘包裹处理区”)。
    • CPU收到中断信号后,自动根据中断类型号(如1023是伪中断)跳转到对应的处理程序入口。

二、​​拆包验货:获取“包裹单号”(中断ID)​
  • ​比喻​​:快递员打开包裹,扫描单号(读取​​Interrupt Acknowledge Register​​),确认这是哪个包裹(中断源)。
  • ​关键操作​​:
    • ​标记为“处理中”​​:扫描单号后,分拣中心(Distributor)会将此包裹状态从“待处理”(Pending)改为“处理中”(Active),防止其他快递员重复处理。
    • ​获得唯一ID​​:例如键盘中断ID是32,网卡中断ID是100,这些编号在系统设计时就已确定。

三、​​分派任务:呼叫“专业处理员”(设备处理程序)​
  • ​比喻​​:根据单号(中断ID),快递员呼叫对应的专业团队(如“键盘维修组”或“网卡数据组”)处理包裹。
  • ​技术细节​​:
    • ​分派规则​​:顶层处理程序通过中断ID查表,找到对应的设备驱动函数(如处理键盘按键的代码)。
    • ​快速处理原则​​:设备处理程序需短小精悍,避免长时间占用快递员(例如仅记录按键值,不立刻更新屏幕)。

四、​​完成签收:通知“包裹已送达”(写入EOI寄存器)​
  • ​比喻​​:专业团队处理完包裹后,快递员在系统里点击“签收完成”(写入​​End of Interrupt Register​​),包裹状态变为“已完成”(Inactive)。
  • ​关键作用​​:
    • ​释放资源​​:标记中断为完成,分拣中心(Distributor)可以继续派送新包裹(其他Pending中断)。
    • ​状态更新​​:若处理期间同一中断源再次触发,状态会变为“活动且待处理”(Active and Pending),避免遗漏。

五、​​循环检查:确认“没有遗漏包裹”(检测伪中断ID 1023)​
  • ​比喻​​:快递员反复检查分拣中心,直到系统显示“无包裹”(读取到伪中断ID 1023),才停止工作。
  • ​技术细节​​:
    • ​伪中断ID 1023​​:相当于系统设置的“空箱标识”,告诉CPU“当前无待处理中断”。
    • ​避免死循环​​:若未检测到1023,CPU会误以为还有包裹,导致无意义循环(类似快递员反复扫描空货架)。

六、​​多包裹处理:一次只能拿一个包裹​
  • ​比喻​​:快递员一次只能搬运一个包裹(CPU核一次处理一个中断),处理完再取下一个。
  • ​优先级规则​​:高优先级包裹(如火灾警报)会插队处理,低优先级需等待。

一句话总结

​“CPU处理中断就像快递分拣:跳转分拣中心查单号→呼叫专业团队处理→签收后释放资源→循环检查直到无包裹。伪中断ID 1023是‘空箱信号’,防止快递员空跑!”​
通过这套机制,CPU能高效处理键盘、网络等外设请求,同时避免中断丢失或重复处理。

1.2 GIC的寄存器

GIC分为两部分:Distributor和CPU interface,它们的寄存器都有相应的前缀:“GICD”、“GICC”。这些寄存器都是映射为内存接口(memery map),CPU可以直接读写。

1.2.1 Distributor 寄存器描述

1. Distributor Control Register, GICD_CTLR
位域读写描述
1EnableGrp1R/W用于将pending Group 1中断从Distributor转发到CPU interfaces 0:group 1中断不转发 1:根据优先级规则转发Group 1中断
0EnableGrp0R/W用于将pending Group 0中断从Distributor转发到CPU interfaces 0:group 0中断不转发 1:根据优先级规则转发Group 0中断
  1. 整体结构​
    GIC就像一个大快递分拣中心,分为两个部门:
  • ​分拣部(Distributor)​​:相当于分拣员,负责接收所有快递(中断信号)
  • ​派送部(CPU接口)​​:负责把分拣好的快递派送给收件人(CPU处理)
  1. ​控制开关(寄存器)​
    图中展示的是分拣部的总控开关(GICD_CTLR寄存器),这个开关有32个按钮位,但目前只有最底下的两个按钮有用:
  • 🟡 ​​黄色按钮1(EnableGrp1)​​:控制VIP快递(高优先级中断)是否进入派送流程
  • 🟡 ​​黄色按钮0(EnableGrp0)​​:控制普通快递(基础中断)是否进入派送流程
  1. ​工作模式​
    每个按钮都有两种状态:
  • ​按下去(写1)​​:允许此类快递进入分拣流程,系统会根据包裹上的优先级标签(中断优先级)自动安排派送顺序
  • ​弹起来(写0)​​:直接拦截此类快递,整个分拣中心会假装没收到这类包裹
  1. ​实际应用​
    假设现在要系统维护:
    ① 先关闭普通快递通道(EnableGrp0=0),避免普通中断干扰
    ② 保持VIP通道开启(EnableGrp1=1),只处理紧急事务
    ③ 维护完成后,再同时打开两个按钮(都写1),恢复正常服务

这种设计让操作系统像物流调度员一样,可以通过简单操作这两个关键开关,灵活控制哪些类型的中断需要立即处理,哪些可以暂时屏蔽,从而保证系统高效稳定运行。

2. Interrupt Controller Type Register, GICD_TYPER
位域读写描述
15:11LSPIR如果GIC实现了安全扩展,则此字段的值是已实现的可锁定SPI的最大数量,范围为0(0b00000)到31(0b11111)。 如果此字段为0b00000,则GIC不会实现配置锁定。 如果GIC没有实现安全扩展,则保留该字段。
10SecurityExtnR表示GIC是否实施安全扩展: 0未实施安全扩展; 1实施了安全扩展
7:5CPUNumberR表示已实现的CPU interfaces的数量。 已实现的CPU interfaces数量比该字段的值大1。 例如,如果此字段为0b011,则有四个CPU interfaces。
4:0ITLinesNumberR表示GIC支持的最大中断数。 如果ITLinesNumber = N,则最大中断数为32*(N+1)。 中断ID的范围是0到(ID的数量– 1)。 例如:0b00011最多128条中断线,中断ID 0-127。 中断的最大数量为1020(0b11111)。 无论此字段定义的中断ID的范围如何,都将中断ID 1020-1023保留用于特殊目的

​整个寄存器 = 快递中心的配置表​

这张图告诉我们这个快递中心(GIC中断控制器)有多大容量、有什么特殊功能,就像一份“分拣中心能力说明书”。


​核心配置项解读​

  1. ​📦 最大包裹处理能力(ITLinesNumber)​

    • ​字段位置​​:第4-0位(最右侧5个开关)
    • ​作用​​:决定快递中心最多能处理多少个包裹(中断信号)。
    • ​计算公式​​:最大中断数 = 32 × (N+1)
      • 比如:如果这里显示0b00011(十进制的3),则能处理 ​​32×(3+1)=128个包裹​
      • ​特殊规则​​:最后4个包裹号(1020-1023)是“保留快递柜”,专门存放紧急物资,普通包裹不能用这些编号。
  2. ​👨💼 分拣员数量(CPUNumber)​

    • ​字段位置​​:第7-5位
    • ​作用​​:告诉你有多少个分拣员(CPU接口)在岗。
    • ​计算公式​​:实际分拣员数 = 数值 + 1
      • 比如:显示0b011(十进制的3),则实际有 ​​3+1=4个分拣员​​。
  3. ​🔒 安全保险柜功能(SecurityExtn)​

    • ​字段位置​​:第10位(单个开关)
    • ​作用​​:快递中心是否有“安全保险柜”(安全扩展功能)。
      • 0:没有保险柜,所有包裹混在一起处理
      • 1:有保险柜,重要包裹(安全相关中断)可以单独上锁保护。
  4. ​🗝️ 保险柜钥匙数量(LSPI)​

    • ​字段位置​​:第15-11位(仅当有保险柜时生效)
    • ​作用​​:如果启用了安全保险柜,这里说明最多有多少把钥匙(可锁定SPI中断数量)。
      • 范围:0到31把钥匙
      • 0:虽然有保险柜,但暂时不提供锁包裹功能
      • 其他值:比如0b11111(十进制的31),表示最多能锁住31个重要包裹。
  5. ​🚧 预留区域(Reserved)​

    • 说明书上的空白格(其他位),是快递中心为未来升级预留的空间,暂时用不上。

​实际场景举例​

假设你看到这份配置表显示:

  • ITLinesNumber=0b11111 → 最大处理 ​​32×(31+1)=1024个包裹​
  • CPUNumber=0b100 → ​​4+1=5个分拣员​
  • SecurityExtn=1 → 有安全保险柜
  • LSPI=0b10101 → 最多能锁住21个重要包裹

那么说明这个快递中心:
1️⃣ 能处理1024个包裹(但1020-1023号包裹是保留的)
2️⃣ 有5个分拣员随时待命
3️⃣ 支持重要包裹单独上锁保护
4️⃣ 安全模式下最多锁定21个包裹


​为什么需要这份表?​

就像快递中心经理需要知道仓库有多大、有多少员工一样,操作系统通过读取这个寄存器,就能知道当前中断控制器的能力上限,从而合理分配任务(比如:最多能注册多少中断?是否需要处理安全相关的中断?)。

希望这个比喻能帮你轻松理解! 😄

3. Distributor Implementer Identification Register, GICD_IIDR
位域读写描述
31:24ProductIDR产品标识ID
23:20保留
19:16VariantR通常是产品的主要版本号
15:12RevisionR通常此字段用于区分产品的次版本号
11:0ImplementerR含有实现这个GIC的公司的JEP106代码; [11:8]:JEP106 continuation code,对于ARM实现,此字段为0x4; [7]:始终为0; [6:0]:实现者的JEP106code,对于ARM实现,此字段为0x3B

整块牌子 = 分拣中心的身份名片​

这个寄存器就像一块电子铭牌,记录了分拣中心(中断控制器)的型号、版本、制造商信息,操作系统每次启动就会自动读取这些信息。


​分拣中心名片详解​

  1. ​📦 型号编号(ProductID)​

    • ​位置​​:31-24位(最左边的8个格)
    • ​作用​​:类似分拣中心的设备型号,比如“快递中心Pro-2024款”。
    • ​特点​​:
      • 只读不可修改(就像机器出厂时镭雕的编号)
  2. ​🏷️ 版本大升级(Variant)​

    • ​位置​​:19-16位
    • ​作用​​:记录架构大改版,比如:
      • V1到V2可能从传统仓库升级成自动化分拣
      • V3可能新增AI调度机器人
  3. ​🔧 维修小版本(Revision)​

    • ​位置​​:15-12位
    • ​作用​​:记录小优化补丁,比如:
      • Rev1.0 ➔ Rev1.1:修正传送带卡顿问题
      • Rev1.2 ➔ Rev1.3:优化包裹扫码速度
  4. ​🏢 制造商密码(Implementer)​

    • ​位置​​:11-0位
    • ​作用​​:相当于制造商身份证(类似公司营业执照号),ARM的专属解码:
      • ​[举例]​
        → 0x4 + 0x3B = ARM公司独家代码
        → 就像“顺丰编码SF-9527”代表官方认证分拣中心
  5. ​🚧 留空扩展位(Reserved)​

    • ​位置​​:23-20位
    • ​作用​​:给未来升级预留的空白栏位(比如应急通道扩建位置)

​举个实际例子​

假设寄存器显示:

  • ▶️ ​​Variant=0x4​​ → 第四代分拣中心架构(比如配备无人机投递)
  • ▶️ ​​Revision=0x2​​ → 第二个优化版本(修复了无人机电池过热问题)
  • ▶️ ​​Implementer=0x43B​​ → ARM认证的标志(刻在设备上的正品钢印)

此时操作系统就能知道:
🔹 正在使用ARM制造的第四代分拣中心
🔹 当前版本已升级到Rev.2
🔹 无需人工设置,所有参数自动识别


​为什么需要这个寄存器?​

就像快递总部要核查每个分拣中心的资质一样:
1️⃣ ​​兼容性问题​​:某新款快递机器人只能在V4架构的分拣中心运行
2️⃣ ​​调试定位​​:发现传送带卡顿时,通过Revision判断是否需要升级固件
3️⃣ ​​正版验证​​:Implementer代码确保不是山寨分拣中心

希望这个比喻能让你轻松看懂这个「硬件身份证」😊

4. Interrupt Group Registers, GICD_IGROUPRn
位域读写描述
31:0Group status bitsR/W组状态位,对于每个位: 0:相应的中断为Group 0; 1:相应的中断为Group 1。

对于一个中断,如何设置它的Group ?首先找到对应的GICD_IGROUPRn寄存器,即n是多少?还要确定使用这个寄存器里哪一位。 对于interrtups ID m,如下计算:

 n = m DIV 32,GICD_IGROUPRn里的n就确定了;
 GICD_IGROUPRn在GIC内部的偏移地址是多少?0x080+(4*n)
 使用GICD_IPRIORITYRn中哪一位来表示interrtups ID m?
 bit = m mod 32。

5. Interrupt Set-Enable Registers, GICD_ISENABLERn
位域读写描述
31:0Set-enable bitsR/W对于SPI和PPI类型的中断,每一位控制对应中断的转发行为:从Distributor转发到CPU interface: 读: 0:表示当前是禁止转发的; 1:表示当前是使能转发的; 写: 0:无效 1:使能转发

对于一个中断,如何找到GICD_ISENABLERn并确定相应的位?

 对于interrtups ID m,如下计算:
 n = m DIV 32,GICD_ISENABLERn里的n就确定了;
 GICD_ISENABLERn在GIC内部的偏移地址是多少?0x100+(4*n)
 使用GICD_ISENABLERn中哪一位来表示interrtups ID m?
 bit = m mod 32。

6. Interrupt Clear-Enable Registers, GICD_ICENABLERn
位域读写描述
31:0Clear-enable bitsR/W对于SPI和PPI类型的中断,每一位控制对应中断的转发行为:从Distributor转发到CPU interface: 读: 0:表示当前是禁止转发的; 1:表示当前是使能转发的; 写: 0:无效 1:禁止转发

对于一个中断,如何找到GICD_ICENABLERn并确定相应的位?

 对于interrtups ID m,如下计算:
 n = m DIV 32,GICD_ICENABLERn里的n就确定了;
 GICD_ICENABLERn在GIC内部的偏移地址是多少?0x180+(4*n)
 使用GICD_ICENABLERn中哪一位来表示interrtups ID m?
 bit = m mod 32。

7. Interrupt Set-Active Registers, GICD_ISACTIVERn
位域读写描述
31:0Set-active bitsR/W读: 0:表示相应中断不是active状态; 1:表示相应中断是active状态; 写: 0:无效 1:把相应中断设置为active状态,如果中断已处于Active状态,则写入无效

对于一个中断,如何找到GICD_ISACTIVERn并确定相应的位?

 对于interrtups ID m,如下计算:
 n = m DIV 32,GICD_ISACTIVERn里的n就确定了;
 GICD_ISACTIVERn在GIC内部的偏移地址是多少?0x300+(4*n)
 使用GICD_ISACTIVERn 中哪一位来表示interrtups ID m?
 bit = m mod 32。

8. Interrupt Clear-Active Registers, GICD_ICACTIVERn
位域读写描述
31:0Clear-active bitsR/W读: 0:表示相应中断不是active状态; 1:表示相应中断是active状态; 写: 0:无效 1:把相应中断设置为deactive状态,如果中断已处于dective状态,则写入无效

对于一个中断,如何找到GICD_ICACTIVERn并确定相应的位?

 对于interrtups ID m,如下计算:
 n = m DIV 32,GICD_ICACTIVERn里的n就确定了;
 GICD_ICACTIVERn 在GIC内部的偏移地址是多少?0x380+(4*n)
 使用GICD_ICACTIVERn中哪一位来表示interrtups ID m?
 bit = m mod 32。

9. Interrupt Priority Registers, GICD_IPRIORITYRn
位域读写描述
31:24Priority, byte offset 3R/W对于每一个中断,都有对应的8位数据用来描述:它的优先级。 每个优先级字段都对应一个优先级值,值越小,相应中断的优先级越高
23:16Priority, byte offset 2R/W
15:8Priority, byte offset 1R/W
7:0Priority, byte offset 0R/W

对于一个中断,如何设置它的优先级(Priority),首先找到对应的GICD_IPRIORITYRn寄存器,即n是多少?还要确定使用这个寄存器里哪一个字节。

 对于interrtups ID m,如下计算:
 n = m DIV 4,GICD_IPRIORITYRn里的n就确定了;
 GICD_IPRIORITYRn在GIC内部的偏移地址是多少?0x400+(4*n)
 使用GICD_IPRIORITYRn中4个字节中的哪一个来表示interrtups ID m的优先级?
 byte offset = m mod 4。
 byte offset 0对应寄存器里的[7:0];
 byte offset 1对应寄存器里的[15:8];
 byte offset 2对应寄存器里的[23:16];
 byte offset 3对应寄存器里的[31:24]。

10. Interrupt Processor Targets Registers, GICD_ITARGETSRn
位域读写描述
31:24CPU targets, byte offset 3R/W对于每一个中断,都有对应的8位数据用来描述:这个中断可以发给哪些CPU。 处理器编号从0开始,8位数里每个位均指代相应的处理器。 例如,值0x3表示将中断发送到处理器0和1。 当读取GICD_ITARGETSR0~GICD_ITARGETSR7时,读取里面任意字节,返回的都是执行这个读操作的CPU的编号。
23:16CPU targets, byte offset 2R/W
15:8CPU targets, byte offset 1R/W
7:0CPU targets, byte offset 0R/W

对于一个中断,如何设置它的目杯CPU?优先级(Priority),首先找到对应的GICD_ITARGETSRn寄存器,即n是多少?还要确定使用这个寄存器里哪一个字节。

 对于interrtups ID m,如下计算:
 n = m DIV 4,GICD_ITARGETSRn里的n就确定了;
 GICD_ITARGETSRn在GIC内部的偏移地址是多少?0x800+(4*n)
 使用GICD_ITARGETSRn中4个字节中的哪一个来表示interrtups ID m的目标CPU?
 byte offset = m mod 4。
 byte offset 0对应寄存器里的[7:0];
 byte offset 1对应寄存器里的[15:8];
 byte offset 2对应寄存器里的[23:16];
 byte offset 3对应寄存器里的[31:24]。

想象这个寄存器是​​快递包裹的派送规则表​​,每个包裹(中断信号)都有专属的派送标签(目标CPU配置),告诉分拣中心:“这个包裹要送给几号分拣员(CPU)”。


​核心规则详解​

1️⃣ ​​表格结构(寄存器布局)​
  • ​每个格子(寄存器)​​能管理​​4个包裹​​(中断ID),每个包裹的派送规则占一个​​小格子(8位)​​。
  • ​格子内部划分​​:
    • ​小格子3​​(字节偏移3):控制包裹的​​高优先级分拣员​​(对应寄存器的[31:24]位)
    • ​小格子2​​(字节偏移2):控制​​中等优先级分拣员​​(对应寄存器的[23:16]位)
    • ​小格子1​​(字节偏移1):控制​​普通分拣员​​(对应寄存器的[15:8]位)
    • ​小格子0​​(字节偏移0):控制​​备用分拣员​​(对应寄存器的[7:0]位)
2️⃣ ​​派送规则设定(二进制位含义)​
  • ​每个小格子(8位)​​对应​​8个分拣员​​(CPU编号0-7),每位代表一个分拣员:
    • ​二进制1​​:这个分拣员需要接收此类包裹(中断)
    • ​二进制0​​:不分派给这个分拣员
    • ​举例​​:0b00000111(二进制)→ 分拣员0、1、2要接收包裹
3️⃣ ​​如何找到包裹对应的格子?​

假设现在有一个包裹编号是 ​​m​​(中断ID):

  • ​步骤1:找大格子(寄存器编号n)​
    n = m ÷ 4(只取整数部分)
    • 比如:包裹编号​​m=9​​ → n=9÷4=2(第2个大格子)
  • ​步骤2:找小格子(字节偏移)​
    字节偏移 = m % 4(取余数)
    • 比如:包裹编号​​m=9​​ → 9%4=1 → ​​字节偏移1​​(对应寄存器的[15:8]位)
4️⃣ ​​实际贴标签(配置示例)​

​案例​​:想让包裹​​m=5​​同时派送给分拣员1和3:
1️⃣ ​​计算位置​

  • n=5÷4=1(使用第1个大格子GICD_ITARGETSR1)
  • 字节偏移=5%4=1(操作寄存器的[15:8]位)
    2️⃣ ​​设置二进制位​
  • 分拣员1 → 第1位写1
  • 分拣员3 → 第3位写1
  • 最终值:0b00001010(二进制,对应十六进制0x0A)

​特殊机制(隐藏规则)​

  • ​自动识别分拣员​​:如果分拣员查看自己的派送任务表(读取寄存器),系统会自动显示当前分拣员的编号(比如CPU2读寄存器时,返回的值会包含自己的编号)。
  • ​多分拣员协作​​:一个包裹可以同时贴多个分拣员标签(多CPU处理同一个中断),但需要分拣中心协调避免重复派送。

​为什么需要这个设计?​

就像快递总部需要灵活调度:
1️⃣ ​​负载均衡​​:紧急包裹(高优先级中断)可以指定给空闲分拣员
2️⃣ ​​容灾备份​​:重要包裹可同时派送多个分拣员,避免漏单
3️⃣ ​​动态调整​​:根据分拣员忙闲状态,随时修改派送规则

希望这个比喻能让你像快递调度员一样轻松配置中断目标! 🚚💨

11. Interrupt Configuration Registers, GICD_ICFGRn
位域读写描述
[2F+1:2F]Int_config, field FR/W对于每一个中断,都有对应的2位数据用来描述:它的边沿触发,还是电平触发。 对于Int_config [1],即高位[2F + 1],含义为: 0:相应的中断是电平触发; 1:相应的中断是边沿触发。 对于Int_config [0],即低位[2F],是保留位。

对于一个中断,如何找到GICD_ICFGRn并确定相应的位域F?

 对于interrtups ID m,如下计算:
 n = m DIV 16,GICD_ICFGRn里的n就确定了;
 GICD_ICACTIVERn 在GIC内部的偏移地址是多少?0xC00+(4*n)
 F = m mod 16。

12. Identification registers: Peripheral ID2 Register, ICPIDR2
位域读写描述
[31:0]-R/W由实现定义
[7:4]ArchRevR该字段的值取决于GIC架构版本: 0x1:GICv1; 0x2:GICv2。
[3:0]-R/W由实现定义

1.2.2 CPU interface寄存器描述

1. CPU Interface Control Register, GICC_CTLR

此寄存器用来控制CPU interface传给CPU的中断信号。对于不同版本的GIC,这个寄存器里各个位的含义大有不同。以GICv2为例,有如下2种格式:

GIC2 with Security Extensions, Non-secure copy 为例,GICC_CTLR中各个位的定义如下:

位域读写描述
[31:10]-保留
[9]EOImodeNSR/W控制对GICC_EOIR和GICC_DIR寄存器的非安全访问: 0:GICC_EOIR具有降低优先级和deactivate中断的功能; 对GICC_DIR的访问是未定义的。 1:GICC_EOIR仅具有降低优先级功能; GICC_DIR寄存器具有deactivate中断功能。
[8:7]-保留
[6]IRQBypDisGrp1R/W当CPU interface的IRQ信号被禁用时,该位控制是否向处理器发送bypass IRQ信号: 0:将bypass IRQ信号发送给处理器; 1:将bypass IRQ信号不发送到处理器。
[5]FIQBypDisGrp1R/W当CPU interface的FIQ信号被禁用时,该位控制是否向处理器发送bypass FIQ信号: 0:将bypass FIQ信号发送给处理器; 1:旁路FIQ信号不发送到处理器
[4:1]-保留
[0]-R/W使能CPU interface向连接的处理器发出的组1中断的信号: 0:禁用中断信号 1:使能中断信号

整体比喻​

这个寄存器相当于快递分拣中心控制台的 ​​核心控制面板​​,有 ​​32个隐藏开关​​(对应32个二进制位),但只有 ​​5个关键按钮​​ 真正生效,其他都是预留的空白按钮(保留位)。


​重点按钮说明​

1️⃣ ​​VIP包裹处理模式(EOImodeNS 第9位)​
  • ​作用​​:控制 ​​VIP包裹(高优先级中断)​​ 的分拣流程
  • ​按钮状态​​:
    • ​按下去(写1)​​ → 流程:
      ✔️ 分拣员只需降低包裹优先级
      ✔️ ​​禁止手动取出包裹​​(无法调用DIR寄存器的退件功能)
    • ​弹起来(写0)​​ → 完整VIP流程:
      ✔️ 分拣员既要降低优先级,又要取出包裹
      ✔️ ​​手动退件功能激活​​(允许调用DIR寄存器)
2️⃣ ​​紧急通道开关(IRQBypDisGrp1 第6位)​
  • ​作用​​:当普通分拣通道(IRQ信号)关闭时,是否启用 ​​紧急通道(bypass IRQ)​
  • ​按钮状态​​:
    • ​按下去(写1)​​ → 锁死紧急通道
      🚫 所有包裹必须走常规分拣流程
    • ​弹起来(写0)​​ → 开放紧急通道
      🚨 紧急包裹直接送达分拣员(绕过常规流程)
3️⃣ ​​超级紧急通道开关(FIQBypDisGrp1 第5位)​
  • ​作用​​:当特快分拣通道(FIQ信号)关闭时,是否启用 ​​超级紧急通道(bypass FIQ)​
  • ​按钮状态​​:与IRQ通道逻辑相同
    • ​写1​​:禁用超级通道
    • ​写0​​:激活超级通道
4️⃣ ​​总闸门开关(EnableGrp1 第0位)​
  • ​作用​​:整个分拣中心的总电源开关
  • ​按钮状态​​:
    • ​按下去(写1)​​ → 启动分拣中心
      💡 所有分拣员开始处理包裹
    • ​弹起来(写0)​​ → 切断电源
      🔌 分拣中心停止运作,所有包裹堆积在仓库

​控制台操作指南​

​场景1:处理系统崩溃​

1️⃣ 按下 ​​总闸门(EnableGrp1=1)​​ → 启动分拣中心
2️⃣ 按下 ​​VIP处理模式(EOImodeNS=1)​​ → 仅处理优先级,禁止手动退件
3️⃣ 弹起 ​​紧急通道开关(IRQBypDisGrp1=0)​​ → 允许紧急包裹直达CPU

​场景2:系统维护模式​

1️⃣ 关闭总闸门(EnableGrp1=0)→ 暂停所有分拣
2️⃣ 锁死所有紧急通道(IRQ/FIQBypDisGrp1=1)→ 彻底隔离系统


​为什么这样设计?​

就像快递分拣中心需要灵活应对各种突发状况:

  • ​模式切换​​:通过EOImodeNS切换VIP包裹处理逻辑,适应不同安全需求
  • ​紧急逃生​​:当常规通道故障时,bypass通道确保关键包裹不丢失
  • ​全局控制​​:总闸门一键切断所有分拣流程,便于系统维护

这排按钮让操作系统像分拣中心主管一样,既能精细控制单个流程,又能快速响应全局状态变化。💡

2. Interrupt Priority Mask Register, GICC_PMR

提供优先级过滤功能,优先级高于某值的中断,才会发送给CPU。

位域读写描述
[31:8]-保留
[7:0]-R/W优先级高于这个值的中断,才会发送给CPU

[7:0]共8位,可以表示256个优先级。但是某些芯片里的GIC支持的优先级少于256个,则某些位为RAZ / WI,如下所示:

 如果有128个级别,则寄存器中bit[0] = 0b0,即使用[7:1]来表示优先级;
 如果有64个级别,则寄存器中bit[1:0] = 0b00,即使用[7:2]来表示优先级;
 如果有32个级别,则寄存器中bit[2:0] = 0b000,即使用[7:3]来表示优先级;
 如果有16个级别,则寄存器中bit[3:0] = 0b0000,即使用[7:4]来表示优先级;

注意:imx6ull最多为32个级别

3. Binary Point Register, GICC_BPR

此寄存器用来把8位的优先级字段拆分为组优先级和子优先级,组优先级用来决定中断抢占。

位域读写描述
[31:3]-保留
[2:0]Binary pointR/W此字段的值控制如何将8bit中断优先级字段拆分为组优先级和子优先级,组优先级用来决定中断抢占。 更多信息还得看看GIC手册。

想象每个包裹(中断)贴着一个 ​​8位二进制紧急度标签​​(优先级字段,如0b10110011)。GICC_BPR寄存器相当于一把 ​​智能切割刀​​,它的作用是把这8位标签切成两部分:

  • ​前半段:组优先级(Group Priority)​​ → ​​决定能否插队​
    (比如标签前半段不同,高优先级的包裹可以直接抢过分拣机)
  • ​后半段:子优先级(Sub Priority)​​ → ​​决定同组内的排队顺序​
    (同一组内的包裹按后半段顺序处理)

​切割刀的使用说明书(寄存器结构)​

这把刀只有 ​​3个刻度按钮​​(对应寄存器的[2:0]位),其他区域都是固定死的([31:3]位保留无用):

███████████████████████████████ ▼ 刻度按钮 ███
[31.....................................3][2 1 0]
                 保留区域                   二进制点位置
​刻度按钮的作用(Binary Point值)​
  • ​数值范围​​:0-7(3位二进制能表示的数)
  • ​实际含义​​:切割刀在第几位后落下
    (比如刻度=3 → 前5位是组优先级,后3位是子优先级)

​举个实际切割案例​

假设现在有一个包裹的紧急度标签是 ​0b10110011​(十进制179):
1️⃣ ​​刻度设置为3​​(Binary Point=3)

  • 切割位置:第3位(从右往左数,第0位开始)
    → ​​组优先级​​:0b10110(前5位,十进制22)
    → ​​子优先级​​:0b011(后3位,十进制3)
  • ​效果​​:不同组的包裹可以互相抢占,同组的按子优先级排序

2️⃣ ​​刻度设置为5​​(Binary Point=5)

  • 切割位置:第5位
    → ​​组优先级​​:0b101(前3位,十进制5)
    → ​​子优先级​​:0b10011(后5位,十进制19)
  • ​效果​​:组划分更粗粒度,更多包裹可能属于同一组,减少抢占次数

​为什么需要这把刀?​

就像快递分拣中心需要动态调整插队规则:

  • ​高抢占模式​​(刻度值小):
    → 组优先级位数多 → 分组更细致 → 更多包裹能插队
    (适合医院急救物资运输,紧急任务频繁的场景)

  • ​低抢占模式​​(刻度值大):
    → 组优先级位数少 → 分组更粗略 → 系统更稳定
    (适合普通物流,减少频繁插队导致的分拣机卡顿)


​操作指南​

  1. ​开机初始化​​:根据业务需求设置切割刻度(比如刻度=3)
    // 代码示例:设置二进制点为3
    GICC_BPR = 3;  // 写入[2:0]位
  2. ​动态调整​​:若发现系统频繁被中断打乱,可调大刻度值减少分组数量
  3. ​保留位警告​​:其他按钮([31:3]位)严禁乱按,可能导致分拣机故障!

通过这把“切割刀”,操作系统就像分拣中心主管,能灵活控制中断插队的精细度,平衡系统响应速度和稳定性。✂️🚚

4. Interrupt Acknowledge Register, GICC_IAR

CPU读此寄存器,获得当前中断的interrtup ID。

位域读写描述
[31:13]-保留
[12:10]CPUIDR对于SGI类中断,它表示谁发出了中断。例如,值为3表示该请求是通过对CPU interface 3上的GICD_SGIR的写操作生成的。
[9:0]Interrupt IDR中断ID

5. Interrupt Register, GICC_EOIR

写此寄存器,表示某中断已经处理完毕。GICC_IAR的值表示当前在处理的中断,把GICC_IAR的值写入GICC_EOIR就表示中断处理完了。

位域读写描述
[31:13]-保留
[12:10]CPUIDW对于SGI类中断,它的值跟GICD_IAR. CPUID的相同。
[9:0]EOIINTIDW中断ID,它的值跟GICD_IAR里的中断ID相同

1.3 GIC编程

使用cortex A7处理器的芯片,一般都是使用GIC v2的中断控制器。 处理GIC的基地址不一样外,对GIC的操作都是一样的。 在NXP官网可以找到IMX6ULL的SDK包。 下载后可以参考这个文件:core_ca7.h,里面含有GIC的初始化代码。

10_实战_GPIO中断编程(IMX6ULL)

GPIO中断编程

目的:实现KEY2中断,按下、松开按键,串口输出相应信息。

1.1 先看原理图

  • 100ASK IMX6ULL按键原理图

  • 我们使用KEY2来演示中断的处理(它更复杂一点)

  • 课后作业:实现KEY1的中断处理函数。

  • KEY2用的是GPIO04_IO14引脚

1.2 IMX6ULL的GPIO中断

IMX6ULL的GPIO中断在硬件上的框架,跟STM32MP157是类似的。 IMX6ULL中没有EXTI控制器,对GPIO的中断配置、控制,都在GPIO模块内部实现:

1.2.1 GPIO控制器

1. 配置GPIO中断

每组GPIO中都有对应的GPIOx_ICR1、GPIOx_ICR2寄存器(interrupt configuration register )。 每个引脚都可以配置为中断引脚,并配置它的触发方式:

整体比喻​

这个寄存器相当于 ​​16条快递传送带的触发规则控制面板​​,每条传送带(对应GPIO的16个输入引脚)有 ​​4种触发模式​​,比如:

  • ​包裹静止不动时报警​​(低电平触发)
  • ​包裹被举起时报警​​(高电平触发)
  • ​包裹刚放上传送带时报警​​(上升沿触发)
  • ​包裹刚离开传送带时报警​​(下降沿触发)

​控制面板结构​

1️⃣ ​​面板布局(寄存器位结构)​
  • ​总共有32个开关位​​(从31到0位),但 ​​每2个位控制一条传送带​
    • ​举例​​:
      • 传送带15 → 31-30位(ICR15)
      • 传送带0 → 1-0位(ICR0)
  • ​复位值全0​​:所有传送带默认关闭报警功能(就像感应器没通电)
2️⃣ ​​每条传送带的触发规则(2位字段的4种模式)​

每个2位开关可以设置4种状态:

二进制值比喻场景实际含义
​00​​关掉感应器​中断禁用
​01​​包裹一碰到传送带就响​高电平触发
​10​​包裹刚被放上传送带时响​上升沿触发(从低到高的瞬间)
​11​​包裹刚被拿走时响​下降沿触发(从高到低的瞬间)

​实际操作指南​

​场景1:设置传送带5的触发规则​

假设想让 ​​传送带5​​(对应ICR5,占用11-10位)在 ​​包裹刚被放上时报警​​:
1️⃣ ​​计算二进制值​​:

  • 选择模式 ​​10​​(上升沿触发)
    2️⃣ ​​写入寄存器​​:
  • 将11-10位的值改为 0b10
// 代码示例(假设基地址为0x4000)  
*(volatile uint32_t*)(0x4000 + 0xICR1偏移) |= (0b10 << 10);  
​场景2:关闭传送带15的报警​

将31-30位(ICR15)设为 00

// 清空31-30位  
*(volatile uint32_t*)(0x4000 + 0xICR1偏移) &= ~(0b11 << 30);  

​注意事项​

1️⃣ ​​不要乱按其他按钮​​(保留位):

  • 图中灰色区域(如位16-31中未被ICR占用的部分)是预留位,随意修改可能导致传送带混乱!

2️⃣ ​​复位状态全0​​:

  • 系统重启后所有传送带默认关闭报警,需要重新设置触发模式

​为什么需要这个设计?​

就像快递中心需要灵活管理不同包裹的警报规则:

  • ​紧急包裹​​(如易碎品):设置为 ​​上升沿触发​​(刚放上就优先处理)
  • ​普通包裹​​:设置为 ​​下降沿触发​​(离开时才统计数量)
  • ​维护模式​​:直接关闭所有报警(设为00)

通过这个「触发感应器控制面板」,操作系统可以像调度员一样,精细控制每个GPIO引脚的中断触发条件,让硬件资源高效协作! 📦🚨

2. 使能GPIO中断

3. 判断中断状态、清中断

1.2.2 GIC

ARM体系结构定义了通用中断控制器(GIC),该控制器包括一组用于管理单核或多核系统中的中断的硬件资源。GIC提供了内存映射寄存器,可用于管理中断源和行为,以及(在多核系统中)用于将中断路由到各个CPU核。它使软件能够屏蔽,启用和禁用来自各个中断源的中断,以(在硬件中)对各个中断源进行优先级排序和生成软件触发中断。它还提供对TrustZone安全性扩展的支持。GIC接受系统级别中断的产生,并可以发信号通知给它所连接的每个内核,从而有可能导致IRQ或FIQ异常发生。

GIC比较复杂,下一个视频再详细讲解。

1.2.3 CPU

CPU的CPSR寄存器中有一位:I位,用来使能/禁止中断。

可以使用以下汇编指令修改I位:

   CPSIE I  ; 清除I位,使能中断
   CPSID I  ; 设置I位,禁止中断
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值