一:寄存器组
Cortex-M3处理器拥有R0-R15的寄存器组:
R0-R12是通用寄存器。
R13作为堆栈指针SP有两个,但在同一时刻只有一个起作用。
(MSP: 复位后默认使用的堆栈指针,用于操作系统内核以及异常处理例程,PSP: 由用户的应用程序代码使用)
R14: 连接寄存器。
R15:程序寄数器,指向当前的程序地址。
特殊功能寄存器:
● 程序状态寄存器组(PSR)
● 中断屏蔽寄存器组(PRIMASK,FAULTMASK,BASEPRI)
● 控制寄存器(CONTROL)
Cortex-M3中有专门的指令复责堆栈操作——PUSH和POP,其汇编语法如下:
PUSH {R0} ; *(--R13) = R0
POP {R0} ; R0 = *R13++
注意注释:何谓“向下增长的满栈”?在PUSH新数据时,堆栈指针先减一个单元,通常在进入一个子程序后,第一件事就是把寄存器的值先PUSH入堆放栈中,在子程序退出前再POP曾经PUSH的那些寄存器。在程序中可以直接把R13写作SP。
R15又叫作“PC”,读PC时返回的值是当前指令的地址+4。
特殊功能寄存器组专用的访问指令:
MRS R0 , PC ;读特殊功能寄存器的值到通用寄存器
MSR PC ,R0 ;写通用寄存器的值到特殊功能寄存器
二:操作模式和特权级别
两种特权操作模式:handler mode 和 thread mode
特权的分级:特权级和用户级
Thread mode可以使用特权级也可以用用户级,但异常服务例程必须使用特权级。
复位后,处理器默认进入thread mode,特权级访问。
从用户级到特权级的唯一途径就是异常,特权级可以通过修改CONTROL寄存切换到用户级。
三:总线接口
Cortex-M3内部有若干条总线接口,使CM3能同时取址和访问内存,它们是:
● 指令存储区总线(若干条)
● 系统总线
● 私有外设总线
两条代码存储区总线负责对代码存储区的访问,分别是I-Code 总线和我D-Code,前者用于取指,后者用于查表等操作,它们按最佳执行速度进行优化。
系统总线用于访问内存和外设,覆盖的区域包括SRAM,片上外设,片外RAM,片外扩展设备,以及系统级存储区的部分空间。
私有外设总线负责一部分私有外设的访问,主要是访问调试组件。它们是系统级存储区。
四:中断和异常
ARMv7-M开创了一个全新的异常模型,这种异常模型跟传统的ARM处理器使用完全是两码事。新的异常模型“使能”了非常高效的异常处理,它支持16-4-1=11种系统异常,外加240个外部中断输入,在CM3中取消了FIQ的概念,这是因为有了更新的更好的机制——中断优先级管理以及嵌套中断支持,它们被纳入CM3的中断管理逻辑中,因此,支持嵌套中断的系统就更容易实现FIQ。
CM3的所有中断机制都由NVIC实现。
五:向量表
CM3响应一个发生的异常后,对应的异常服务例程就会执行,为了决定异常服务程序入口地址,CM3使用“向量表查询机制”。向量表其实是一个WORD数组。
六:常见部分汇编指令(移植操作系统时用)
1.后缀的使用:
● S 更新APSR的相关标志
● EQ,NE,LT,GT等:EQ = Euqal, NE = Not Equal, LT = Less Than ,GT = Greater Than.
2.APSR的5个标志:N: 负数标志(Negative);
Z: 零结果标志(Zero);
C: 进位/借位标志(Carry);
V:溢出标志(oVerflow);
S: 饱和标志;
3.ADC: 带进位的加法
4.ASR: 算术右移
5.BIC: 按位清0
6.CMP: 比较(更新标志)
7.EOR: 近位异或
8.LSL: 算术左移
9.ORR: 按位异或
10.ROR: 圈圈左移
11.SBC: 带借位的减法
12.SUB: 减法
13.TST: 测试
14.BL: 转移并链接
15.CBZ: 比较,如果结果为0就转移
16.LDR: 从存储器中加载一个字到一个寄存器中
17.LDRH 加载半字
18.LDRB: 加载一个字节
19.STR:
20.STRH:
21.STRB:
22.TST: 测试(执行按位与操作,并且根据结果更新Z)
(其本质就是AND指令,只是不写`回运算结果,只更新标志位)
23.TEQ: 测试是否相等(对两个数妨行异或,更新标志但不存储结果)
24.IF THEN 指令
例:CMP RO,R1
ITTEE EQ :如果R0 == R1,Then-then-Else-Else
ADDEQ
ADDEQ
ADDNE
ADDNE
七:异常
Cortex-M3在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其中编号1-15的对的应系统异常,大地等于16的则全是外部中断。
(细分中断和异常:240个外部中断对CM3核来说都是是“意外的突发事件”——也就是说,该诸求信号来自CM3内核的外面,来自各种外部片上外设和外扩的外设,对CM3来说是“异步”的,而异常则是因CM3内核的活动产生的——在执行指令或访问存储器时产生,因此对CM3来说是“同步”的)
当发生了异常并且要响应它时,CM3需要定位其服务例程的入口地址,这些入口地址存储在所谓的“异常向量表”中。
八:SVC和PendSV
SVC(系统服务调用)和PendSV(可挂起系统调用)多用在操作系统的软件开发中。SVC用于产生系统函数的调用请求,例如:操作系统通常不让用户程序直接访问硬件,而是通过提供一些系统服务函数,让用户程序使用SVC发出对系统服务函数的调用请求,以这种方式调用它们来直接访问硬件。因此,当用户程序想要控制特定硬件时,就要产生一个SVC异常,然后操作系统提供的SVC异常服务例程得到执行,它再调用相关的操作系统函数,后者完成用户程序请求的服务。
这种“提出要求——得到满足”的方式,很好,很强大,很方便,很灵活,很能可持续发展。首先,它使用户程序从控制硬件的繁文缛节中解脱出来,由OS负责控制具体的硬件。第二,OS的代码可以经过充分的测试,从而使系统更加健壮和可靠。第三,它使用户程序无需在特权级下执行,用户程序无需承担因误操作而瘫痪整个系统的风险。第四,通过SVC的机制,用户程序变得与硬件无关,因此在开发应用程序时无需了解硬件的操作细节,从而简化了开发的难度和繁琐度,并且使应用程序跨平台移植成为可能。
SVC异常通过执行SVC指令来产生。该指令需要一个立即数充当系统调用代号。SVC异常服务例程序稍后会提取出此代号,从而获知本次调用的具体要求,再调用相应的服务函数。
另一个相关的异常是PendSV,它和SVC协同使用。一方面,SVC异常是必须执行SVC指令后立即得到响应的,应用程序执行SVC时都是希望所需的请求立即得到响应是。另一方面,PendSV则不同,它可以像普通的中断一样被挂起,OS可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动作,挂起PendSV的方法是:手工往NVIC的PendSV挂起寄存器中写1,挂起后,如果优先级不够高,则将缓期执行。
(参见<CORTEX-M3权威指南>130页)
PendSV典型使用场合是在上下文切换时(在不同任务间切换)。例如:一个系统中有两个就绪任务,上下文切换被触发的场合可以是:
● 执行一个系统调用
● 系统滴答定时器中断(轮转调度中需要)
PendSV异常会自动延尺上下文切换的请求,直到其他的ISR都完成了处理后才放行。为了实现这个机制,需要把PendSV编程为最低优先级的异常。如果OS检测到某IRQ正在活动并且被SysTick抢占,它将挂起一个PendSV异常,以便缓期执行上下文切换。
(《Cortex-M3权威指南》第130-131页)
九:中断的具体行为
当CM3开始响应一个中断时,在它小小的体内干了三件大事:
● 入栈:把8个寄存器的值压入栈。
● 取向量: 从向量表中找出对应的中断服务程序入口地址。
● 选择堆栈指针MSP/PSP,更新堆栈指针SP,更新连接寄存器LR,更新程序计数器PC。
1.入栈
响应异常的第1个动作,就是自动保存现场的必要部分:依次把x PSR,PC,LR,R12以及R0-R3由硬件自动压入适当的栈中,如果响应异常时,当前的代码正在使用PSP,则压入PSP,也就是使用进程堆栈否则就压入MSP,使用主堆栈,一量进入服务例程,就将一直使用主堆栈。
CM3在看不见的内部打乱了入栈的顺序,这是有深层次的原因的。先把PC与XPSR的值保存,就可以更早地启动服务例程指令的预取——因为这需要修改PC;同时也做到了在早期就可以更新XPSR中IPSR位段的值。
为啥袒护R0-R3和R12呢? R4-R11就是下等公民?
在ARM上,有一套C函数调用标准约定(AAPCS),原因就在它上面,它使得中断服务例程序能用C语言来编写,编绎器首先使用了栈寄存器来保存中间结果(当然,如果程序过大也可能使用到R4-R11,此时编绎器负责生成代码来PUSH它们,但是ISR应短小精悍,不要让系统如此操心)。
2.取向量
当数据总线(系统总线)正在为入栈操作而忙得风风火火时,指令总线(I-Code)可不是凉快地坐着看热闹——它正在为响应中断紧张有序地执行另一项重要的任务:从向量表中找出正确的异常向量,然后在服务程序的入口处预取指。由此看到各自都有专用总线的好处:入栈与取指这两个工作是同时进行的。
3.更新寄存器
入栈和取向量操作完成后,在执行服务例程之前,还需要更新一系列的寄存器。
需要更新的有:SP,PSR,PC,LR以及NVIC相关寄存器。
(详细参见《权威指南》147页)
4.异常返回
异常返回包括以下两个动作:
● 出栈:原先压入栈的数据出栈。
● 更新NVIC寄存器:伴随着异常的返回,它的活动位也被硬件清除。
Cortex-M3真是好啊,越来越觉得它功能强大,使用灵活,理解其体系结构有助于在各场家芯片间应对自如,还有就是移植UCOS 时必须知道这些东西。
====
http://blog.csdn.net/fanwenjieok/article/details/6316058