IMX6LL|中断详解

一.通用中断控制器(GIC)

1.概念

通用中断控制器(General Interrupt Controller,GIC)是一种硬件设备,通常用于处理多核处理器或多处理器系统中的中断。

GIC 负责接收来自各个设备和处理器内核的中断信号,并根据优先级和配置规则将这些中断分派给适当的处理器核心进行处理。

GIC 的工作原理如下:

  1. 中断请求:外设或处理器核心会向 GIC 发送中断请求信号,表示产生了一个中断。

  2. 中断分发:GIC 根据中断请求的类型、优先级和配置规则,决定将中断分派给哪个处理器核心进行处理。GIC 使用一种称为中断向量表的数据结构来维护中断请求和处理器的映射关系。

  3. 中断响应:被选中的处理器核心会接收到中断信号,并开始执行中断处理程序(ISR),该程序用于处理特定的中断请求。

  4. 中断处理:中断处理程序会执行必要的操作来响应中断请求,例如保存当前上下文、处理中断逻辑、清除中断标志等。

  5. 中断返回:中断处理程序执行完毕后,处理器核心会将处理器状态恢复到中断前的状态,然后从中断返回到原始的执行流程。

GIC 是一个灵活且可配置的中断控制器,可以根据系统的需求进行定制和扩展。它在多核处理器、多处理器系统和嵌入式系统中广泛使用,提供了一种可靠且高效的中断处理机制。

2.结构

2.1三类信号源:

  • 软件中断:用于多核通信,ID0~ID15
  • 私有中断:内核独有的中断,ID16~ID31
  • 共享中断:所有内核共享的中断,ID32~ID1019(常用)

当涉及到多核通信时,GIC(通用中断控制器)的软件中断、私有中断和共享中断是重要的概念。

  1. GIC软件中断(ID0~ID15):这些中断用于多核通信。每个处理器核心都可以通过软件中断发送中断请求给其他核心。通过设置特定的软件中断ID,发送核心可以向接收核心传递消息或任务。软件中断提供了一种高效的多核通信机制,可以用于实现同步、任务协作等。

  2. 私有中断(ID16~ID31):这些中断是内核独有的,每个内核具有独立的中断号空间。每个内核可以为自己的特定事件或任务分配私有中断,并使用对应的中断号。这些中断不与其他内核共享,因此可以为各自的需求和场景定制中断处理程序。

  3. 共享中断(ID32~ID1019):这些中断是所有内核共享的,多个内核可以同时监听和响应这些中断。共享中断使用较大的中断号空间,允许多个内核在同一中断上注册中断处理程序。这些中断通常用于处理系统级别的事件,如定时器中断、设备中断等。

总而言之,GIC的软件中断、私有中断和共享中断是用于实现多核通信和中断处理的重要机制。软件中断用于核间通信,私有中断用于处理核内特定事件,而共享中断则用于处理系统级别的共享事件。这些中断提供了一种可靠高效的方式来协调和管理多核系统中的任务执行和资源共享。

2.2分发器(GICD):

选择把中断信号发送到哪一个cpu接口单元

GIC(通用中断控制器)分发器是一个硬件模块,用于接收和分发中断请求到处理器核心。它是多核系统中的关键组件,负责管理中断的分配和处理。

GIC分发器的主要功能如下:

  1. 中断请求接收:GIC分发器通过外部连接或内部总线接收来自各种外设和内部模块的中断请求信号。这些中断请求可以是来自设备的硬件中断、软件发送的中断请求、或其他触发中断的事件。

  2. 中断分发:GIC将接收到的中断请求分配给对应的处理器核心。它根据中断类型、优先级和其他配置参数来确定中断应该被发送到哪个核心。对于共享中断,GIC分发器可能会将中断请求发送给多个处理器核心。

  3. 中断优先级管理:GIC分发器根据每个中断的优先级,按照特定的中断控制规则来决定中断的处理顺序。它可以确保高优先级中断在低优先级中断前得到处理,并在需要时执行中断抢占。

  4. 中断控制和屏蔽:GIC分发器允许软件对中断进行控制和屏蔽。它提供了一组寄存器,用于配置和管理中断的使能状态、优先级、中断屏蔽等。

  5. 中断处理广播:对于共享中断,GIC分发器会将中断广播给所有相关处理器核心。这确保了所有核心都能接收到共享中断请求,并进行相应的中断处理。

  6. 中断处理确认和反馈:GIC分发器会在中断请求被处理完毕后,向触发中断的设备发送确认和反馈信号,以通知设备中断已被处理。

