重要规则:多个中断源在它们的抢占式优先级相同的情况下,子优先级不论是否相同,如果某个中断已经在服务当中,则其它中断源都不能打断它(可以末尾连锁);只有抢占式优先级高的中断才可以打断其它抢占式优先级低的中断。优先级分组规定:亚优先级至少1位,因此抢占式优先级最多7位;
优先级分组在AIRCR(应用程序中断与复位控制寄存器(0XE000_ED00))中的[10:8]PRIGROUP位域设置(芯片的标准库函数中一般都会有相应的这样的设置函数给用户调用:如
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
void NVIC_SystemHandlerPriorityConfig(u32SystemHandler, u8SystemHandlerPreemptionPriority, u8SystemHandlerSubPriority)
具体的芯片支持的M3的优先级分组情况不一样,芯片在设计时已经确定了它支持多个种分组,如我的STM32只支持0~4分组,这个具有要看芯片手册(其实查看芯片提供的相关代码就可以查出了),为了更好的支持代码的跨平台特性,优先级是以MSB对齐的(这里的对齐,比如3位抢占式优先级移植到另一款芯片变成2位,这时丢失的是最高位,如抢占式优先级5会变成1);
4:《权威指南》第一章小结
ARM处理器支持的指令集:ARM(32位,对应CPU的ARM状态)、Thumb(16,对应CPU的Thumb状态)、Thumb2(32、16);
Thumb指令在功能上时ARM指令的一个子集,它的优点是提高代码密度;Thumb2是Thumb指令的超集(16和32位的指令共存);
Cortex M3使用的就是2003年盛产的Thumb2指令集,M3支持Thumb2指令的好处:1.支持绝大多数的传统的Thumb指令,方便在只支持Thumb指令平台上写的代码的移植;2.不用进行处理器的状态切换(在一些运算复杂的地方需要Thumb<->ARM切换),提高效率。
5:《权威指南》第二章小结
CPU的寄存器:R0~R12(通用寄存器)、R13(M/PSP)、R14(LR)、R15(PC)、xPSR(程序状态字寄存器)、PRIMASK/FAULTMASK/BASEPRI(中断屏蔽寄存器)、CONTROL(控制寄存器)【最后三类为特殊功能寄存器,具体功能后面分析】
堆栈指针(R13)的最低两位永远为0,因为堆栈是4字节对齐(ARM是32位处理器,各寄存器都是32位的);
M3支持两种处理器的操作模式以及两种特权操作;
操作模式:handler mode 、thread mode (异常时处理器处于handler mode ,其他时候是threadmode)
特权操作:特权级(复位后系统默认、handlermode下总是特权级)、用户级(非特权级);这是一种安全策略,特权级是可以访问所有的存储器(有MPU,要除去MPU规定的禁区),可执行所有的指令【这是特权级与用户级的区别所在,配上MPU,就可以对特权级访问和用户级访问施加不同的限制】。
CONTROL[1]、CONTROL[0]只有在特权级模式下才允许写(从用户级到特权级的唯一路径就是异常:触发一个异常,处理器总是先切换到特权级,异常退出时,返回先前的状态,也可通过LR手动修改返回状态),特权级的线程模式可通过修改CONTROL[0]=1进入用户模式,这样就只能通过异常才能返回特权级;
Cortex M3拥有4G的存储空间,且对这4G的存储空间进行了粗线条的规划:
0x0000_0000--0x1FFF_FFFF:代码区。 0x2000_0000--0x3FFF_FFFF:用于片上静态RAM。
0x4000_0000--0x5FFF_FFFF:片上外设空间。 0x6000_0000--0x9FFF_FFFF:扩展外部存储器。
0xA000_0000--0xDFFF_FFFF:扩展片外外设。 0xE000_0000--0xFFFF_FFFF:系统控制空间(NVIC、SCB等)
处于最高地址的系统级存储区包括NVIC、MPU、SCB、调试组件等,且所有这些控制模块的寄存器地址是固定的,不随芯片厂家的不同而发生改变,这样就方便移植了。
MPU:MPU保护内存是按region(区)来管理的,当检测到访问犯规时,MPU会产生一个异常,进入对应的异常服务程序。最常见的MPU玩法是操作系统使用MPU来包含特权级代码的数据,包括操作系统本身的数据不被其他的用户程序破坏。
MRS、MSR访问特殊功能寄存器。
调试:M3不同于以往的ARM处理器,内核本身不再含有JTAG接口,取而代之的是CPU提高的DAP“调试访问接口”的总线接口,通过这个总线接口,可以访问芯片的寄存器、系统存储器等,甚至可以在内核运行时访问,而对此总线接口的使用是通过一个调试端口(DP)设备完成,DP不属于M3内核,但它是在芯片内部实现的。DP包括SWJ-DP(支持JTAG调试与串行线调试)、SW-DP(串行线调试),也可以使用JTAG-DP,具体使用哪一个由厂家选择提供给用户(通常为SWJ-DP);M3还挂载了一个ETM(嵌入式跟踪宏单元),ETM不断发出跟踪信息,这些信息通过一个被称为TPIU(跟踪端口接口单元)的模块送到内核的外部,如果再芯片外使用“跟踪信息分析仪”就可以捕捉TPIU的“已执行指令信息”,送给调试PC机。
通过WFI(等待中断指令)与WFE(等待事件指令),内核可以进入睡眠模式。
M3支持“位寻址带”操作,支持非对齐的数据访问。
6:《权威指南》第三章小结
M3中指令至少是半字对齐,所以读取PC的值时,PC的LSB总是读回0,且PC的LSB位表示的是CPU所处的状态,1表示Thumb状态,0表示ARM状态,所以无论是在直接写PC值还是使用分支指令,都必须保证加载到PC的数值是奇数(LSB=1),用以表示这是在Thumb状态下执行,若写了0,则试图转入ARM状态,CM3将产生一个异常。
读取PC值时获得的数值是与CPU的流水线级数【M3的是三级:取指、译码、执行】有关的,CM3在读PC时返回的值是当前指令的地址+4,PC(取指)= PC(执行) +4(16位的是两个字节,2*2)【这里出于对Thumb代码兼容,Thumb2既有16位的指令也包含32位的指令】
【复位序列】在离开复位状态后,CM3做的第一件事就是读取下列两个32位整数的值:
1:从地址0x0000_0000处取出MSP(默认使用MSP)的初始值
2:从地址0x0000_0004处取出PC的初始值(这个值是复位向量,LSB必须是1)
这与传统的ARM架构以及绝大多数的单片机不同,传统ARM架构总是从0地址开始执行第一条指令(0地址处一般总是一条跳转指令),在CM3中,0地址处提供MSP的初始值,然后紧跟的是向量表(向量表在以后还可以被移到其他的位置),向量表中存放的是32位的服务程序的地址(我们通过工具查看这些地址值时,他们的最低位都是1)
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |