微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM CORTEX-M3 内核架构理解归纳

ARM CORTEX-M3 内核架构理解归纳

时间:11-21 来源:互联网 点击:

位是不一样的,传统的单片机是直接从地址0处开始运行,然后再执行地址0处的跳转指令,跳转到设定的程序起始段;而CM3位后首先是在地址零处0x0000 0000取出主堆栈MSP的初始值,(因为CM3的堆栈是向下生长型的,所以这个初始值一般设为RAM区的末地址+1,以保证堆栈足够大,再啰嗦下,比方说RAM区为0x2000 0000——0x3FFF FFFF那么初始值就设置为0x4000 0000);然后通过位中断号找到存放位程序入口地址的地址单元(0x00000004),地址单元(0x00000004)存放着第一条指令执行的地址(0x0000 0100)并赋给PC,PC就从这个地址里存放的指令依次执行。关于指令执行的地址需要严重关切:CM3运行在thumb状态,所以加载到PC中的值的最低位LSB必须置1,以区别ARM状态(ARM为偶数),所以若想指向0x0000 0100的地址值,中断向量表中存的位程序入口地址应为0x0000 0101,用0x0000 0101表示0x0000 0100,这里不要把存储数据的地址和PC的指向地址搞混,只有PC的执行地址LSB不能等于0,其他总线访问地址则没有此限制。(为了把问题解释清楚,啰嗦的我自己都受不了了)为什么要首先初始化堆栈MSP呢?因为在位的过程中也可能发生中断,例如NMI,硬fault等。

中断从发生到结束主要需要经过以下这么几个步骤:1捕获并响应中断,2现场保护,3中断程序入口,4返回。下面就根据这个脉络来总结cortexM3在提高中断响应速度方面所涉及的重要知识点(这个讲解顺序针对已具备一定的基础人员):

说到中断必涉及到优先级、涉及到嵌套,在CM3中用8位来编程中断的优先级数,可实现256级优先级,其中这8位又分为两段,一段决定抢占优先级的级数,一个决定亚优先级的级数,其中规定抢占优先级不得少于3位(8级优先级),亚优先级最少不得少于1位,所以抢占优先级在M3中最多128级,在哪一位开始分组由NVIC中的寄存器中(应用程序中断及复位控制寄存器)的PRIGROUP来决定;但实际中,芯片制造商一般只使用最高几位,比如5位,高三位(7,6,5)编程抢占优先级,剩下的两个次高位(4,3)用来决定亚优先级,从第4位处作为亚优先级的分组,这里通过一个分组寄存器来决定从哪一位做亚优先级分组。

优先级确定好了,那么在众多不同优先级的中断面前,CM3又是以什么样的机制来提高响应速度的呢?这就需要表一表在响应之前,处理器必须要做的工作——现场保护即保护当前的程序运行环境,依次入栈以下8个寄存器:程序状态寄存器XPSR,程序计数器PC,返回地址寄存器LR(连接寄存器),R12,R0——R3,这些都是硬件自动完成的。如果当前正在使用堆栈,则压入相应的堆栈寄存器MSP/PSP值,当前在用PSP就压入PSP,反之则压入MSP,进入中断服务程序就将一直用MSP了;好了,请注意,提高中断的响应速度就在这些寄存器的入栈顺序上,我们知道,堆栈是建立在片上RAM中的,通过系统总线(system code)来操作(为什么要建立在RAM上,因为堆栈需要不停地做出栈、入栈等动作,需要不断改变存储的值,而flash或rom只在烧写的时候写入数据),指令是存放在flash中的即code区通过指令总线(code bus)来操作,所以在入栈的时候先压入xPSR的值,再压入PC的值,压入PC的值后,就可以通过指令总线,根据中断向量号取出中断服务函数的地址赋给PC新的指令地址,进行指令的预取,而堆栈仍然可以通过系统总线继续压入其他寄存器的值,与取指令操作并行不悖,互不干扰,加快了中断的响应速度。相关寄存器可查询权威手册。

在响应中断前所做的准备工作都做好了,那么当众多中断前来叫门时,应该如何以最短的延时处理一系列的中断呢?第一级中断自不必说,根据中断号来进行仲裁,当发生中断嵌套的时候,CM3中的一些响应机制就能加快整个中断响应过程的速度了,低优先级由于高优先级中断的抢占而处于挂起状态,当高优先级中断处理完毕,按照传统的嵌套中断处理流程,高优先级中断处理完成后应该出栈弹出内容,然后再入栈压入先前弹出的内容,再处理被挂起的低优先级中断,按书中所说,这就是砸锅炼铁再铸锅的过程,完全没有必要,于是CM3内核在处理一系列嵌套的中断时,总共只执行一次入栈,出栈工作,这样处理连续的几个嵌套中断时,就减少了很多环节,缩短了时间,尤其是嵌套级别计较深的时候,尤为明显。但是要注意的是:不要嵌套太深,因为每嵌套一级就至少入栈8个32位的寄存器值(32B),如果本身就是中断进程,当前代码正在使用堆栈,还要将堆栈的值再入栈,这样无疑加大了堆栈的存储压力,如果用穿堆栈,发生溢出

上一篇:ARM 伪指令讲解
下一篇:ARM问答

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top