总的来说,GIC分发器在多核系统中起到了中断请求的接收、分配和管理的关键作用。它确保了中断的正确分发和处理,实现了高效的中断处理机制,提高了系统的性能和可靠性。

有哪些相关寄存器?

  • 中断数量:GICD_TYPER

  • 中断清除: GICD_ ICENABLERn

  • 中断使能:GICD_ISACTIVERn

  • 中断优先级设置:GICD_IPRIORITYR

2.3cpu接口单元GICC:

处理信号后,发送信号给CPU

有哪些相关寄存器?

  • 中断优先级数量:GICC_PMR
  • 抢占优先级和子优先级设置: GICC_BPR
  • 保存中断ID:GICC_IAR
  • 通知cpu中断完成:GICC_EOIR

3.获取GIC基地址

方法一:查询芯片数据手册

IMX6LL|中断详解_第1张图片

方法二:查询cp15协处理器

共有16个:c0~c15寄存器。每个协处理器本身有多种含义,需逐步配置,利用协处理器读取cp15的值。

MRC指令用于将数据从协处理器寄存器传输到ARM通用寄存器, MCR指令则用于将数据从ARM通用寄存器传输到协处理器寄存器。

//设置并读协处理器
MRC {cond} p15, , , , , 
//设置并写协处理器
MCR {cond} p15, , , , ,  
  • cond:执行条件,一般省略
  • p15:指定协处理器编号,p15代表系统控制协处理器(CP15)。
  • opc1:第一层设置
  • Rn:通用寄存器
  • CRn:要设置的协处理器
  • CRm:第二层设置
  • opc2:第三层设置

实际使用时,您需要替换这些参数为具体的数值或寄存器。例如,要从CP15的某个寄存器中读取数据,您可以使用以下指令:

MRC p15, 0, , c0, c0, 0

其中,是要存储读取结果的通用寄存器。

同样地,您可以使用MCR指令将数据写入CP15的寄存器。具体的指令使用方法和寄存器的编号取决于所使用的ARM处理器的架构和型号。因此,建议您查阅相关的ARM处理器技术参考手册或文档,以获取更具体的指令和寄存器信息。

IMX6LL|中断详解_第2张图片

1.配置成CBAR寄存器

CRn=c15,opc1=4,CRm=c0,opc2=0

  • 功能查询GIC的地址
MRC p15, 4, r1, c15, c0, 0 ;获取 GIC 基地址

2.配置成SCTLR 寄存器

CRn=c1,opc1=0,CRm=c0,opc2=0

IMX6LL|中断详解_第3张图片

  • bit13:中断向量表基地址

  • cache\mmu\分支预测…

    MRC p15, 0, , c1, c0, 0 ;读取 SCTLR 寄存器,数据保存到 Rt 中。
    MCR p15, 0, , c1, c0, 0 ;将 Rt 中的数据写到 SCTLR(c1)寄存器中。
    

3.配置成VBAR寄存器

CRn=c12,opc1=0,CRm=c0,opc2=0

IMX6LL|中断详解_第4张图片

  • bit5~31:中断向量表偏移地址
MRC p15, 0, , c12, c0, 0 ;读取 VBAR 寄存器,数据保存到 Rt 中。
MCR p15, 0, , c12, c0, 0 ;将 Rt 中的数据写到 VBAR寄存器中。

