stm32启动原理

stm32启动原理

非常建议仔细阅读启动过程详解

结论:

stm32系统启动的初始化过程是由汇编开始分配资源,设定函数基础后开始运行的,在所有汇编程序运行后,系统的运行交由项目中的main()函数,并由此开始以c为首的运行过程。这个过程中,很重要的一点是进行了系统运行前的内存分配,将硬件内存系统(初始时都是静态区)分割为堆区,栈区,静态区,其中,堆栈区原本就是从静态区中分割出来的,在汇编过程中从内存区中分割适合大小的位置给堆栈。对于ucos来说,剩余没有被分割的内存区域(静态区)就是可以用来做为ucos系统运行的内存堆栈基础。
对于ucos系统,任务切换过程中是将当前任务所使用寄存器里的数值保存到内存堆栈中,然后切换到另一个任务中,当切换回当前任务时,从堆栈中取回相应的寄存器数值,从上次执行的地方继续运行。可以认为ucos系统的内核即对内存堆栈的处理。这一部分的理解参考浅谈STM32堆栈与uCOS堆栈,其实是两码事!,在作者的实验中,表明了stm32设备sram对于初始化过程内存的分配原理。总结来说,stm32设备(暂定为stm32c8t6,该设备有64k的sram,范围是0x2000 000->0x2000FFFF),sram的使用是按照低地址到高地址的方式进行分配,需要注意的是,内存分配结束后,没有用到的部分就不会再进行分配了,所有资源的分配在代码编译结束时就结束了,不存在运行时去分配sram中未使用到的内存的情况,在了解这点后再来分析下其分配方式,首先stm32编译过程产生的静态/全局/常量指针从0x2000 0000开始递增占用内存,然后是堆,最后是栈。栈是以高地址向低地址方向增长的结构,也就是有一个栈顶__initial_sp,栈以该值开始递减,直到抵达堆栈的分界范围,再增加就是堆的范围了,如果运行过程中突破了该范围即称堆栈溢出,此外该字段表明了程序编译结束后使用的最大内存量,程序开始运行后,所有的内存地址都不会超过该值,在多数情况下,该值不会指向0x2000 FFFF,除非你的设备编译的确使用了如此大的内存,由此可以知道内存分配不会刚好是64k,而是以代码编译的最终结果定下系统最终运行占用的内存大小。sram的结构图可以参照如下
sram分配方式
也可增加一个静态数组自己动手测试
test1
在.map文件中查看当前栈顶的地址为:0x2000a888
test2
增加一个静态数据后,栈顶地址变为:0x2000b888
简单计算0x2000b888-0x2000a888=4000(hex)=4k,刚好为大小1024的int(4字节)类型数组的大小。

参考

ARM汇编编程基础(一) – ARM CPU寄存器

ARM中的寄存器(R0-R15)

同时,对于不同任务分配的内存空间的利用率,有网友以使用量分析的方式实现内存利用率的最大化,参考uCOS-III任务堆栈溢出检测及统计任务堆栈使用量的方法

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值