admin 发表于 2022-8-23 15:46:35

【zynq课程笔记】【裸机】【第13课 】【中断概念与中断控制器】

1.      什么是中断

本次课程呢,我们将带领大家一起学习Zynq 的GPIO中断的相关内容。
在第7课的学习中,我们是为大家介绍了GPIO的结构,而在介绍GPIO控制器的寄存器时候,提到其中有几个与中断相关的寄存器。
当时,在讲解GPIO控制器的时候我们说过,GPIO在检测到一些满足指定条件的信号状态后为了能通知CPU及时处理,可以产生中断请求。
那么,什么是GPIO的中断请求?什么样的信号变化才会导致GPIO发生中断请求呢?CPU又是怎样处理中断请求的。中断功能对于我们设计应用程序,又有怎样的优势呢。
要回答这些问题,我们首先要明白中断的概念。为了方便大家理解中断概念,我们先将自己的生活琐事带入为例,讲解几个实际的生活场景,通过类比来形象的展示中断的概念。

我们为什么需要使用中断,或者说中断存在的价值是什么呢?要回答这个问题,先看以下三个简单的生活场景:


场景1

假如,你正在Bilibili上看小梅哥FPGA的视频课程,非常认真的学习。突然间,你的女朋友给你打电话过来了,那么此刻,我想请问,你是继续看视频课程,还是马上接女朋友电话?相信在坐的各位,肯定都是选择第一时间接女朋友电话。为什么呢?因为重要,接女朋友电话,陪女朋友逛街这个事情,远比看fpga教学视频更重要,我相信这一点没有人反驳。你必须得立即接,不接怎么样,你就等着哄吧,是不是,那可比调FPGA代码更让人头秃。那么这也就是中断事件的第一个特征,紧迫性。


场景2

然后再看第二个场景:你正在家做饭,突然间有人敲门,此时,你不得不赶紧关火,然后去开门看看是谁找你。在这种场景下,有人敲门找你这个事情,是不是具有随机性?有可能你在家呆了一个月连手机都不响一下,也有可能你做个饭的功夫,来三波人查水表。所以,这也是中断事件的第二个特征:随机性。


场景3

然后我们再来看一下场景3,你下班/下课后正在家在Bilibili上看小梅哥FPGA视频课程(事件1)。
突然之间,你的手机响了,当你拿起手机一看,发现有三条推送消息:
第一条:你女朋友的发微信跟你说,说她感冒了
第二条:支付宝的推送,内容是说你这个月花呗该马上还了,这个时候你才想起来,上个月自己通过花呗的方式在淘宝上买了一套小梅哥的zynq开发板。
第三条:小区保安跟你发的消息,说你停在楼下的电瓶车电瓶被人偷了。让你赶紧下去看看。

面对这个复杂的场景,你的潜意识里面,认为哪件事情最重要?毫无疑问,肯定是女朋友感冒了嘛。电动车没了咱还可以走路上下班,花呗晚一点还也还是来得及,但是女朋友生病这个事情肯定不能耽误,所以你马上暂停了手机上的fpga视频的播放,然后在京东买了一个热水壶和几瓶上好的纯净水给女朋友寄过去,并嘱咐她多喝热水。
好了,处理完了女朋友的事情,接下来该干什么呢?是接着看视频呢,还是赶紧还花呗呢?还是说去看看电瓶车是不是自己的。这种情况下当然是电瓶车更重要对不对,所以你赶紧跑下楼看了下,保安问哪辆车是你的,说是小区里面好多电瓶车的电瓶都被偷了,你看了半天才突然想起来,自己连电动车都没有,每天都是骑共享单车上下班的。保安给每个住户都发了消息的。这下你心里就放心多了。
既然没自己的事,那就上楼呗,上楼之后,你打开支付宝,还了花呗。
还完花呗,接着打开手机看小梅哥fpga视频课程。

好了,介绍完了生活场景,我们再来看下关于计算机/处理器中断的相关定义,在百度百科中,对中断的定义是这样的:
“中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。”
从定义中,我们可以看到,中断,代表的是一个过程,是高优先级事件打断低优先级事件,抢夺CPU资源处理其他事情的过程。在处理完成后再返回处理低优先级事件的过程。

CPU就像一个人,同一时间只能做一件事情,但是无奈事有轻重缓急,为了让CPU能够合理的处理一些紧急或者随机事件。中断的方法就诞生了。

