痞子衡嵌入式:ARM Cortex-M内核那些事(6)- 系统堆栈机制
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是ARM Cortex-M堆栈机制。
今天给大家分享的这篇依旧是2016年之前痞子衡写的技术文档,花了点时间重新编排了一下格式。前面痞子衡讲过 《嵌入式里的堆栈原理》,本篇算是堆栈原理的工程实践,更具体点说是在ARM Cortex-M上的应用。ARM Cortex-M家族发展至今已经很多代,我们且以最简单的Cortex-M0为例来讲述堆栈机制:
1.基本规则
1.1 R13 / sp寄存器
R0-R12为通用寄存器,R13为系统堆栈指针sp,堆栈指针是用于访问堆栈,也即系统的RAM区。Cortex-M0中采用了两个堆栈指针:主堆栈指针(MSP)和进程堆栈指针(PSP),R13在任何时刻只能是其中一个,默认情况为MSP,可以通过控制寄存器(CONTORL)来改变。
MSP是系统复位后(即其处于Handler Mode)的指定sp(vector table的前4Byte自动载入),用于处理异常中断。当结束Reset_Handler后,cpu进入正常运行状态(即其处于Thread Mode),仅在此状态下PSP才能被使用,当然MSP也可以使用。其后如有硬中断来临,则进入Handler Mode,如果硬件中断结束,则返回Thread Mode。
关于MSP和PSP的选用,其是通过CONTORL寄存器来配置,仅在Thread Mode下才可设置CONTORL寄存器。一般情况下,没有必要使用PSP,除非是有os存在时,MSP用于os内核的sp,而PSP用于thread级app的sp,这两个sp需严格分开。
在编译器中,可以通过r13(R13)或sp(SP)来访问堆栈(具体是MSP和PSP由当时环境决定);也可以通过指定的MRS、MSR指令来访问MSP和PSP。
1.2栈结构
无OS的堆栈结构:
有OS的堆栈结构:
1.3栈操作
Cortex-M0中堆栈方向是向低地址方向增长,为满堆栈机制。堆栈操作是通过PUSH和POP来完成操作的。
栈一般放在ARM的 RAM高位区,如某MCU中RAM地址为0x20000000-0x20007fff,共32KByte。栈大小设为4KByte的话,其地址一般就放在0x20007000-0x20007fff,其中0x20007000为绝对栈顶,0x20007ffc为绝对栈底,sp总是指向相对栈顶。第一个PUSH数据被存在绝对栈底(此时绝对栈底也是相对栈顶)。实际上,除了POP指令可以从栈顶中取数据外;MOV指令也可从任意位置取数据,但不会影响栈结构(即不影响其sp)。
由于ARM寄存器均是32bit,故PUSH和POP指令均是32bit访问,故sp指针总是至少4Byte对齐(低2bit永远为0)。有时编译器也会分配8Byte对齐的栈,这是由于double浮点类型需要占用8Byte,为了处理方便,故将栈设为8Byte对齐。
2.入栈顺序
入栈顺序因编译器、处理器系统、OS而异,C语言中并没有强制规定入栈顺序,此处主要是讲ARM Cortex-M系列处理器在指定编译器情况下的入栈顺序。
2.1一般函数调用(通用)
上图展示了在一般函数(无参无局部变量无返回值)嵌套调用时,关于sp的操作。在执行BL FunctionA指令时,LR记录的是BL FunctionA的下一条顺序指令,在进入FunctionA后执行的第一条操作便是PUSH {LR}即将下一条顺序指令压入栈中,然后才开始执行FunctionA函数体。函数体执行结束之后,使用POP {PC}指令将栈顶数据弹到PC中,即可返回继续执行BL FunctionA的下一条顺序指令。
2.2极端函数调用(平台而异)
考虑一种极端情况来详细讲述入栈顺序,即函数含有4个参数以上,函数体内定义了多个局部变量,并且还有返回值。这个情况比较特殊,痞子衡专门在IAR上做过一次实验,详见下图:
至此,ARM Cortex-M堆栈机制痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。
痞子衡嵌入式:ARM Cortex-M内核那些事(6)- 系统堆栈机制的更多相关文章
- 痞子衡嵌入式:ARM Cortex-M内核那些事(9.1)- 存储保护(MPU - PMSAv6/7)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是ARM Cortex-M存储保护模块(MPU). <ARM Cortex-M内核MCU开发那些事>的内核篇连载最早是 201 ...
- 痞子衡嵌入式:ARM Cortex-M调试那些事(1)- 4线协议标准(JTAG)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式调试里的接口标准JTAG. 在结束<ARM Cortex-M文件那些事>系列文章之后,痞子衡休整了一小段时间,但是讲课的 ...
- 痞子衡嵌入式:ARM Cortex-M文件那些事(1)- 源文件(.c/.h/.s)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的source文件. 众所周知,嵌入式开发属于偏底层的开发,主要编程语言是C和汇编.所以本文要讲的source文件主要指的就是 ...
- 痞子衡嵌入式:ARM Cortex-M文件那些事(3)- 工程文件(.ewp)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的project文件. 前面两节课里,痞子衡分别给大家介绍了嵌入式开发中的两种典型input文件:源文件(.c/.h/.s). ...
- 痞子衡嵌入式:Ethos-U55,ARM首款面向Cortex-M的microNPU
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是ARM Ethos-U55. ARM 前几天刚发布了 Cortex-M 家族最新一款内核 - Cortex-M55 以及首款面向 Cor ...
- 痞子衡嵌入式:链接函数到8字节对齐地址或可进一步提升i.MXRT内核执行性能
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT上进一步提升代码执行性能的经验. 今天跟大家聊的这个话题还是跟痞子衡最近这段时间参与的一个基于i.MXRT1170的大项目有 ...
- 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(1) - 执行在不同CM内核下
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(1)之执行在不同CM内核下. 文接上篇 <RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计&g ...
- 痞子衡嵌入式:盘点国内RISC-V内核MCU厂商
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是国内RISC-V内核MCU厂商. 虽然RISC-V风潮已经吹了好几年,但2019年才是其真正进入主流市场的元年,最近国内大量芯片公司崛起 ...
- 痞子衡嵌入式:盘点国内RISC-V内核MCU厂商(2020年发布产品)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是国内RISC-V内核MCU厂商(2020). 虽然RISC-V风潮已经吹了好几年,但2019年才是其真正进入主流市场的元年,最近国内大量 ...
随机推荐
- 使用属性创建区域 (Creating Areas with Attributes) | 使用区域 | 高级路由特性 | 精通ASP-NET-MVC-5-弗瑞曼
- leetcode腾讯精选练习之螺旋矩阵(八)
螺旋矩阵 题目 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素. 示例 1: 输入: [ [ 1, 2, 3 ], ...
- Docker和Kubernetes
Docker和Kubernetes Docker Docker是一个容器的开放平台,但它不是最早的.自20世纪70年代以来,容器平台一直存在.他们的开发可以追溯到Unix中的chroot系统调用.在2 ...
- 《算法九》(A星寻路算法)
A星寻路: 结构:N叉树 直线代价斜线代价:符合勾股定理 代价:每走一步,距离终点所付出的 计算公式:f = g + h + w; f : 当前点到终点的代价 g : 起点到当前点的代价 h : 当前 ...
- 《考研机试》(一)C/C++基础
1.setfill/setw使用 2.定义结构体 3.关于字符串读取 4.排序问题:复试不要求一般用:冒泡排序 5.数字和字符之间转换 6.进制转化:10进制转8进制 7.质数判断 8.字符串拷贝函数 ...
- WTL Picture Control显示图片
1.在对话框上新建一个Picture Control ID为:IDC_STATIC_IMG 2.添加图片资源ID:IDB_BITMAP1(选中Bitmap点击导入,选择bmp图片资源) 实现: CWi ...
- webdriver高级应用 -更改一个对象界面的属性值
#-*- coding=utf-8 -*- #更改一个对象界面的属性值 from selenium import webdriver import unittest def addAttribute( ...
- D语言-认识D语言&安装
Part1: Something about "D" D语言在国外比较流行,在国内相当少的人才知道这个语言的存在 但是D语言有C++的效率,有Java的灵活 更重要的有两点: 1. ...
- postman之设置关联
接口关联(上一个接口的返回参数作为下一个接口的入参使用): 一:在第一个接口的test点击Response body:JSON value check和set an environment varia ...
- 基于MySQL+MHA+Haproxy部署高可用负载均衡集群
一.MHA 概述 MHA(Master High Availability)是可以在MySQL上使用的一套高可用方案.所编写的语言为Perl 从名字上我们可以看到.MHA的目的就是为了维护Master ...