二.中断向量表

1.一级查表

i.MX6LL 是 i.MX6 系列 SoC 的一个特定变体。关于 i.MX6LL 的一级中断向量表,它通常位于设备的内存中,包含了一系列内存地址,这些地址对应不同的中断处理程序。表中的每个条目表示特定的中断来源及其对应的处理程序例程。中断向量表的确切布局和内容可能因具体实现和操作系统的不同而有所变化。

自动跳转指定位置(基址+偏移),确定中断类型,cpu进入指定模式运行。是系统固定的。

addr TYPE FUNCTION MODE
0x00 Reset 复位中断 SVC
0x04 Undefined instructions 未定义指令中断 Undef
0x08 Supervisor Call 软中断 SYC
0x0C Prefetch abort 指令预取中止中断 ABT
0x10 Data abort 数据访问中止中断 ABT
0x14 RESERVED 未使用 未使用
0x18 IRQ interrupt IRQ 中断 IRQ
0x1C FIQ interrupt FIQ 中断 FIQ

通过触发不同类型的中断,系统进入到相应的运行模式

IMX6LL|中断详解_第5张图片

IMX6LL|中断详解_第6张图片

2.二级中断函数

i.MX6LL SoC 的二级中断表(Nested Interrupt Controller,NIC)是用来管理和分发处理器的二级中断的数据结构。具体的二级中断表的布局和内容会根据具体的实现和操作系统有所不同。

一般而言,二级中断表是一个数组,每个数组元素对应一个二级中断的编号。每个元素保存了该二级中断的优先级、处理函数地址以及其他相关信息。当一个二级中断发生时,处理器会通过查找二级中断表,找到对应的处理函数并进行调用。

需要注意的是,i.MX6LL SoC 的具体二级中断表的信息最好通过参考相关的技术文档或者开发者手册来获取,以确保准确性和一致性。

预先注册、回调执行。当发生某个中断时,会自动执行该中断函数,可以自定义该中弄断函数。

IMX6LL|中断详解_第7张图片

三.中断处理流程

1.中断上下文

中断上下文(Interrupt Context)指的是在处理器执行中断发生时,需要保存和恢复的上下文信息。当中断发生时,处理器会立即转移到中断处理程序,但在执行中断处理程序之前,需要将当前正在执行的任务的上下文保存起来,以确保在中断处理完毕后能够正确地回到中断发生之前的执行状态。

中断上下文保存的内容通常包括处理器寄存器的值、程序计数器(PC)的值、中断标志位等与中断处理相关的信息。保存上下文的过程被称为中断的保存现场,而恢复上下文的过程则被称为中断的恢复现场。

保存和恢复中断上下文是处理中断的重要步骤,可以确保在中断处理完成后,处理器能够正确地回到原来的任务继续执行,而不会造成执行状态的混乱或数据的丢失。

中断上下文的具体保存方法和细节会根据不同的处理器架构和操作系统而有所不同,但核心思想是相似的:在中断发生时,保存当前的执行状态,执行中断处理程序,处理完毕后恢复之前的执行状态。这样可以确保中断处理是可靠和正确的。

cpu通过内核寄存器来运行指令并进行数据的读写处理的,它在进入中断前一个时刻的具体值,称为中断上下文

2.处理流程

2.1初始化irq模式栈指针

当上电时,会先触发复位中断,发生复位中断时,会先禁止IRQ中断模式,因为此时没有初始化和进去IRQ运行模式。我们用cpsr/cps寄存器进入IRQ运行模式。并将要保存的数据压入栈中。

在ARM架构中,CPSR(Current Program Status Register)是用来保存和控制处理器的当前执行状态的寄存器,而CPS(Control Program State)则是一个相关概念。

CPSR是一个32位的寄存器,其中包含了各种标志位、状态位和控制位,用于描述和控制处理器的当前状态。CPSR的不同位表示了不同的信息,比如条件标志位、执行模式、中断使能等。