中断的第一大优点就是可以请求CPU立即停下当前主线正在做的事情,转而去处理其他事情,抢占CPU的资源。就像前面场景1中,在B站看小梅哥fpga教学视频是主线事情,而女朋友电话就是中断请求,你接电话,按女朋友的指导,做饭就是中断事件的任务。假如CPU也有女朋友的话,那么他点灯可能就是主线任务,而接到某个按键管脚产生的中断(女朋友打电话)后,他去控制继电器断开就属于中断任务。

中断的第二大优点是可以方便的处理一些随机出现的事情。这些随机出现的事情,可能并不常发生,比如CPU任务已经很重很复杂了,又要忙着采集数据数据,又要对数据进行FFT变换,还要在显示屏上绘制波形。整个CPU的主线任务很繁重或者说很复杂。但是又有某个不常发生的事件偶尔需要处理一下,比如某光电传感器输出引脚产生上升沿后,就把控制背光的pwm占空比减到最小。
中断的第三个特点就是各个中断事件之间有优先级,什么意思呢?就是说如果有多个事件的中断请求同时存在,当CPU来处理中断时,会优先处理高优先级的中断,当高优先级的中断处理完成之后,再去处理低优先级中断。比如我们前面讲的场景3中,收到催你还支付宝花呗的短信,和保安喊你,说你电瓶车电瓶被偷了,以及女朋友说肚子疼,就是3个几乎同时发生的中断事件,当你同时面对多个事情的时候,就需要根据自己的判断,按先后顺序处理各个事情。比如最紧急的,女朋友感冒了最优先,其次,就是电瓶车被偷了。再最后,才是还花呗。对于CPU来说也是,当打开某个重要的设备的继电器开关中断请求信号,和打开跑马灯功能的中断请求信号同时到来时,当然是要先开继电器开关,再开跑马灯了。这也就是中断的优先级概念。
这里,是以非常形象且扯淡的方法,给大家介绍了中断的相关概念。如果之前不了解的,听了课程之后,希望您能稍微有一点理解,如果之前已经懂了的,就当是听了几个段子。
了解了这些概念之后呀,我们就该回归我们课程的本质,学习如何让CPU正确的处理中断事务。
要掌握如何让CPU正确的处理中断事务,就需要先对CPU的中断结构有个清楚的了解。那么这个内容,我们放到下一节课,来给大家细说。、




2.      Zynq的中断结构

从中断事务的产生和处理过程的角度来说,中断结构会至少包括2个部分,一是一个或多个能够产生中断请求的中断源,比如GPIO、定时器、串口等,二是能够接受中断请求信号并作出相应处理的主机,也就是CPU。
我们知道,一个CPU一个时刻只能处理一个事情,这也就意味着,当多个中断请求同时存在时,CPU必须优先选择其中一个事件处理。而且,CPU本身只有一个中断输入端口。所以,需要有一个功能单元,能够预先决定,哪些中断源发出的中断请求直接忽略(屏蔽),哪些中断源的中断请求允许被处理(启用),哪些中断源的中断请求优先处理(优先级),该功能单元接收各个中断源的中断信号,并根据预先设定好的使能、禁止、优先级顺序,向CPU产生中断请求。这个就是通用中断控制器(Generic Interrupt Controller (GIC))




在ug585手册中,Xilinx官方给出了ZYNQ-7000系列的系统级中断架构(UG585::Chapter 7::Figure 7-1):



从图中可以看到,整个中断架构共分为以下三种中断:

[*]软件生成中断(Software Generated Interrupts,SGI)
[*]私有外设中断(Private Peripheral Interrupts,PPI)
[*]共享外设中断(Shared Peripheral Interrupts,SPI)

