Cortex M3学习笔记 02 寄存器中断控制器.docx

上传人:b****2 文档编号:23083712 上传时间:2023-04-30 格式:DOCX 页数:13 大小:41.20KB
下载 相关 举报
Cortex M3学习笔记 02 寄存器中断控制器.docx_第1页
第1页 / 共13页
Cortex M3学习笔记 02 寄存器中断控制器.docx_第2页
第2页 / 共13页
Cortex M3学习笔记 02 寄存器中断控制器.docx_第3页
第3页 / 共13页
Cortex M3学习笔记 02 寄存器中断控制器.docx_第4页
第4页 / 共13页
Cortex M3学习笔记 02 寄存器中断控制器.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

Cortex M3学习笔记 02 寄存器中断控制器.docx

《Cortex M3学习笔记 02 寄存器中断控制器.docx》由会员分享,可在线阅读,更多相关《Cortex M3学习笔记 02 寄存器中断控制器.docx(13页珍藏版)》请在冰豆网上搜索。

Cortex M3学习笔记 02 寄存器中断控制器.docx

CortexM3学习笔记02寄存器中断控制器

CortexM3学习笔记02

寄存器,中断控制器

好像XX看了我的文章一样,上次笔记中写了一些对抱怨审核太慢的内容,结果第二天就审核好了,不知道这次速度怎么样……

一、名词定义

MSP:

主堆栈指针;

PSP:

进程堆栈指针;

二、寄存器

通用寄存器:

32位一个,不多说,一共22个。

R0~R15,其中R13是个有两个堆栈指针寄存器的功能,一共17个;另外还有5个特殊功能寄存器。

下面来理解。

a)通用寄存器

R0~R12:

用于数据操作,使用Thumb-2可以全部访问,使用Thumb只能访问R0~R7。

R13:

堆栈指针(SP):

包括主堆栈指针(MSP),进程堆栈指针(PSP)

PUSH和POP指令的用法解释:

PUSH{R0}//*(--R13)=R0;R13是long*型指针

POP{R0}//R0=*R13++

R13的最低两位强制为0,且读取同样也为0;

R14:

连接寄存器(LR):

保存子程序返回时的地址;

R15:

程序计数器(PC):

PC返回的地址是当前那指令的地址+4。

例如:

0x4000MOVR0,PC;//R0=0x4004;

当针对执行一条写入R15指令时,写入R15的地址被当成一个指令地址,程序从这个地址处开始执行,但是不更新LR寄存器,相当于引发一次跳转;

PC的LSB读回内容始终为0,不论是直接写入PC的值,还是使用分支跳转命令,都要求加载到PC的值是奇数(LSB=1),用以表明处理器是在Thumb状态下执行。

若写入0,则视为企图跳转到ARM模式,Cortex-M3将产生一个fault异常。

b)特殊功能寄存器

Ø程序状态寄存器组(PSRs);

分为:

应用状态寄存器(APSR)为[27~31];

中断状态寄存器(IPSR)为[0~8];

执行状态寄存器(EPSR)为[10~15],[24~26];

共计32位

自己画个0~31的寄存器“位”表格,很直观。

Ø中断屏蔽寄存器组(PRIMASK、FAULTMASK、BASEPRI);

PRIMASK相当于中断总开关,

当PRIMASK=1时,屏蔽所有中断(除NMI和fault外)。

FAULTMASK屏蔽错误中断。

BASEPRI优先级屏蔽寄存器中断。

Ø控制寄存器(CONTROL)。

第一.定义特权级别:

特权级线程模式,用户级线程模式;

CONTROL[0]=0是特权级;

CONTROL[0]=1是用户级;

第二.选择当前堆栈指针:

主堆栈MSP,备用堆栈。

CONTROL[1]=0是主堆栈(复位缺省);

CONTROL[1]=1是备用堆栈,

特殊功能寄存器不存在地址,只能被专用的MSR和MRS指令访问。

使用方式:

MRS,;

读特殊功能寄存器的值到通用寄存器;

MSR,;

写通用寄存器的值到特殊功能寄存器;

其中是通用寄存器,是特殊寄存器;

例如:

·MOVR0,#0x01;

MOVRPIMASK,R0;

·MOVR0,0x60;

MOVBASEPRI,R0;

三、CortexM3操作模式和特权级别

分为两种模式;两种级别:

a)操作模式:

线程模式(Threadmode),处理模式(handlermode);

线程模式:

在此模式中程序指令逐一运行;

处理模式:

在程序执行过程中,触发了一个异常后,处理器将进入到处理模式;处理结束后返回之前的状态。

b)特权级别:

特权级,用户级;

特权级:

系统开启后默认进入。

无限制。

用户级:

处理器将禁止对系统控制区域(SCS)(包含配置寄存器和调试组建的存储区域)的访问。