CPS寄存器是一种更广义的概念,它包含了比CPSR更多的寄存器,用于描述和控制处理器的状态。除了CPSR,CPS还可能包含其他与执行状态相关的寄存器,例如SPSR(Saved Program Status Register)用于保存被中断前的程序状态。

总结来说,CPSR是ARM架构中用来保存和控制处理器当前执行状态的寄存器,而CPS是一个更广义的概念,它可能包含多个寄存器,用于描述和控制处理器的状态。

cpsr寄存器

  • bit31:负数标记位
  • bit30:零标志位
  • M[4:0]:运行模式控制位
    • 10000:User 模式
    • 10001:FIQ 模式
    • 10010:IRQ 模式
    • 10011:SVC模式
    • 10111:Abort模式
    • 11011:Undef模式
    • 11111:System模式
    • 10110:Monitor模式
    • 11010:Hyp模式
mrs ,cpsr //读cpsr
msr cpsr, //写cpsr
cps #xx //写立即数到cpsr中的M[4:0]

2.2保存现场

保护现场,主要是保存三类寄存器,分别是通用寄存器,lr寄存器,spsr寄存器。

lr寄存器

“LR” 通常在计算机体系结构中代表 “Link
Register”(链接寄存器)。链接寄存器是一个特殊的寄存器,用于存储函数调用的返回地址。

当一个函数调用另一个函数时,当前函数的返回地址需要保存,以便在被调用函数执行完成后能够回到正确的位置。链接寄存器就是用来存储这个返回地址的。

在函数调用过程中,调用指令(例如跳转指令)会将下一条指令的地址存储到链接寄存器中。这个地址就是当前函数被调用后要返回的位置。被调用的函数在执行完毕后,通过从链接寄存器中取出返回地址,将控制流恢复到调用者函数的正确位置。

链接寄存器还可以用于实现其他编程结构,如尾递归优化和异常处理等。

总结来说,LR(Link
Register)是一个寄存器,用于存储函数调用的返回地址。它在函数调用时保存返回地址,以便在函数执行完毕后能够正确返回到调用者函数的位置

spsr寄存器

“SPSR” 代表 “Saved Program Status Register”(保存程序状态寄存器)。在一些处理器体系结构中,SPSR
是一个特殊的寄存器,用于存储中断或异常处理程序执行之前的程序状态。

当处理器执行到中断或异常时,它会自动保存当前的程序状态,包括程序状态寄存器 (CPSR)
的值,以便在返回到中断或异常处理程序之后能够恢复正常的执行。

为了确保执行流的无缝切换,处理器会将当前程序状态的副本存储到 SPSR 中,然后将 CPSR
设置为处理中断或异常所需的状态。当中断或异常处理完成后,处理器可以使用 SPSR 中的值将 CPSR
还原为之前的状态,从而继续正常的执行流程。

SPSR 包含与 CPSR 相同的位字段,例如条件标志位、模式位和处理器状态位等。它的结构和具体位的含义可能因不同的处理器架构而有所不同。

总结来说,SPSR(Saved Program Status
Register)是一个特殊的寄存器,用于保存中断或异常处理程序执行之前的程序状态。它允许处理器在执行中断或异常处理程序后能够返回到之前的状态,从而实现无缝切换和正常的执行流程。注意spsr的读写要用mrc/mcr指令

2.3获取中断编号

中断编号保存在GICC_IAR寄存器,因此只需要从GICC_IAR寄存器中读取即可。但要找到其地址需要先找到GIC基地址。在找到GICC基地址,从而找到GICC_IAR寄存器,然后读取值。

(1.)读取GIC基地址

通过配置cp15协处理器进行获取GIC基地址。配置成CBAR寄存器

CRn=c15,opc1=4,CRm=c0,opc2=0

  • 功能查询GIC的地址
MRC p15, 4, r1, c15, c0, 0 ;获取 GIC 基地址

(2.)GICC基地址(GIC cpu interface)

