历史上的今天
返回首页

历史上的今天

今天是:2025年04月23日(星期三)

正在发生

2020年04月23日 | ARM异常与中断处理

2020-04-23 来源:eefocus

中断是ARM处理器提高工作效率的方法之一。


Ⅰ、形象理解中断:

假设有个大房间里面有小房间,婴儿正在睡觉,他的妈妈在外面看书。母亲怎么才能知道小孩醒?


过一会打开一次房门,看婴儿是否睡醒,让后接着看书

一直等到婴儿发出声音以后再过去查看,期间都在读书


查询

while(1)

{

    1 read book(读书)

    2 open door(开门)

    if(睡)

        return(read book)

    else

        照顾小孩

 

}


中断

while(1)

{

    read book

    中断服务程序()//声音中断

    {

        处理照顾小孩

    }

}

两种方式对比:很明显,第一种会累死妈妈滴。


这种是比较形象化的比喻,真正在ARM处理器中是如何处理的呢?


有数据(孩子声音)

保护现场(放下手头工作)

调用中断函数(打开房门查看)

处理数据(照顾孩子)

恢复现场(继续工作)

 

这里存在几个问题:


ARM处理是怎样知道有数据的,谁来告诉它

如何保存正在运行的程序

在哪里调用中断函数

如何恢复程序

 

问题解决:


中断控制器,通过设置中断控制器,监听中断源,例如串口的数据接收中断源

保存寄存器,例如程序返回寄存器,后面通过代码比较好懂

硬件规定异常向量地址,软件设置异常向量表,发生中断时,跳转到处理函数

恢复寄存器


Ⅱ、为了更好、更安全的运行程序,ARM分出了多种工作模式:

用户模式(usr),也称普通模式

系统模式(sys),也称兴奋模式

未定义模式(und),指令不能识别

管理模式(svc)

终止模式(abt)

中断模式

快速中断模式

 

Ⅲ、再论保护现场

在这些模式下都有一堆自己一堆寄存器,进入其他模式之前都会先保存r0到r14的寄存器到栈中,加粗的代表是这个模式下的专属寄存器。

Ⅳ、中断模式与快速中断模式的区别

ARM有irq和fiq中断通道,这两个通道可以通过CPSR寄存器I位和F位设置使能。


当触发irq中断时,如果此时再来一个irq,此时ARM是不会鸟你的。ARM核心就像老板,老板本来在做事,然后来了一个客户,秘书打断它,让客户进去。而此时再来一个客户,要么秘书不断去敲门问,要么客户走人。老板第一个客户没有会见完,不会理你。 


但是有一种情况例外,当ARM处在IRQ模式,这个时候fiq pin来了一个中断信号,fiq pin是什么?快速中断,好比公安局的来查刑事案件,才不管老板是不是在会见客户,直接打断,进入到fiq模式,跳到相应的fiq的异常向量表处去执行代码。那如果当ARM处理FIQ模式,fiq pin又来中断信号,也就是又一批公安来了,那没戏,都是执法人员,你打不断我。如果此时irq pin来了呢?来了也不理,正在办案,还敢来妨碍公务。 


所以得出一个结论: IRQ模式只能被FIQ模式打断,FIQ模式下谁也打不断。


中断概念介绍到此,下面将结合三步骤和前面提到的几个问题做详细编程!!!


Ⅴ、芯片手册

由于中断是没有线连接的,所以略过原理图。


1、程序状态寄存器(PSR)

前面提到CPU可以工作在多种模式,CPU也可以处理中断,这些都是可以在CPSR中设置的。


看一下PSR可以设置CPU哪些东西:


T位为1,表示CPU工作于Thumb指令集(一条指令16位)

F位为1,表示CPU不接收任何FIQ中断请求

I位为1,表示CPU不接收任何IRQ中断请求

中间保留位

V是CPU的计算溢出位

C是CPU的计算进位

Z是CPU的计算0位

N是CPU的计算正位,逻辑运算