画个表格:

代码作用

特权级

用户级

异常handler代码

Handler模式

错误,不可操作

主应用程序代码

线程模式

(复位后默认进入的模式)

线程模式

这样可以直观的看出,处理模式下,只提供特权级的代码才能访问。

好处不多说了,保护关键区域代码安全,防止有意无意的篡改。

·思考一下,上面说过CONTROL寄存器的可以更改特权;

程序启动后,线程模式会在CONTROL的指引下进入从特权级转为用户级运行,如果在用户级下面MSR命令自然是不能更改CONTROL特权的,那么如何解决?

答案:

刚才表格中说了handler模式下肯定是特权级的,那么我们就利用handler模式来解决这个问题。

在中断处理的时候(handlermode),加入代码:

MRSR0,CONTROL;//读取CONTROL;

BIC.WR0,R0,#0x01;//清零CONTROL[0];

MSRCONTROL,R0;//将清零的内容写入CONTROL;

这样CONTROL[0]就等于0了,变成特权级;程序返回后,继续往下执行,就是在特权级下的指令执行了。

记得利用MSR+CONTROL返回用户级;如此再加上MPU设备,书上这样形容:

安全,健壮……

四、CortexM3的异常、中断及向量表

“中断”和“异常”,经常被混合使用,强调他们对主程序的执行所体现的“中断”性质。

书本不强调他们之间的区别。

若一定要区别:

可以理解“异常”由指令执行或访问存储器时产生,例如:

存储单元的值改变;

而“中断”可以理解为“中断请求信号”一般由外部产生,例如:

外设信息处理请求;

CortexM3处理器在内核水平上搭载了一个中断控制器——嵌套向量中断控制器NVIC(NestedVectoredInterruptController),可实现非常高校的异常处理。

取消FIQ(快速中断处理),取而代之的是“嵌套中断支持”和“优先级管理”。

1.嵌套中断支持,在下面的“优先级分组”中介绍。

2.向量中断支持,CortexM3会自动定位一张向量表,根据中断号从表中找出相应中断的入口地址,然后跳转过去执行。

3.异常类型,支持11种系统异常和240种外部中断输入。

其中1~15对应的是系统异常,大于等于16的则全是外部中断。

大部分异常的优先级是可编程的,出了部分固定的。

编号

类型

优先级

描述

1

复位

-3(最高)

复位

2

NMI

-2

不可屏蔽中断(来自外部NMI引脚)

3

Hardfault

-1

所有被除能的fault,都将上访(escalation)成硬fault。

只要FAULTMASK没有置位,硬fault服务例程就会被强制执行。

Fault被除能的原因包括被禁用,或者FAULTMASK被置位。

4

存储器管理fault

可编程

存储器管理fault,MPU访问违规或访问非法位置均可引发。

企图在“非执行区”取指也会引发此fault。

5

总线fault

可编程

总线错误,当AHB接口收到总线系统的错误响应时发生(也称为预取中止或是数据中止)。

6

用法fault

可编程

由于程序错误或企图访问协处理器(CortexM3不支持协处理器)导致的异常。

7~10

保留

NA

NA

11

SVCall

可编程

执行系统服务调用指令(SVC)引发的异常。

12

调试监视器

可编程

调试监视器(断点,数据观察点或外部调试请求)

13

保留

NA

NA

14

PendSV

可编程

为系统设备而设的“挂起请求”(pendablerequest)

15

SysTick

可编程

系统节拍定时器

16~255

外部中断

可编程

CortexM3内核之外产生的中断(0~239)

上边的“优先级表”中-3,-2,-1始终会高于0,所以画个数轴,就明白了“数值越小,优先级越高”的道理,但是“可编程”的优先级不存在负数……。

系统异常是CortexM3内核支持的基本异常,与具体芯片无关,而外部中断则与芯片相关,芯片厂商会根据需要和用途设计中断源数目(1~240)和优先级的位数。

例如:

NXP公司的LPC1752支持35个外部中断和32个中断优先级。

4.异常优先级,优先级数值越小,则级别越高(前面提过,批注A7)。

CortexM3中:

复位、NMI、硬fault是固定优先级。

5.优先级配置寄存器,理论上一个字节Bit[0~7],可以表示256个优先级,但是实际上为了精简设计芯片设计商会裁剪掉部分低端有效位。

例如:

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

用于表达优先级

不执行,读回为零

优先级为:

0x00(最高)、0x20、0x40、0x60、0x80、0xA0、0xC0、0xE0。

或者

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

用于表达优先级

不执行,读回为零

6.优先级分组:

·思考一下,既然中断响应的优先级已经分了,为什么还要分组呢?

书本上介绍并不详细,看了一些资料,才弄明白,这个部分其实很重要。