获取GICC基地址只需要在 GIC 基地址的基础上,加上偏移量即可

(3.)GICC_IAR寄存器

获取GICC_IAR基地址只需要在 GICC基地址的基础上,加上偏移量即可

2.4执行中断处理函数

跳转到中断处理函数,进行中断处理,可以用栈传递参数。并且可以接收返回的中断编号。

2.5通知cpu,中断处理完成

将返回的中断编号写入GICC_EOIR

2.6还原现场

从栈中弹出原先压入的数据。恢复原先的数据即可。

2.7返回原程序

三级流水线是一种计算机处理器的流水线架构,用于提高处理器的执行效率。它将任务分为三个阶段(或称为段),每个阶段执行不同的指令操作。

这三个阶段通常是指取指(Fetch)、译码(Decode)和执行(Execute)。

  1. 取指(Fetch)阶段:从指令内存中读取指令,并将其加载到指令寄存器中。这个阶段主要负责获取下一条指令。

  2. 译码(Decode)阶段:将取得的指令进行解码,确定指令的类型和操作数。例如,确定是算术操作还是逻辑操作,以及要使用的寄存器或内存位置等。

  3. 执行(Execute)阶段:根据译码阶段解码的结果,执行指令的实际操作。这可能包括算术运算、逻辑运算、访问内存或修改寄存器等。

通过将处理器的执行任务分解为这三个独立的阶段,可以同时进行多个指令的执行,从而提高处理器的吞吐量和效率。每个阶段在同一时刻执行不同的指令,形成一个流水线,使得整个处理器能够在更短的时间内完成更多的指令。

除了三级流水线,还有其他流水线架构,比如五级流水线或甚至更多级别的流水线。不同级别的流水线在拆分指令执行阶段的细化程度上有所不同,但基本原理是相似的,即将指令执行过程分成多个阶段并并行执行,以提高处理器的效率。

subs pc, lr, #4				 @将lr-4赋给pc 

三.相关寄存器

3.1GCC相关寄存器

分发器

  • 中断数量:GICD_TYPER
  • 中断清除: GICD_ ICENABLERn
  • 中断使能:GICD_ISACTIVERn
  • 中断优先级设置:GICD_IPRIORITYR

详见GIC官方手册

4.3 Distributor register descriptions

  • cpu接口单元

    • 中断优先级数量:GICC_PMR
    • 抢占优先级和子优先级设置: GICC_BPR
    • 保存中断ID:GICC_IAR
    • 通知cpu中断完成:GICC_EOIR

    详见GIC官方手册

    4.4 CPU interface register descriptions

3.1GPIO中断相关寄存器

  • gpio中断触发类型:高/低电平、上升/下降沿

    • GPIO5_ICR1(0~15)

    • GPIO5_ICR2(16~31)

  • gpio中断屏蔽

    • GPIO5_IMR
  • gpio中断状态寄存器

    • GPIO5_ISR
  • gpio双边缘触发

    • GPIO5_EDGE_SEL

    详见芯片数据手册

    28.5 GPIO Memory Map/Register Definition

四.位置无关码和重定位

程序执行和变量访问的两种方式:

  • pc指针+偏移地址
  • 绝对地址
位置无关码

没有出现绝对地址访问的代码称为位置无关码

  • 普通.text段指令
  • 局部变量

位置无关码可以在任意合法内存运行

位置相关码

出现了绝对地址访问的代码称为位置相关码

  • 访问.data段:初始值非零的全局变量、静态变量

  • 访问.rodata段:字符串、具有初始值的数组

  • 访问.bss段:初始值为0的全局变量、静态变量

  • 特殊.text段指令

    汇编: ldr pc,=100000
    
    c语言:(*(void(*)(void))0x100000)();
    

位置相关码必须在指定运行地址运行

重定位

在执行位置相关码之前,可以通过位置无关代码把位置相关码加载到位置相关代码的指定位置,如重定位.data段

你可能感兴趣的:(嵌入式)