每种中断都各自包含特定的中断源,如: PPI包括全局定时器(global timer)、私有看门狗定时器(private timer)、私有定时器(private timer)和PL中的FIQ。SGI则是通过写入通用中断控制器(Generic Interrupt Controller,GIC)中的寄存器生成。SPI是由PS和PL中的各种I/O和内存控制器生成的。
对于一般的中低端CPU系统来说,上面的结构就足够实现中断的产生和处理功能了。但是,我们zynq的PS可不是一般的处理器系统,它是一个结构复杂,性能强劲的双核Cortex-A9处理器系统。其包含一级缓存L1 ,二级缓存L2,缓存能够提升CPU读写总线数据的性能。但是使用不当,也会造成CPU读写数据实时性的下降,甚至因为缓存一致性的问题,把一些已经由其他外设更新但是缓存中还是旧值的数据取用,从而产生错误。由于中断的实时性和重要性,中断控制器的相关寄存器的读写是不能因为缓存的存在而被延误的,所以CPU并不通过L2来访问GIC中的寄存器,而是通过一个名为窥探控制单元Snoop Control Unit(简称SCU),采用私有总线访问GIC的寄存器,以此来提升中断的处理效率。
The Interrupt Controller is memory-mapped. The Cortex-A9 processors access it by using a private interface through the SCU(出处Cortex-A9 MPCore Technical Reference Manual ::48页)



介绍完了CPU与GIC的通信情况,我们再来看看左侧的中断源相关的内容。以GPIO为例。GPIO属于PS侧的I/O外设(IOP)资源,因此,其产生的GPIO中断为SPI中断。GPIO中断以及其他各种类型中断都会被送到通用中断控制器也正是前面我们所说的GIC,随后交由GIC统一管理并分发到指定CPU处理。下图为中断控制器的结构框图(UG585::Chapter 7::Figure 7-2):



GIC是一种集中式资源,是联系中断和 CPU 的桥梁,也是各 CPU 之间中断互联的通道(也带有管理功能),它负责管理、分发从PS和PL发送到CPU的中断。当CPU接口接受下一个中断时,控制器启用、禁用、屏蔽中断源并确定其优先级,然后按照编程设定将它们发送给选定的CPU。

当然,并不是说所有的中断请求一发出都能立马被CPU处理。所有中断源都有唯一的中断标识号标识以及自己可配置的优先级和目标CPU列表。图中的中断分发器保存着每个CPU的挂起中断列表。它会集中所有的中断源,随后根据其优先级(优先级设置值越大,优先级越小),优先将高优先级的中断源分配给指定CPU处理,以确保针对多个CPU的中断一次只能由一个CPU处理。但是优先级逻辑在物理上是重复的,也就是说不同的中断也可以设置为同一优先级。对于这种情况,中断分发器会优先将中断标识号最低的中断源分配给CPU处理。
同时需要注意的一点是,zynq的中断触发方式有两种,一种是边沿触发,一种是电平触发。对于不同的中断源,中断触发方式的要求可能不同。以SPI中断为例,其各种中断源所要求的中断触发方式如下表(UG585::Chapter 7::Table 7-4):


中断源中断名中断ID#状态位触发类型PS-PL信号名I/O
APUCPU 1, 0 (L1, TLB, BTAC)33:32spi_status_0上升沿~~
L2 Cache34spi_status_0高电平~~
OCM35spi_status_0高电平~~
Reserved~36spi_status_0~~~
PMUPMU 38,37spi_status_0高电平~~
XADCXADC39spi_status_0高电平~~
DevCDevC40spi_status_0高电平~~
SWDTSWDT41spi_status_0上升沿~~
TimerTTC 044:42spi_status_0高电平~~
DMACDMAC Abort45spi_status_0高电平IRQP2F输出
DMAC 49:46spi_status_0高电平IRQP2F输出
MemorySMC50spi_status_0高电平IRQP2F输出
Quad SPI51spi_status_0高电平IRQP2F输出
Reserved~~~始终低电平驱动IRQP2F输出
IOPGPIO52spi_status_0高电平IRQP2F输出
USB 053spi_status_0高电平IRQP2F输出
Ethernet 054spi_status_0高电平IRQP2F输出
Ethernet 0 Wake-up55spi_status_0上升沿IRQP2F输出
SDIO 056spi_status_0高电平IRQP2F输出
I2C 057spi_status_0高电平IRQP2F输出
SPI 058spi_status_0高电平IRQP2F输出
UART 059spi_status_0高电平IRQP2F输出
CAN 060spi_status_0高电平IRQP2F输出
PLPL 63:61spi_status_0上升沿/高电平IRQF2P输入
PL 68:64spi_status_1上升沿/高电平IRQF2P输入
TimerTTC 171:69spi_status_1高电平~~
DMACDMAC75:72spi_status_1高电平IRQP2F输出
IOPUSB 176spi_status_1高电平IRQP2F输出
Ethernet 177spi_status_1高电平IRQP2F输出
Ethernet 1 Wake-up78spi_status_1上升沿IRQP2F输出
SDIO 179spi_status_1高电平IRQP2F输出
I2C 180spi_status_1高电平IRQP2F输出
SPI 181spi_status_1高电平IRQP2F输出
UART 182spi_status_1高电平IRQP2F输出
CAN 183spi_status_1高电平IRQP2F输出
PLPL 91:84spi_status_1上升沿/高电平IRQF2P输入
SCUParity92spi_status_1上升沿~~
Reserved~95:93spi_status_1~~~

