C语言上分为栈、堆、bss、data、code段。具体每个段具体是存储什么数据的,直接百度吧。重点分析一下STM32以及在MDK里面段的划分。
Code是存储程序代码的。
RW-data是存储初始化值不为0的全局变量。
Flash=Code + RO Data + RW Data;
这个是MDK编译之后能够得到的每个段的大小,也就能得到占用相应的FLASH和RAM的大小,但是还有两个数据段也会占用RAM,但是是在程序运行的时候,才会占用,那就是堆和栈。在stm32的启动文件.s文件里面,就有堆栈的设置,其实这个堆栈的内存占用就是在上面RAM分配给RW-data+ZI-data之后的地址开始分配的。
栈:是程序运行的时候局部变量的地方,所以局部变量用数组太大了都有可能造成栈溢出。
1、 工作模式 1) 在复位时处理器进入线程模式, 异常返回时也会进入该模式。 特权和用户(非特权)
2) 出现异常时处理器进入处理模式,在处理模式中,所有代码都是特权访问的。
代码可以是特权执行或非特权执行。 非特权执行时对有些资源的访问受到限制或不允许 权访问。 用户(非特权)访问。用户访问禁止: 2)对系统控制空间(SCS)的大部分寄存器的访问。
变线程模式的访问特权。处理模式始终是特权访问的。
结束复位后,所有代码都使用主堆栈。异常处理程序(例如 SVC)可以通过改变其在 栈指针 r13 是分组寄存器,在 SP_main 和 SP_process 之间切换。在任何时候,进程堆栈和主 除了使用从处理模式退出时的 EXC_RETURN 的值外,在线程模式中,使用 MSR 指令 3、关于STM32的 主堆栈指针 和 进程堆栈指针
在任务调度的代码中设置断点,任务调度过程一定不属于任何一个task。从断点看,任务调度过程使用的是MSP 继续debug,单步至调度过程结束,进入一个task代码,此时栈指针立刻切换到PSP。 4、结论
RTOS task运行时,使用的是当前task的栈,栈指针使用的是PSP
附:
map文件中,关于栈的起始地址和大小都有描述。起始地址即栈的栈底地址,栈顶地址为栈低地址加上栈大小的地址
startup文件中申请的heap内存管,如果没有被使用的话,会被编译器优化掉
|