Cortex-M3那点事

Cortex-M3 的 双堆栈MSP和PSP 在裸机开发中,CONTROL的bit1始终是0,也就是说裸机开发中全程使用程MSP,并没有使用PSP。在执行后台程序(大循环程序)SP使用的是MSP,在执行前台程序(中断服务程序)SP使用的是MSP。栈是一种先进后出的数据结构(类似于枪支的弹夹,先放入的子弹最后打出,后放入的子弹先打出)。M3内核的堆栈也不例外,也是先进后出的。在OS开发中,当运行中断服务程序的时候CONTROL的bit1是0,SP使用的是MSP;当运行线程程序的时候CONTROL的bit1是1,SP使用的是PSP。 阅读详情


一:寄存器组

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.youkuaiyun.com/fanwenjieok/article/details/6316058

ARM单片机中断处理过程解析 所以当中断嵌套加深时,对主堆栈的压力会增大:每嵌套一级,就至少再需要8个字,即32字节的堆栈空间(这没算上 ISR 对堆栈的额外需求),并且何时嵌套多少级也是不可预料的。比如,若在响应某低优先级 异常#1 的早期,检测到了高优先级 异常#2,则只要 #2 没有太晚,就能以“晚到中断”的方式处理:在入栈完毕后执行ISR #2。当 CM3 对某异常的响应序列还处在早期:入栈的阶段,尚未执行其服务例程时,如果此时收到了高优先级异常的请求,则本次入栈就成了为高优先级中断所做的了。中断,在单片机开发中再常见不过了。 阅读详情

相关推荐

Arm ContxM FreeRTOS MSP之间PSP相互切换

FreeRTOS 创建线程的时候,事先往堆栈中保存EXC_TURN值,然后做线程切换的时候,先把保存的EXC_TURN值反映到CPU寄存器,这样执行线程的时候就变成了PSP.也就是说线程的时候使用PSP是人为设置的.相反MSP是硬件自己完成的,比如当发生中断后,执行中断函数的时候硬件吧SP改成MSP.代码从main()函数开始执行的时候,栈默认是MSP开始.当创建线程后从main函数切换到线程的时候,栈从MSP->PSP. 这个过程如下.4.执行线程的代码,除非线程结束,不然不会再继续main()函数。

cxtian55555的博客 1265

Cortex-M系列,MSP和PSP区别

比如,当应用程序发生栈溢出问题时,必须要确保应用程序的故障不会影响到操作系统的运行和异常事件的处理——也就需要保证始终要有栈空间来执行异常事件。例如,如果一个任务发生了堆栈溢出,我们需要确保这个问题不会影响到操作系统的运行和异常处理——也就是说,我们需要确保始终有足够的堆栈空间来处理异常。这就是MSP的作用,它为操作系统和异常处理程序提供了一个独立的堆栈。在Cortex-M系列中,引入MSP(主堆栈指针)和PSP(进程堆栈指针)的主要原因是为了实现操作系统的安全性和稳健性。

我的博客 4028

Cortex-M0和Cortex-M0+简介

一 Cortex-M0到Cortex-M0+ TODO: ARM处理器家族 Cortex-M0处理器于2009年发布,是一款具有开创性的产品,因其实第一个将32位处理器在同8位和16位处理器差不多大小的硅片实现的,在保持可用性的同时还具有极佳的能耗效率,并且对于32位处理器而言,它的性能也是可以接受的。 尽管Cortex-M0处理器比Cortex-M3(于2003年发布)处理器小的多,它还是保留了Cortex-M3处理器的许多特性: 利用内置名为NVIC的中断控制器实现灵活的中断管理; OS支持特性 高代

ching的专栏 3万+

关于CM3内核的PSP和msp

操作系统也要遵循我从哪来,要干什么,到哪去的基本规则。

xiaoxuechong的博客 1490

ARM架构—— Cortex-M3与Cortex-M4特点概述

哈佛结构是一种将程序指令存储和数据存储分开的存储器结构。哈佛结构是一种并行体系结构,它的主要特点是将程序和数据存储在不同的存储空间中,即程序存储器和数据存储器是两个独立的存储器,每个存储器独立编址、独立访问。两个存储器相对应的是系统的4条总线,即程序的数据总线与地址总线数据的数据总线与地址总线。这种分离的程序总线和数据总线可允许在一个机器周期内同时获得指令字(来自程序存储器)和操作数(来自数据存储器),从而提高了执行速度,进而提高了数据的吞吐率。

m0_61973119的博客 4958

【ARM Cortex-M3指南】2:Cortex-M3综述

带你了解Cortex-M3处理器,希望能够帮助到大家。

伟大的心胸,应该表现出这样的气概——用笑脸来迎接悲惨的厄运,用百倍的勇气来应付一切的不幸。 3106

从Cortex-M3到A8:聊聊MMU和MPU那点事,以及它们如何影响你的Linux移植

本文深入探讨了MMU和MPU在嵌入式Linux移植中的关键作用,从Cortex-M3到A8平台的转换过程中,内存管理单元的差异对系统性能和安全性的影响。通过对比MMU的动态分页与MPU的固定区域配置,帮助开发者理解如何在不同场景下选择合适的内存管理策略,提升嵌入式系统的开发效率。

weixin_30905981的博客 313

cortex-M3/M4 指令集

