历史上的今天
返回首页

历史上的今天

今天是:2024年10月27日(星期日)

正在发生

2021年10月27日 | Linux之ARM Cortex-A7 中断系统详解

2021-10-27 来源:eefocus

1、中断是什么?

中断系统是一个处理器重要的组成部分,中断系统极大的提高了 CPU 的执行效率


2、STM32中断系统和 Cortex-M(STM32)中断系统的异同

STM32 的中断系统主要有以下几个关键点:


①、 中断向量表。

②、 NVIC(内嵌向量中断控制器)。

③、 中断使能。

④、 中断服务函数。


2.1、中断向量表

中断向量表是一个表,这个表里面存放的是中断向量。中断服务程序的入口地址或存放中断服务程序的首地址成为中断向量,因此中断向量表是一系列中断服务程序入口地址组成的表。这些中断服务程序(函数)在中断向量表中的位置是由半导体厂商定好的,当某个中断被触发以后就会自动跳转到中断向量表中对应的中断服务程序(函数)入口地址处。中断向量表在整个程序的最前面,比如 STM32F103 的中断向量表如下所示:


  __Vectors DCD __initial_sp ; Top of Stack

DCD Reset_Handler      ; Reset Handler

DCD NMI_Handler ; NMI Handler

DCD HardFault_Handler ; Hard Fault Handler

DCD MemManage_Handler ; MPU Fault Handler

DCD BusFault_Handler ; Bus Fault Handler

DCD UsageFault_Handler   ; Usage Fault Handler

DCD 0 ; Reserved

DCD 0 ; Reserved

DCD 0 ; Reserved

DCD 0 ; Reserved

DCD SVC_Handler ; SVCall Handler

DCD DebugMon_Handler ; Debug Monitor Handler

DCD 0 ; Reserved

DCD PendSV_Handler ; PendSV Handler

DCD SysTick_Handler ; SysTick Handler

External Interrupts

DCD WWDG_IRQHandler ; Window Watchdog

DCD PVD_IRQHandler ; PVD through EXTI Line detect

DCD TAMPER_IRQHandler ; Tamper

DCD RTC_IRQHandler ; RTC

DCD FLASH_IRQHandler ; Flash

/* 省略掉其它代码 */

DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & l5


上表就是 STM32F103 的中断向量表,中断向量表都是链接到代码的最前面,比如一般 ARM 处理器都是从地址 0X00000000 开始执行指令的,那么中断向量表就是从 0X00000000 开始存放的。上表中第 1 行的“__initial_sp”就是第一条中断向量,存放的是栈顶指针,接下来是第 2 行复位中断复位函数 Reset_Handler 的入口地址,依次类推,直到第 27 行的最后一个中断服务函数 DMA2_Channel4_5_IRQHandler 的入口地址,这样 STM32F103 的中断向量表就建好了。


我们说 ARM 处理器都是从地址 0X00000000 开始运行的,但是我们学习 STM32 的时候代码是下载到 0X8000000 开始的存储区域中。因此中断向量表是存放到 0X8000000 地址处的,而不是 0X00000000,这样不是就出错了吗?为了解决这个问题, Cortex-M 架构引入了一

个新的概念——中断向量表偏移,通过中断向量表偏移就可以将中断向量表存放到任意地址处,中断向量表偏移配置在函数 SystemInit 中完成,通过向 SCB_VTOR 寄存器写入新的中断向量表首地址即可,代码如下所示:


void SystemInit (void)

{

RCC->CR |= (uint32_t)0x00000001;

/* 省略其它代码 */

#ifdef VECT_TAB_SRAM

SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;

#else

SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;

#endif

}


第 8 行和第 10 行就是设置中断向量表偏移,第 8 行是将中断向量表设置到 RAM 中,第10 行是将中断向量表设置到 ROM 中,基本都是将中断向量表设置到 ROM 中,也就是地址0X8000000 处。第 10 行用到了 FALSH_BASE 和 VECT_TAB_OFFSET,这两个都是宏,定义如下所示:


#define FLASH_BASE ((uint32_t)0x08000000)

#define VECT_TAB_OFFSET 0x0


因此第 10 行的代码就是: SCB->VTOR=0X080000000,中断向量表偏移设置完成。


STM32中断向量表和中断向量偏移和I.MX6U中断向量表和中断向量偏移的关系?


I.MX6U 所使用的 Cortex-A7 内核也有中断向量表和中断向量表偏移,而且其含义和 STM32 是一模一样的!只是用到的寄存器不同而已,概念完全相同。


