1.存储器
(1).ROM 只读存储器,掉电不丢失
(2).RAM 临时存储器也称内存,掉电丢失
(3).堆区
·堆区用于存放程序运行中被动态分布的内存段,可增可减。
·有malloc函数分布的内存,必须用free进行内存释放,否则会造成内存泄漏。
(4).栈区
·临时创建的局部变量存放在栈区。
·函数调用时,其入口参数存放在栈区。
·函数返回时,其返回值存放在栈区。
(5).全局区(静态区)
全局区有.bss段和.data段组成,可读可写。
.bss段
·未初始化的全局变量存放在.bss段。
·初始化为0的全局变量和初始化为0的静态变量存放在.bss段。
·.bss段不占用可执行文件空间,其内容有操作系统初始化。
·已经初始化的全局变量存放在.data段/以及const定义的全局变量。
·已经初始化静态变量存放在.data段。
·.data段占用可执行文件空间,其内容有程序初始化。
(6).常量区
·字符串存放在常量区。
(7).代码区
·程序执行代码存放在代码区。
ROM用来存放代码区和常量区
RAM用来存放堆区、栈区、全局区
在Cortex M3架构的芯片运行时,根据ROM上电不丢失的特性,芯片使用它用来存储用户烧录的代码和代码中的常量,芯片上电后,芯片运行会自动加载全局变量、局部变量到RAM中。
2.寄存器组(R0-R15)
在cortex M3架构的芯片寄存器中主要有通用寄存器寄存、堆栈指针、连接寄存器、程序计数器,
(1).R0-R12:通用寄存器
R0‐R12 都是 32 位通用寄存器,用于数据操作。
作用:它的存在主要是存放入口参数、返回参数、局部变量、临时计算结果
(2).SP堆栈指针:
Cortex‐M3 拥有两个堆栈指针,然而它们是 banked,因此任一时刻只能使用其中的一个。
堆栈指针指向的堆栈,是因为在寄存中和同指针只有
主堆栈指针( MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程)
进程堆栈指针( PSP):由用户的应用程序代码使用。
作用:在内核刚启动时,OS处于hander mode(也就是操作系统常说的内核态),OS的内核函数(例如异常中断函数、其他中断函数等其他内核函数)使用的是MSP堆栈指针,当芯片启动成功,且未产生任何异常,os自动切换为线程模式,堆栈值指针选为PSP。
Sp的属性选择靠什么实现呢?
那这里就需要引入控制寄存器(CONTROL)
SP的定义选择,主要是靠CONTROL寄存器实现,当该寄存器为1时,选择进程堆栈指针,当该寄存器为时,选择主堆栈指针。
那有人就会想了,明明它的存在就只是存储堆栈指针,无论是内核函数的堆栈指针还是线程模式下的堆栈指针,它不都是个指针吗,为什么需要用CONTROL寄存器去区分堆栈指针选择MSP和PSP?
首先推荐一篇文章,这篇文章详细讲解了MSP\PSP\SP,之间的关系,以及区别。
RTOS系列文章(6):Cortex-M3/4之SP,MSP,PSP,Thread模式、Handler模式、内核态、用户态_arm sp msp psp-CSDN博客
上图讲解了main堆栈指针是确定的,os程序、内核程序、ISR(中断服务程序)能够访问,这时寄存器sp属性选择MSP,它既可以指向主堆栈指针,又可以指向任务堆栈指针。而任务堆栈指针,只能指向任务堆栈。
在RTOS中,有一片特定堆栈空间专为异常和中断而生,并且这片空间只能在特权级线程模式下能访问,也就是说当control寄存器为0时才能访问,为啥呢?因为这时SP属性选择为msp,此时的SP它能够访问此片空间,而当系统处于用户级线程模式下,也就是control寄存器为1时不能访问,此时SP属性选择为PSP,他不能访问此片空间,他只能访问任务堆栈指针。那我们在转成定义就可以这样说,系统会限制用户直接访问系统资源。
(3).LR连接寄存器:
R14 是连接寄存器( LR)。主要用于存储子程序调用时的返回地址。当发生函数调用时,当前的程序计数器(PC)值会被保存到LR中,以便函数执行完成后能够正确返回调用点。
作用:
裸机中,当程序正在函数1时,此时调用到函数2,此时函数1会被装载在栈区,函数2会从ROM装载进寄存器中运行,装载时函数1的堆栈地址会储存在寄存器LR中,这样函数2运行结束时就能通过访问LR寄存器的指针,返回到函数1继续运行。
在操作系统(OS)中,除了包含上述作用,LR在任务切换和异常处理等场景中也起着重要作用:
任务切换:当操作系统切换任务时,它需要保存当前任务的上下文信息(包括LR寄存器的值),以便稍后能够恢复任务的执行。LR保存了任务在切换前的返回地址,当任务被重新调度时,通过恢复LR的值,任务可以从中断点继续执行。
异常处理:当发生中断或异常时,Cortex-M3会自动保存上下文,包括PC和LR的值。LR在此时用于标记异常返回类型,具体表现为LR保存特殊的返回值(如0xFFFFFFF9或0xFFFFFFFD),用于指示在异常处理完成后,系统应该返回到哪种堆栈(主堆栈MSP还是进程堆栈PSP)以及恢复到特权模式或用户模式。
0xFFFFFFF9:返回到特权模式,使用MSP。
0xFFFFFFFD:返回到用户模式,使用PSP。
异常返回:当异常处理结束时,系统根据LR的值决定如何返回原任务。不同的LR值会影响系统返回时恢复哪种上下文(如用户模式或特权模式),并决定是否使用MSP或PSP。
(4).PC程序计数器:
R15 是程序计数器,在汇编代码中你也可以使用名字“PC”来访问它。
作用:通过它,我们可知道一个函数调用一个函数,被调用的函数结束时,这个函数运行在哪一条指令流(代码对应的二进制指令)。
该文章只是我学习上的一些总结,希望大家有自己的总结欢迎在评论区讨论。