一、理解汇编语言用法 ARM汇编(适用于ARM realview工具链 DS-5 Keil微控制器开发套件)指令格式如下: label ​ mnemonic operand1,operand2, … ;注释 label(标号)表示地址位置,是可选的。有些指令的前面可能会有标号,这样就可以通过这个标号得到指令的地址。标号也可以用于表示数据地址。例如,可以在程序内的查找表处放一个标号。mnemonic为助记符,也就是指令的名称,其后跟着的是多个操作数。 对于在ARM汇编器中编写的数据处理指令,第一个操

u011728490的博客 8009

【ARM Cortex-M 系列 1 -- Cortex-M0, M3, M4, M7, M33, M35P 差异】

Cortex-M0 是 ARM 公司推出的一款微控制器(MCU)核心。这个核心是基于ARMv6-M架构设计的,只支持 56 条指令的小指令集,大部分指令是 16 位指令, 是 ARM Cortex-M 系列中的入门级产品。Cortex-M0 的设计目标是提供一种低成本、低功耗的解决方案,适用于简单的微控制器应用。它的特点包括:小型和低功耗:Cortex-M0 的硬件设计非常紧凑,消耗的功率也非常低,这使得它非常适合在功率和空间受限的应用中使用。简单的指令集:Cortex-M0 使用的是。

CodingCos的博客 3万+

解读《ARM Cortex-M3 与Cortex-M4 权威指南》——第1章 ARM Cortex-M处理器简介

Cortex-M3处理器可以执行一些数字信号处理(DSP)相关的任务,但它并不具备专门为DSP设计的指令集和硬件加速功能。具体来说,Cortex-M3支持基本的定点运算和一些简单的数学操作,但缺少Cortex-M4所提供的SIMD(单指令多数据)、快速乘法累加(MAC)和饱和运算等专用指令。因此,虽然Cortex-M3能够进行一些基本的数字信号处理,但在性能和效率上不如Cortex-M4。对于需要复杂数字信号处理的应用,Cortex-M4更为合适,因为它的设计更能满足这些需求。

makabaka2020的博客 1270

Cortex-M3 SoC的启动过程

介绍从C语言程序的编写到在裸机上运行的详细流程 基本概念 几种不同类型的存储器 在过去的20年里,嵌入式系统一直使用ROM(EPROM)作为它们的存储设备,然而近年来Flash全面代替了ROM(EPROM)在嵌入式系统中的地位,用作存储Bootloader以及操作系统或者程序代码或者直接当硬盘使用(U盘)。 ...

北枫凉的博客 4682

Cortex-M3架构学习

Cortex-M3架构学习笔记

kkbbaaii的博客 3433

已解决-Parallels Desktop 16 网络初始化失败:您的虚拟机将继续正常运作,但将无法连接网络

我是月球挖掘机,相信不少打工人为了尝鲜已经更新了MacOS 11 Big Sur,当然,苹果每次的系统大更新,都会给我们软件的功能无法使用惊喜,这次的也不例外。 这个问题是我在更新macOS Big Sur之后,Parallels Desktop打开虚拟机后,提示: 报错信息 网络初始化失败:您的虚拟机将继续正常运作,但将无法连接网络 这是我的软件版本: 起初我以为是我的虚拟机坏了,结果重装了一遍虚拟机,没有任何用处。我开始在网上找方法,只能找到那个使用命令行打开软件的命令,除此之外没有了

月球挖掘机 5万+

Cortex-M3概述

Cortex-M3概述 转载至:https://blog.youkuaiyun.com/bulebin/article/details/74093147 MCU的主要组成有:内核、储存器、外设。大部分刚接触MCU的人员一般是从关注外设的使用开始,但对于要深入理解MCU工作原理,了解MCU的内核、储存器这两部分内容是很有必要的。本文将以Cortex-M3内核为例对MCU的内核做一个简要分析。主要关注以下三个问题: 问题一、定义:Cortex-M3内核是什么? 问题二、结构:Cortex-M3架构是怎么样的? 问

学海无涯的专栏 1万+

【mip-NeRF】使用一组二维图像渲染3D场景视频(mip-NeRF论文复现)

本文对mip-NeRF模型的pytorch实现进行了复现

Ryan2k的博客 1841

新手强化学习—深入解析 YOLOv13 项目包中的文件结构和各文件作用

YOLOv13是YOLO系列最新发布的计算机视觉模型。在这篇博客中,我将深入分析YOLOv13中各个文件的作用,对整个项目的文件结构有更清晰的认识。

Limiiiing的博客 482

ARM Cortex-M3/M4内核相关

1、什么是ARM Cortex-M处理器 1.1、Cortex-M3和Cortex-M4处理器 Cortex-M3(2005年发布)和Cortex-M4(2010年发布)处理器是ARM公司设计的处理器。 Cortex-M3和Cortex-M4处理器使用32位架构,寄存器组中断内部寄存器、数据以及总线接口都是32位。Cortex-M处理器使用的指令集架构(ISA)是Thumb ISA(是一种RISC(精简指令集)),其基于Thumb-2技术并同时支持16位和32位指令。 主要有以下特点: 三级流水线

taoking123的博客 1万+

UDF学习(二)基础数据类型与常见宏

thread_loop_c (t,d) 必须与begin_c_loop (c,t)同时使用,但begin_c_loop (c,t)不一定与thread_loop_c (t,d)同时使用。同理thread_loop_f(t,d)必须与begin_f_loop (c,t)同时使用,但begin_f_loop (c,t)不一定与thread_loop_f(t,d)同时使用。begin_c_loop (c,t) 在计算域内对网格单元进行循环。c_face_loop (c,t)遍历网格单元上的所有网格面。

weixin_44386973的博客 855
上一篇: LDR指令
下一篇: Declaring Attributes of Functions
Alan0521
博客等级 码龄19年 77粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值