2.2、NVIC(内嵌向量中断控制器)

中断系统得有个管理机构,对于 STM32 这种 Cortex-M 内核的单片机来说这个管理机构叫做 NVIC,全称叫做 Nested Vectored Interrupt Controller。关于 NVIC 本教程不作详细的讲解,既然 Cortex-M 内核有个中断系统的管理机构—NVIC,那么 I.MX6U 所使用的 Cortex-A7 内核是不是也有个中断系统管理机构?答案是肯定的,不过 Cortex-A 内核的中断管理机构不叫做NVIC,而是叫做 GIC,全称是 general interrupt controller。


2.3、中断使能

要使用某个外设的中断,肯定要先使能这个外设的中断,以 STM32F103 的 PE2 这个 IO 为例,假如我们要使用 PE2 的输入中断肯定要使用如下代码来使能对应的中断:


NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道

NVIC_Init(&NVIC_InitStructure);


上述代码就是使能 PE2 对应的 EXTI2 中断,同理,如果要使用 I.MX6U 的某个中断的话也需要使能其对应的中断。


2.4、中断服务函数

我们使用中断的目的就是为了使用中断服务函数,当中断发生以后中断服务函数就会被调用,我们要处理的工作就可以放到中断服务函数中去完成。同样以 STM32F103 的 PE2 为例,其中断服务函数如下所示:


/* 外部中断 2 服务程序 */

void EXTI2_IRQHandler(void)

{

/* 中断处理代码 */

}


当PE2 引脚的中断触发以后就会调用其对应的中断处理函数 EXTI2_IRQHandler,我们可以在函数 EXTI2_IRQHandler 中添加中断处理代码。同理, I.MX6U 也有中断服务函数,当某个外设中断发生以后就会调用其对应的中断服务函数。


3、Cortex-A7 中断系统详解

3.1、Cortex-A7 中断系统简介

跟 STM32 一样, Cortex-A7 也有中断向量表,中断向量表也是在代码的最前面。 CortexA7 内核有 8 个异常中断,这 8 个异常中断的中断向量表如下表所示:

image.png?imageView2/2/w/550

中断向量表里面都是中断服务函数的入口地址,因此一款芯片有什么中断都是可以从中断向量表看出来的。从上表中可以看出, Cortex-A7 一共有 8 个中断,而且还有一个中断向量未使用,实际只有 7 个中断。和“示例代码的 STM32F103 中断向量表比起来少了很多!难道一个能跑 Linux 的芯片只有这 7 个中断?明显不可能的!那类似 STM32 中的EXTI9_5_IRQHandler、 TIM2_IRQHandler 这样的中断向量在哪里? I2C、 SPI、定时器等等的中断怎么处理呢?这个就是 Cortex-A 和 Cotex-M 在中断向量表这一块的区别,对于 Cortex-M 内核来说,中断向量表列举出了一款芯片所有的中断向量,包括芯片外设的所有中断。对于 CotexA 内核来说并没有这么做,在上表中有个 IRQ 中断, Cortex-A 内核 CPU 的所有外部中断都属于这个 IQR 中断,当任意一个外部中断发生的时候都会触发 IRQ 中断。在 IRQ 中断服务函数里面就可以读取指定的寄存器来判断发生的具体是什么中断,进而根据具体的中断做出相应的处理。这些外部中断和 IQR 中断的关系如图 所示:

外部中断和 IRQ 中断关系

在上图中,左侧的 Software0_IRQn~PMU_IRQ2_IRQ 这些都是 I.MX6U 的中断,他们都属于 IRQ 中断。当图左侧这些中断中任意一个发生的时候 IRQ 中断都会被触发,所以我们需要在 IRQ 中断服务函数中判断究竟是左侧的哪个中断发生了,然后再做出具体的处理。


在 中断系统表中一共有 7 个中断,简单介绍一下这 7 个中断:

在上面的 7 个中断中,我们常用的就是复位中断和 IRQ 中断,所以我们需要编写这两个中

断的中断服务函数。


首先我们要根据表 的内容来创建中断向量表,中断向量表处于程序最开始的地方,比如我们前面例程的 start.S 文件最前面,中断向量表如下:


.global _start /* 全局标号 */


_start:

ldr pc, =Reset_Handler /* 复位中断 */

ldr pc, =Undefined_Handler /* 未定义指令中断 */

ldr pc, =SVC_Handler /* SVC(Supervisor)中断 */

ldr pc, =PrefAbort_Handler /* 预取终止中断 */

ldr pc, =DataAbort_Handler /* 数据终止中断 */

ldr pc, =NotUsed_Handler /* 未使用中断 */

ldr pc, =IRQ_Handler /* IRQ 中断 */

ldr pc, =FIQ_Handler /* FIQ(快速中断)未定义中断 */


/* 复位中断 */

Reset_Handler:

/* 复位中断具体处理过程 */


/* 未定义中断 */

 Undefined_Handler:

ldr r0, =Undefined_Handler

bx r0


/* SVC 中断 */

SVC_Handler:

ldr r0, =SVC_Handler

bx r0


/* 预取终止中断 */

PrefAbort_Handler:

ldr r0, =PrefAbort_Handler

bx r0


/* 数据终止中断 */

DataAbort_Handler:

ldr r0, =DataAbort_Handler

bx r0


/* 未使用的中断 */

NotUsed_Handler:


ldr r0, =NotUsed_Handler

bx r0


 /* IRQ 中断!重点!!!!! */

IRQ_Handler:

/* 复位中断具体处理过程 */


FIQ_Handler:

ldr r0, =FIQ_Handler

bx r0


第 4 到 11 行是中断向量表,当指定的中断发生以后就会调用对应的中断复位函数,比如复位中断发生以后就会执行第 4 行代码,也就是调用函数 Reset_Handler,函数 Reset_Handler就是复位中断的中断复位函数,其它的中断同理。


第 14 到 50 行就是对应的中断服务函数,中断服务函数都是用汇编编写的,我们实际需要编写的只有复位中断服务函数 Reset_Handler 和 IRQ 中断服务函数 IRQ_Handler,其它的中断本教程没有用到,所以都是死循环。在编写复位中断复位函数和 IRQ 中断服务函数之前我们还需要了解一些其它的知识,否则的话就没法编写。


3.2、GIC 控制器简介

3.2.1、 GIC 控制器总览

I.MX6U(Cortex-A)的中断控制器叫做 GIC


GIC 是 ARM 公司给 Cortex-A/R 内核提供的一个中断控制器,类似 Cortex-M 内核中的NVIC。目前 GIC 有 4 个版本:V1~V4, V1 是最老的版本,已经被废弃了。 V2~V4 目前正在大量的使用。 GIC V2 是给 ARMv7-A 架构使用的,比如 Cortex-A7、 Cortex-A9、 Cortex-A15 等,V3 和 V4 是给 ARMv8-A/R 架构使用的,也就是 64 位芯片使用的。 I.MX6U 是 Cortex-A 内核的,因此我们主要讲解 GIC V2。 GIC V2 最多支持 8 个核。 ARM 会根据 GIC 版本的不同研发出不同的 IP 核,那些半导体厂商直接购买对应的 IP 核即可,比如 ARM 针对 GIC V2 就开发出了 GIC400 这个中断控制器 IP 核。当 GIC 接收到外部中断信号以后就会报给 ARM 内核,但是ARM 内核只提供了四个信号给 GIC 来汇报中断情况: VFIQ、 VIRQ、 FIQ 和 IRQ,他们之间的关系如图所示:

在上图中, GIC 接收众多的外部中断,然后对其进行处理,最终就只通过四个信号报给 ARM 内核,这四个信号的含义如下:


VFIQ:虚拟快速 FIQ。

VIRQ:虚拟快速 IRQ。

FIQ:快速中断 IRQ。

IRQ:外部中断 IRQ

本博文我们只使用 IRQ,所以相当于 GIC 最终向 ARM 内核就上报一个 IRQ信号。那么 GIC 是如何完成这个工作的呢? GICV2 的逻辑图如图下所示:

图中左侧部分就是中断源,中间部分就是 GIC 控制器,最右侧就是中断控制器向处理器内核发送中断信息。我们重点要看的肯定是中间的 GIC 部分, GIC 将众多的中断源分为分为三类:


①、 SPI(Shared Peripheral Interrupt),共享中断,顾名思义,所有 Core 共享的中断,这个是最常见的,那些外部中断都属于 SPI 中断(注意!不是 SPI 总线那个中断) 。比如按键中断、串口中断等等,这些中断所有的 Core 都可以处理,不限定特定 Core。