可以通过设置低4位让CPU进入不同模式,不过处于用户模式是无法设置这4个位的

为什么有CPSR和SPSR?


SPSR是保存程序状态寄存器,CPSR是当前程序状态寄存器,当发生异常时或者中断时,SPSR会保存CPSR的值。


ARM920t给出异常进入和退出的操作,基本上前面都提到了。


2、中断控制器

上面是CPU的中断处理,但是我们还有很多的外设啊,比如按键中断,这些需要中断控制器来完成。


图为中断的流程:最终进入CPU处理的中断需要经过多个屏蔽寄存器的筛选,这些寄存器就是“小秘书”

3、中断向量表

按键中断后,中断处理函数如何调用(中断向量表)

4、外设中断

这里以按键为例子:按键接在GPF0处,只要配置GPF0为中断引脚

除此之外,按键还要配置上升沿触发还是下降沿触发

设置完成后要使能中断吧,对应中断使能即可,这是中断第一屏蔽关

Ⅵ、中断编程

这里以按键中断作为例子,按键触发中断,点亮LED灯。


前面提到了这么多,编程是否有关呢?


答案是确定的,可以想象一下中断的过程:


按键触发中断(中断引脚)

经过屏蔽寄存器(不屏蔽)

进入模式选择(快中断、普通中断)

CPU总中断

 


编程需要解决的问题:


按键中断后,中断处理函数如何调用(中断向量表)

如何得知是对应按键触发中断的(中断源寄存器)

中断之后在哪里保存现场,又是如何恢复现场(保存寄存器)

 


设置中断向量表

这些地址都是硬件规定的,编程只需要在对应位置上放上跳转指令即可


_start:

b reset          /* vector 0 : reset */

ldr pc, und_addr /* vector 4 : und */

ldr pc, swi_addr /* vector 8 : swi */

b halt /* vector 0x0c : prefetch aboot */

b halt /* vector 0x10 : data abort */

b halt /* vector 0x14 : reserved */

ldr pc, irq_addr /* vector 0x18 : irq */

b halt /* vector 0x1c : fiq */

 

 und_addr:

.word do_und

 

swi_addr:

.word do_swi

 

irq_addr:

.word do_irq

设置按键中断源、中断控制器屏蔽中断源

/* 配置GPIO为中断引脚 */

GPFCON &= ~((3<<0) | (3<<4));

GPFCON |= ((2<<0) | (2<<4));   /* S2,S3被配置为中断引脚 */

 

GPGCON &= ~((3<<6) | (3<<22));

GPGCON |= ((2<<6) | (2<<22));   /* S4,S5被配置为中断引脚 */

 

/* 设置中断触发方式: 双边沿触发 */

EXTINT0 |= (7<<0) | (7<<8);     /* S2,S3 */

EXTINT1 |= (7<<12);             /* S4 */

EXTINT2 |= (7<<12);             /* S5 */

 

/* 设置EINTMASK使能eint11,19 */

EINTMASK &= ~((1<<11) | (1<<19));

 

    INTMSK &= ~((1<<0) | (1<<2) | (1<<5));

保护现场,恢复现场

do_irq:

/* 执行到这里之前:

* 1. lr_irq保存有被中断模式中的下一条即将执行的指令的地址

* 2. SPSR_irq保存有被中断模式的CPSR

* 3. CPSR中的M4-M0被设置为10010, 进入到irq模式

* 4. 跳到0x18的地方执行程序 

*/

 

/* sp_irq未设置, 先设置它 */

ldr sp, =0x33d00000

 

/* 保存现场 */

/* 在irq异常处理函数中有可能会修改r0-r12, 所以先保存 */

/* lr-4是异常处理完后的返回地址, 也要保存 */

sub lr, lr, #4

stmdb sp!, {r0-r12, lr}  

/* 处理irq异常 */

bl handle_irq_c

/* 恢复现场 */

