首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

M3内核点滴记录

M3内核点滴记录

1:M3的系统控制块(SCB)中的VTOR(0XE000_ED08)寄存器:【7~28】向量表的起始地址,【29】向量表是在Code区(0),还是在RAM区(1);2:在keil环境中,编译器是通过***.sct分散加载文件来组织映像文件,分散加载文件中包含加载地址、运行地址以及哪一个段的位置(启动代码中的RESET代码段就被描述放在特定的地址中);
LR_IROM1 0x08000000 0x00040000 {    ; loadregion size_region
  ER_IROM1 0x08000000 0x00040000 {  ; load address = executionaddress
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00010000 {  ; RW data
   .ANY (+RW +ZI)
  }
}
3:M3的优先级
M3的异常,包括系统异常(15个系统异常:复位、NMI、hardfault、SysTick等,编号从1~15,0表示没有异常运行)与外部中断(总共240个,编号从16~255,NVIC最多支持1~240个外部中断IRQ,芯片具体支持多少个由芯片厂商设计),支持中断嵌套,使得高优先级的异常可以抢占低优先级的中断。
其中3个系统异常(复位、NMI、hardfault)有固定的优先级且都是负数级优先级,所以他们的优先级高于其他的所有可编程的优先级(非负),除这三个系统异常外,其他的异常与中断的优先级都是可以编程的。
因此M3拥有3个固定的高优先级与最多256级可编程的优先级。
M3所有可编程优先级的异常(系统异常与外部中断)都拥有一个对应的8位的优先级寄存器,且中断优先级的值(8位)又分为两个域:抢占域与亚优先(非抢占)域;高抢占域的异常可以抢占低抢占域的异常(这时不考虑亚优先级谁高谁低),如果两个异常抢占域相同,其中一个异常已在服务中,那此时不论另一中断的亚优先级是高或低都不能抢占它,而如果这两个中断同时出现,那么系统会先响应亚优先级高的中断;如果两个异常优先级完全相同,同时出现时则会优先响应异常编号小的那个异常。

重要规则:多个中断源在它们的抢占式优先级相同的情况下,子优先级不论是否相同,如果某个中断已经在服务当中,则其它中断源都不能打断它(可以末尾连锁);只有抢占式优先级高的中断才可以打断其它抢占式优先级低的中断。优先级分组规定:亚优先级至少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)

继承事业,薪火相传
返回列表