②、 PPI(Private Peripheral Interrupt),私有中断,我们说了 GIC 是支持多核的,每个核肯定有自己独有的中断。这些独有的中断肯定是要指定的核心处理,因此这些中断就叫做私有中断。


③、 SGI(Software-generated Interrupt),软件中断,由软件触发引起的中断,通过向寄存器GICD_SGIR 写入数据来触发,系统会使用 SGI 中断来完成多核之间的通信。


3.2.2、中断 ID

中断源有很多,为了区分这些不同的中断源肯定要给他们分配一个唯一 ID,这些 ID 就是中断 ID。每一个 CPU 最多支持 1020 个中断 ID,中断 ID 号为 ID0~ID1019。这 1020 个 ID 包含了 PPI、 SPI 和 SGI,那么这三类中断是如何分配这 1020 个中断 ID 的呢?这 1020 个 ID 分配如下:


ID0~ID15:这 16 个 ID 分配给 SGI。

ID16~ID31:这 16 个 ID 分配给 PPI。

ID32~ID1019:这 988 个 ID 分配给 SP。

I.MX6U 的总共使用了 128 个中断 ID,加上前面属于 PPI 和 SGI 的 32 个 ID, I.MX6U 的中断源共有 128+32=160个,这 128 个中断 ID 对应的中断在《I.MX6ULL 参考手册》的“3.2 Cortex A7 interrupts”小节,中断源如表 所示:

image.png?imageView2/2/w/550

这里只列举了一小部分并没有给出 I.MX6U 完整的中断源


NXP 官方 SDK中的文件 MCIMX6Y2C.h,在此文件中定义了一个枚举类型 IRQn_Type,此枚举类型就枚举出了 I.MX6U 的所有中断,代码如下所示:


