Cortex-M CPU架构基础

不同于老的经典arm处理器(例如:ARM7,ARM9),ARM Cortex-M 处理器有一个非常不同的架构,Cortex-M是一个家族系列,其中包括Cortex M0/M3/M4/M7多个不同型号,每个型号之间会有些区别,例如Cortex-M4比Cortex-M3多了浮点计算功能等,但它们的编程模型基本是一致的。

寄存器简介

Cortex-M系列CPU的寄存器组里有R0~R15共16个通用寄存器组和若干特殊功能寄存器,如图所示:

Cortex-M CPU架构基础_第1张图片

通用寄存器组里的R13作为堆栈指针寄存器(Stack Pointer,SP);R14作为连接寄存器(Link Register,LR),用于在调用子程序时,存储返回地址;R15作为程序计数器(Program Counter,PC),其中堆栈指针寄存器可以是主堆栈指针(MSP),也可以是进程堆栈指针(PSP)。

特殊功能寄存器包括程序状态字寄存器组(PSRs)、终端屏蔽寄存器组(PRIMASK、FAULTMASK、BASEPRI)、控制寄存器(CONTROL),可以通过MSR\MRS指令来访问特殊功能寄存器,例如:

MRS   R0,  CONTROL  ;读取CONTROL到R0中

MSR   CONTROL,   R0 ;写入R0到CONTROL寄存器中

程序状态字寄存器里保存算术与逻辑标志,例如负数标志,零结果标志,溢出标志等等。中断屏蔽寄存器组控制Cortex-M的中断除能。控制寄存器用来定义特权级别和当前使用哪个堆栈指针。

如果是具有浮点单元的COrtex-M4或者Cortex-M7,控制寄存器也用来指示浮点单元当前是否在使用,浮点单元包含了32个浮点通用寄存器S0-S31和特殊FPSCR寄存器(Floating point status and control register)。

操作模式和特权级别

Cortex-M引入了操作模式和特权级别的概念,分别为线程模式和处理模式,如果进入异常或中断处理则进入处理模式,其他情况则为线程模式。

Cortex-M CPU架构基础_第2张图片

Cortex-M有两个运行级别,分别为特权级和用户级,线程模式可以工作在特权级或者用户级,而处理模式总工作在特权级,可通过CONTROL特殊寄存器控制,工作模式状态切换情况如上图所示。

Cortex-M的堆栈寄存器SP对应两个物理寄存器MSP和PSP,MSP为主堆栈,PSP为进程堆栈,处理模式总是使用MSP作为堆栈,线程模式可以选择使用MSP或PSP作为堆栈,同样通过CONTROL特殊寄存器控制。复位后,Cortex-M默认进入线程模式、特权级、使用MSP堆栈。

嵌套向量中断控制器

Cortex-M中断控制器名为NVIC(嵌套向量中断控制器),支持中断嵌套功能。当一个中断触发并且系统响应时,处理器硬件会将当前运行位置的上下文寄存器自动压入中断栈中,这部分的寄存器包括PSR、PC、LR、R12、R3-R0寄存器。

Cortex-M CPU架构基础_第3张图片

当系统正在服务一个中断时,如果有一个更高优先级的中断触发,那么处理器同样会打断当前运行的中端服务程序,然后把这个中断服务程序上下文的PSR、PC、LR、R12、R3-R0寄存器自动保存到中断栈中。

PendSV系统调用

PendSV也称为可悬起的系统调用,它是一种异常,可以像普通的中断一样被挂起,它是专门用来辅助操作系统进行上下文切换的。PendSV异常会被初始化为最低优先级的异常。每次需要进行上下文切换的时候,会手动触发PendSV异常,在PendSV异常处理函数中进行上下文切换。

中断向量表

中断向量表是所有中断处理程序的入口,把一个函数(用户中断服务程序)同一个虚拟中断向量表中的中断向量联系在一起。当中断向量对应中断发生的时候,被挂起的用户中断服务函数程序就会被调用执行。

Cortex-M CPU架构基础_第4张图片

在Cortex-M内核上,所有中断都采用中断向量表的方式进行处理,即当一个中断触发时,处理器将直接判定是哪个中断源,然后直接跳转到相应的固定位置进行处理,每个中断服务程序必须排列在一起放在统一的地址上(这个地址必须要设置到NVIC的中断向量偏移寄存器中)。中断向量表一般由一个数组定义或在起始代码中给出,默认采用起始代码给出:

__Vectors   DCD      __initial_sp               ; Top of Stack
            DCD      Reset_Handler              ; Reset 处理函数
            DCD      NMI_Handler                ; NMI 处理函数
            DCD      HardFault_Handler          ; Hard Fault 处理函数
            DCD      MemManage_Handler          ; MPU Fault 处理函数
            DCD      BusFault_Handler           ; Bus Fault 处理函数
            DCD      UsageFault_Handler         ; Usage Fault 处理函数
            DCD      0                          ; 保留
            DCD      0                          ; 保留
            DCD      0                          ; 保留
            DCD      0                          ; 保留
            DCD      SVC_Handler                ; SVCall 处理函数
            DCD      DebugMon_handler           ; Debug Monitor 处理函数
            DCD      0                          ; 保留
            DCD      PendSV_handler             ; PendSV 处理函数
            DCD      SysTick_handler            ; SysTick 处理函数

... ...

NMI_Handler          PROC
            EXPORT  NMI_Handler                 [WEAK]
            B        .
            ENDP
HardFault_Handler    PROC
            EXPORT  HardFault_Handler           [WEAK]
            B        .
            ENDP
... ...

以SysTick中断为例,在系统启动代码中,需要填上SysTick_Handler中断入口函数,然后实现该函数即可对SysTick中断进行响应。

你可能感兴趣的:(Cortex-M)