简单分析一下,我们知道,程序在运行时,当多个中断来的时候,根据优先级的高低来处理中断请求的。

那么问题来了,如果正在响应一个异常时,突然来了一个优先级比较高的异常,那么我们是放下当前正在响应的异常,去执行新来的这个?

还是继续响应当前的异常,直到处理完毕,再去考虑那个新异常的优先级呢?

答案:

CortexM3提供了“抢占式优先级”和“子优先级”来解决这个问题。

(有地方对“子优先级”叫做“副优先级”或“响应优先级”,无所谓叫什么,关键是通途)

看看下表,CortexM3将“优先级配置寄存器”划分为两组,这样的分组信息保存在AIRCR中。

根据上面“优先级配置寄存器”定义,来引申一下。

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

抢占优先级

子优先级

不执行,读回为零

“子优先级”至少要有1位!

“抢占优先级”可以没有。

优先级分组在“位4”上;

或者

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

抢占优先级

子优先级

不执行,读回为零

优先级分组在“位5”上;

也可以这样分,但是太没有意思了吧……

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

抢占优先级

抢占优先级(不执行)

子优先级

(不执行)

画个表格更直观:

分组位置

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

7

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

6

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

5

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

4

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

3

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

2

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

1

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

0

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

虽然可以这样随意分组,但是如果“优先级配置器”没有涉及到的“位”,结果还是没用……。

下面来看看,分组的作用:

以“位5”分组为例:

Bit[7]

Bit[6]

Bit[5]

Bit[4]

Bit[3]

Bit[2]

Bit[1]

Bit[0]

抢占优先级

子优先级

不执行,读回为零

假设有个正在被响应的异常,“抢占优先级”为第四级(即Bit[7]=1,Bit[6]=1),当有一个“抢占优先级”为第二级(即Bit[7]=0,Bit[6]=1)的异常产生后,不会被等待或排序,将直接挂起“第四级”,而执行“第二级”;当“第二级”执行完毕后,返回刚才“第四级”的响应。

如此一来,第一级>第二级>第三级>第四级,这样便形成了先前所说的“嵌套向量中断控制器”中“嵌套”作用。

如下图:

那么“子优先级”就好解释了,在相同“抢占等级”下,优先响应“子优先级”高的异常,而相互之间不可抢占!

也就是说“子优先级”不能再“嵌套”了。

例如:

如果系统正在响应“0x40”优先级的异常,同时出现“0x00与0x20”,那么不论她执行到哪里,都将被挂起,而优先执行“0x00与0x20”。

而0x00与0x20,必定先响应0x00。

注:

复位、NMI、硬fault是固定优先级,且无条件抢占任何优先级。

顺带提一下,“应用程序中断及复位控制寄存器(AIRCR)”:

位段

名称

类型

描述

复位值

0

VECTRESET

W

复位CortexM3处理器内核(调试逻辑除外),此复位不影响芯片上内核以外的电路

1

WECTCLRACTIVE

W

清零所有异常的活动状态信息。

通常在调试或OS从错误中恢复时使用。

2

SYSRESTREQ

W

请求芯片的控制逻辑产生一次复位

[10~8]

PRIGROUP

R/W

优先级分组

0

15

ENDIANESS

R

数据字节顺序设置:

1:

大端(BE8);0:

小端。

此位在复位时确定,不可更改。

[31~6]

VECTKEY

R/W

访问钥匙:

任何对该寄存器的写操作,都必须同时将0x05FA写入此字段,否则写操作被忽略。

读取此半字,返回0xFA05

例如:

分组设置

AIRCR=(0x05FA)|(0x05<<8);

//优先级在位5处分组;其中0x05<<8,表示数值在寄存器右移8位保存,0x05FA,在写入AIRCR数值时必须同时写入。

如果没有这个,那么在响应异常的时候,有两种可能:

第一,其余异常将会被排序并等待前面的异常处理完毕后再执行;第二,如同51芯片一样,中断优先级被固化在芯片中,可供调节的范围很小。

7.异常向量表

地址

异常编号

值(32位整数)

0x00000000

-

MSP的初始值

0x00000004

1

复位向量(PC初始值)

0x00000008

2

NMI处理函数入口地址

0x0000000C

3

硬fault处理函数入口地址

……

……

其他异常处理函数入口地址

如前面所说的,理论上中断请求有256个,这里也预留了256,缺省情况下,CortexM3中的向量表位于存储空间的零地址出,表中每个向量4个字节。

跳转功能和51系列很相似,CortexM3允许向量表重定位到内存的其他位置,这些位置对应区域可以使是代码区,也可以是RAM区。

当向量表位于RAM区时,允许运行中对异常服务函数进行动态修改。

 

结束,下次继续。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1