ldmia sp!, {r0-r12, pc}^  /* ^会把spsr_irq的值恢复到cpsr里 */

中断处理函数

void handle_irq_c(void)

{

/* 分辨中断源 */

int bit = INTOFFSET;

 

/* 调用对应的处理函数 */

if (bit == 0 || bit == 2 || bit == 5)  /* eint0,2,eint8_23 */

{

key_eint_irq(bit); /* 处理中断, 清中断源EINTPEND */

}

 

/* 清中断 : 从源头开始清 */

SRCPND = (1< INTPND = (1<}

void key_eint_irq(int irq)

{

unsigned int val = EINTPEND;

unsigned int val1 = GPFDAT;

unsigned int val2 = GPGDAT;

if (irq == 0) /* eint0 : s2 控制 D12 */

{

if (val1 & (1<<0)) /* s2 --> gpf6 */

{

/* 松开 */

GPFDAT |= (1<<6);

}

else

{

/* 按下 */

GPFDAT &= ~(1<<6);

}

}

else if (irq == 2) /* eint2 : s3 控制 D11 */

{

if (val1 & (1<<2)) /* s3 --> gpf5 */

{

/* 松开 */

GPFDAT |= (1<<5);

}

else

{

/* 按下 */

GPFDAT &= ~(1<<5);

}

}

else if (irq == 5) /* eint8_23, eint11--s4 控制 D10, eint19---s5 控制所有LED */

{

if (val & (1<<11)) /* eint11 */

{

if (val2 & (1<<3)) /* s4 --> gpf4 */

{

/* 松开 */

GPFDAT |= (1<<4);

}

else

{

/* 按下 */

GPFDAT &= ~(1<<4);

}

}

else if (val & (1<<19)) /* eint19 */

{

if (val2 & (1<<11))

{

/* 松开 */

/* 熄灭所有LED */

GPFDAT |= ((1<<4) | (1<<5) | (1<<6));

}

else

{

/* 按下: 点亮所有LED */

GPFDAT &= ~((1<<4) | (1<<5) | (1<<6));

}

}

}

 

EINTPEND = val;

}

推荐阅读

史海拾趣

Equinox公司的发展小趣事

2020年,新冠疫情的爆发给全球健身行业带来了前所未有的挑战。许多健身房因为疫情而被迫关闭,Equinox也不例外。然而,Equinox并没有放弃,而是迅速调整策略,通过线上课程、虚拟健身等方式保持与客户的联系。同时,公司还加强了内部优化和成本控制,以应对疫情带来的经济压力。

Elma Electronic Inc公司的发展小趣事

Elma Electronic Inc公司在电子封装市场拥有显著的领导地位。从VME/VME64x到Rugged COTS封装,该公司凭借其创新的设计和制造技术,成功地在多个细分市场取得了领先地位。这种领导地位不仅体现在产品的多样性上,更在于其为客户提供的高质量、可靠性和性能优异的产品。

驰芯微(CHIPWISE)公司的发展小趣事

驰芯微公司自2014年成立以来,就立志于打破国外芯片厂商在车规级芯片领域的垄断。初创时期,公司面临着资金短缺、技术壁垒高和市场竞争激烈的挑战。然而,驰芯微团队凭借对技术的执着追求和对市场的敏锐洞察,成功研发出了一系列车规级智能传感和控制芯片,并逐渐在行业中崭露头角。经过数年的努力,驰芯微已经成为国内车规级芯片领域的领军者,其产品广泛应用于各类前装量产车型。

Fujisoku Corporation公司的发展小趣事

“未来电子”深知人才是企业发展的第一资源。因此,公司高度重视人才培养和团队建设工作。通过建立完善的培训体系、激励机制和晋升通道,公司吸引并留住了一大批优秀的研发、生产和销售人才。这些人才在各自的岗位上发挥出色,为公司的快速发展提供了有力保障。同时,“未来电子”还注重团队合作和跨部门协作,通过组织丰富多彩的团队建设活动,增强了员工的归属感和凝聚力。

常州星海电子(Starsea)公司的发展小趣事

在电子行业,技术创新是企业持续发展的关键。常州星海电子一直致力于技术的研发和创新。近年来,公司成功取得了一项名为“一种高反压二极管”的专利,通过采用先进的生产工艺和设计,实现了产品性能的优化和成本的降低。这一创新不仅提升了公司的市场竞争力,也为整个电子行业的发展注入了新的活力。

GAPTEC Electronic GmbH & Co. KG公司的发展小趣事

背景:在闪存市场取得成功后,Galaxy Microelectronics开始探索多元化发展道路。

发展:公司决定进入DRAM市场,并投入大量资源进行技术研发。经过几年的努力,Galaxy Microelectronics成功推出了多款高性能DRAM产品,进一步丰富了其产品线。此外,公司还开始涉足SSD固态硬盘领域,推出了多款具有竞争力的产品,进一步巩固了其在存储市场的地位。

问答坊 | AI 解惑

江苏人民好幸福,俺也想用华丽丽免费的手机上网~~

这两天出差到南京,就感觉到江苏人民可真是幸福,用江苏电信的E9套餐算算,去掉赠送的600分钟+400分钟这一摊固话和手机通话费(挺复杂,送的特别多,这些话费一毛一分钟都已经有小一百块钱了),几乎是一天一块钱宽带了,可真是让偶介个首都人民眼 ...…

查看全部问答>

CPLD的双向端口问题!毕设啊求助!

现在PCI数据线与CPLD相连,有一个功能是测速,首先用LAD0发一个控制信号,然后如入LAD[15..0]的数据。 由于LAD0需要双向,因此将LAD[15..0]都设为Bir(在顶层框图中)但是发现通过LAD0根本写入不了命令,不知为什么? 现在只能LAD0只作输入 其余1 ...…

查看全部问答>

Uboot中那个函数可以使其重启

RT, 想在里面添加一个reboot命令,请了解的仁兄指点.…

查看全部问答>

自制廉价的GPS外接天线

    有网友试过,效果确实不错:宿舍窗台上(11楼)不到20秒,显示了时间,再过几秒,就显示了经纬度,没调,就收到4颗心!!     材料: 同轴线 直径1mm的漆包线200mm以上 敷铜板:长:100mm; 宽:100mm; 敷铜条 ...…

查看全部问答>

嵌入式组态软件系统

    嵌入式组态软件系统以应用为中心,以半导体技术、控制技术计算机    嵌入式组态软件系统技术和通讯技术为基础,强调硬件软件的协同性与整合性,软件与硬件可剪裁,以满足系统对功能、成本、体积和功耗等要求。 ...…

查看全部问答>

STC-ISP

各位大虾,您们好! 我有各问题想请教一下。 我的STC  USB转串口下载 时好时坏,昨晚在宿舍下载好好的一直玩到12点,早山八点到实验室又不能用了。几乎每天都是这样。有时候在实验室能用了 去宿舍又不能用了?? 这个是线的问题么。 PS:ST ...…

查看全部问答>

FPGA控制W5300

有没有大神做过这个项目呀,手头没什么资料,不知道从何下手。…

查看全部问答>

TSP-Link——超越基础(DIO作为触发总线)

测试设置 此测试采用与前一个测试完全同样的脚本,只是这次包括了TSP触发模型。此触发模型使用了2602与3706灵活性高、功能强大的数字I/O控制。   下列指令通过触发模型提高了吞吐量:   测试结果 取决于DUT,此方法能在一次 ...…

查看全部问答>

如何提高IP核的可靠性?

各位大虾,小弟最近在写程序时会经常调用双口RAM,双口RAM的数据读写并不需要同时进行,只有在数据写入RAM之后才会读取RAM中的数据,由于实际应用对安全性要求特别高,而且要长时间应用,我怕RAM不能及时更新数据或者出现其他故障,请教各位有没有 ...…

查看全部问答>