typedef enum IRQn {

  /* Auxiliary constants */

  NotAvail_IRQn                = -128,             /**< Not available device specific interrupt */


  /* Core interrupts */

  Software0_IRQn               = 0,                /**< Cortex-A7 Software Generated Interrupt 0 */

  Software1_IRQn               = 1,                /**< Cortex-A7 Software Generated Interrupt 1 */

  Software2_IRQn               = 2,                /**< Cortex-A7 Software Generated Interrupt 2 */

  Software3_IRQn               = 3,                /**< Cortex-A7 Software Generated Interrupt 3 */

  Software4_IRQn               = 4,                /**< Cortex-A7 Software Generated Interrupt 4 */

  Software5_IRQn               = 5,                /**< Cortex-A7 Software Generated Interrupt 5 */

  Software6_IRQn               = 6,                /**< Cortex-A7 Software Generated Interrupt 6 */

  Software7_IRQn               = 7,                /**< Cortex-A7 Software Generated Interrupt 7 */

  Software8_IRQn               = 8,                /**< Cortex-A7 Software Generated Interrupt 8 */

  Software9_IRQn               = 9,                /**< Cortex-A7 Software Generated Interrupt 9 */

  Software10_IRQn              = 10,               /**< Cortex-A7 Software Generated Interrupt 10 */

  Software11_IRQn              = 11,               /**< Cortex-A7 Software Generated Interrupt 11 */

  Software12_IRQn              = 12,               /**< Cortex-A7 Software Generated Interrupt 12 */

  Software13_IRQn              = 13,               /**< Cortex-A7 Software Generated Interrupt 13 */

  Software14_IRQn              = 14,               /**< Cortex-A7 Software Generated Interrupt 14 */

推荐阅读

史海拾趣

Herotek Inc公司的发展小趣事

在电子元件的制造过程中,粘接技术是关键环节之一。Henkel凭借其深厚的技术积累和创新能力,在电子元件粘接领域取得了显著成就。其研发的粘合剂产品具有优异的粘接强度、耐温性能和耐化学腐蚀性能,能够满足各种复杂工况下的使用需求。例如,在汽车电子领域,Henkel的粘合剂产品被广泛应用于传感器、控制器等关键部件的粘接固定中,确保了汽车电子系统的稳定性和可靠性。

Helium_Systems__Inc.公司的发展小趣事

在20世纪90年代初,一家名为“海曼电子”(虚构名称,类似HEIMANN发音)的初创公司在德国慕尼黑成立。创始人海曼博士凭借其在半导体材料领域的深厚研究背景,带领团队成功研发出了一种新型高效能传感器芯片。这种芯片在温度测量领域表现出色,迅速获得了市场的认可。随着技术的不断迭代,海曼电子逐渐在传感器市场占据了一席之地,并通过持续的技术创新,将产品线扩展至光电子、汽车电子等多个领域。

Banner Engineering公司的发展小趣事

随着电子行业的快速发展,Banner Engineering公司意识到必须不断进行技术升级和产品创新,以满足市场的不断变化。因此,公司加大了研发投入,不断推出新的传感器技术和产品。其中,公司的光电传感器、激光测距仪等产品在市场上表现突出,成为行业的领先产品。同时,公司还拓展了产品线,涵盖了视觉系统、安全光幕等多个领域,进一步增强了公司的市场竞争力。

CONTRINEX公司的发展小趣事

自1972年在瑞士成立以来,Contrinex便踏上了成为全球传感器行业领军企业的征程。起初,公司专注于开发工业用的位置判定传感器,凭借其卓越的技术和精准的性能,很快便在市场上崭露头角。随着技术的不断进步和市场的不断扩大,Contrinex逐渐将业务拓展至全球60多个国家,旗下拥有500多名优秀员工,成为一家真正的国际化企业。

Component Research Co公司的发展小趣事

在电子行业中,环保问题日益受到关注。Component Research Co积极响应环保号召,将环保理念融入产品研发和生产过程中。公司采用环保材料、推行节能减排措施、加强废弃物处理等,努力降低生产过程中的环境污染。这些举措不仅提升了公司的社会形象,还为公司赢得了更多客户的青睐。

Frequency Sources公司的发展小趣事

为了满足不同客户的需求,Frequency Sources公司不断丰富产品线,推出了包括晶体振荡器、温补晶振、压控晶振等在内的多种频率源产品。同时,公司还加强了与上下游企业的合作,通过产业链整合实现了资源的优化配置和成本的降低。这种产品多样化和产业链整合的策略不仅提升了公司的综合竞争力,还为客户提供了更加全面和优质的解决方案。

问答坊 | AI 解惑

铃流源电路的新设计

  摘要:阐述三种新型铃流源电路的工作原理,分析它们的性能与特点,并依据上述原理,设计出具体的实用电路。 关键词:阶梯波文氏电桥振荡器SPWM解调器   铃流源又称铃流信号发生器,它是一种特殊形式的电源。在通信交换设备中,铃流源为 ...…

查看全部问答>

数字控制挑战传统电源设计理念

电源设计之初所要求的基本决定之一是:采用电压模式控制(VMC)还是采用电流模式控制(CMC)。对任何设计而言,交易存在于两个执行方法之间。然而,由于数字控制方法的引入,这些已被尝试并值得信赖的交易正面临着严峻挑战。本文将研究这条绘制的主线, ...…

查看全部问答>

很好的超声波设计资料

很好的超声波设计资料…

查看全部问答>

protel快捷键

1. 在新建的PCB里,按\"O\"-\"O\"(Option-color)快捷键,设置PCB各层(Layer)的颜色: 设置层颜色的三个原则:① 接近自然,看起来很舒服;② 颜色分明,不易混淆;③ 长时 间画板,眼睛不易疲劳。 我的设置例子: TopLayer: 222 \'接近绿油的颜 ...…

查看全部问答>

七月份嵌入式 和“间谍门”热点,八月份要看可再生能源

      七月南非世界杯结束了,北京是骄阳似火,闷热闷热的桑拿天 ,南方 ,西部和东北暴雨台风。 七月份嵌入式和“间谍门”是热点。各大芯片原厂和嵌入式产品制造商在物联网概念里必定谈到嵌入式。俄罗斯美女” ...…

查看全部问答>

需要32位定时器,主要是如果需要电机速度很慢的话。

16位--65536不够用。32位4294967296正好。一般都不要分频了。 对STM32的16位级联不了解,知道的大侠说说。 我只是特例啊。希望STM32出32位定时,和32位PWM... 友好讨论,拒绝抬杠。呵呵。…

查看全部问答>

AVR16 如何把产生的波形 在12864上面显示出来?

最近打算做个示波器, 但是把波形显示在12864上面  没想到好的方法   有大侠做过么?  望指点一二  谢谢~~~~…

查看全部问答>

哪位朋友了解Vishay的光学传感器VCNL4010?

本帖最后由 jameswangsynnex 于 2015-3-3 20:03 编辑        有利于客户减少在软件上花的功夫,避免在传感器和微控制器之间产生轮询通信流量,降低功耗的光学传感器VCNL4010。VCNL4010将用于接近探测的红外发射器和 ...…

查看全部问答>