可以看到,对于电平触发类型的中断,如GPIO、UART等,请求源必须在确认中断后清除中断。对于边沿触发的中断,中断源必须提供至少2个CPU_2x3x周期的脉冲,以便GIC捕捉。

tb一下 发表于 2022-8-24 16:16:30

CJC 发表于 2022-8-24 15:10
在学习的过程中,我有一直有一个疑问:在GIC配置中void XScuGic_SetPriorityTriggerType(XScuGic *Instance ...

你按键的下降沿触发对应的是GPIO内部,检测到输入信号的下降沿,产生中断请求信号
设置的HIGH level sensitive是GIC对中断请求信号的敏感类型,ug585的7.2.3中是有提到的

CJC 发表于 2022-8-24 15:10:50

本帖最后由 CJC 于 2022-8-24 15:12 编辑

在学习的过程中,我有一直有一个疑问:在GIC配置中void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, u8 Priority, u8 Trigger)这个函数的使用,我在GPIO使用中断过程中,我的按键是下降沿触发,可确要设置为HIGH level sensitive,百思不得其解,听完这节课后我就i知道了,原来在UG558中,给定了外设的触发类型!!原来在UG1085手册中没有给定外设的触发类型,害

CJC 发表于 2022-8-26 08:49:23

tb一下 发表于 2022-8-24 16:16
你按键的下降沿触发对应的是GPIO内部,检测到输入信号的下降沿,产生中断请求信号
设置的HIGH level sens ...

谢谢,明白了。这期视频收获很大,明白了这些函数里面是怎么实现中断的流程的,下一节课什么时候,期待继续

tb一下 发表于 2022-8-26 11:30:50

CJC 发表于 2022-8-26 08:49
谢谢,明白了。这期视频收获很大,明白了这些函数里面是怎么实现中断的流程的,下一节课什么时候,期待继 ...

14B已经更新了

CJC 发表于 2022-8-26 22:00:17

今天在学习过程中,碰见了一段这样的注释,中断优先级的设置
* @param        Priority is the new priority for the IRQ source. 0 is highest
*         priority, 0xF8(248) is lowest. There are 32 priority levels
*         supported with a step of 8. Hence the supported priorities are
*         0, 8, 16, 32, 40 ..., 248.

这里我不太明白,优先级到底应该怎么设置呢,见官方例程中,设置为0XA0,十进制是160,是八的倍数,我见小梅哥Lib库中写着,只有高5位有效,当时就不太理解这注释,要是这样的话,A0就是1010 0000 就是1010 0了? 变成20了?然后我现在对中断优先级的设置也不是明白,求解惑

CJC 发表于 2022-8-27 12:06:46

这里记录下,学习前面外设使用中断的相关问题
1、void XGpio_InterruptEnable(XGpio *InstancePtr, u32 Mask) 我的设置是 XGpio_InterruptEnable(&gpioaxi, 1 << AXI_KEY1) ;想着是设置开启按键中断,其他不开。可就这错了,注释中写着Mask is the mask to enable. Bit positions of 1 are enabled.This mask is formed by OR'ing bits from XGPIO_IR* bits whichare contained in xgpio_l.h.,我理解就是设置为1是使能,可以在 xgpio_l.h找到参数定义。一个GPIO不是有32位嘛,我就想着这个函数是可以设置32个位就中断使能,结果错了。要设置位XGPIO_IR_CH1_MASK也就是1,就是一个AXI_GPIO的通道一的中断是是全开启的。
2、        XGpio_InterruptGlobalEnable(&gpioaxi);这个函数也很容易误解,理解为使能该GPIO的全部中断,错了!这是中断开关,要想开关通道一或通道二必须这个要函数使能。
页: [1]
查看完整版本: 【zynq课程笔记】【裸机】【第13课 】【中断概念与中断控制器】