你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32自定义stack和heap位置和大小

[复制链接]
smallcsduck 发布时间:2018-3-26 22:01
本帖最后由 smallcsduck 于 2018-3-27 05:05 编辑
4 _, A4 H1 \( x/ j9 \4 G; r, T7 A# o' q$ W6 Y4 A. _

     Stackheap是运行c运行环境比较重要的两个东西。默认的启动代码把他们是设立在sram里面的,那怎么把他们放在别的地方(比如外部sram)呢?这里用f407做例子,给大家介绍一下armc库推荐的标准做法。

2 x. @5 X( G6 }* R8 n0 X8 K  A

  首先在启动程序startup_stm32f407xx.s里面把这两段代码全部注释掉。

; y2 o; c0 E6 J. `8 i  |

2.png

1.png

  然后在向量表第一个字的位置要自己定义一个RAM地址。我这里是放在CCM里面。

4.png 3 u' s" q. i& l

9 d/ L1 |4 z9 e
4 p7 I/ _5 v4 E: l6 ?% e0 B& {

  这里要说明一下,这里设置的stack指针地址是芯片启动以后的stack指针地址。在你进入c环境的时候,c运行库首先会重新初始化stack地址和heap空间。所以这个地址在c环境运行起来以后就没用了。如果启动汇编程序在调用_main之前没用到任何c语言函数,那这stack地址都不用设置。(默认的启动汇编调用_main之前是用调用了一个LDR  R0, =SystemInit,一开始的stack就是为能运行这个SystemInit设置的。)

       然后在链接选项里面设置为自定义链接脚本。

3.png
. T1 m( h3 t& z* F2 `

  在链接脚本里面添加两个运行段。要注意的是这两个运行段范围不要与其他运行段重叠了。默认的链接脚本是sct文件,在mdk工程的Objects文件夹里。你可以在自动生成的sct基础上改。

5.png 7 m. ?; v. i7 E* y

   这里stack还是设置在CCM的最后。stack顶是0x1001000,大小是0x400Stack是从高地址往低地址增长的,所以是-0x400heap设置在外部sram里面。特别要注意的是这里是heapstack两块内存是分开的,需要在程序里加上编译控制。

6.png 4 o) f- k. E" m( @" T

       __asm(".global __use_realtime_heap\n\t");是指用heap算法里面的一种复杂算法,适合需要malloc大块空间,或者需要反复malloc和free的情况下用。这个算法有内存碎片合并的功能。不加这一句就是用的功能简单比较快的算法,反复malloc和free是会产生内存碎片的。上面是ARM Compiler6的写法,ARM Compiler5#pragma import(__use_realtime_heap)

   如果你使用了默认的stackheap合在一起的情况,那就可以不用这句__asm(".global __use_two_region_memory\n\t");。这种情况下链接脚本里直接定义一个ARM_LIB_STACKHEAP 运行段就可以了。上面是ARM Compiler6的写法,ARM Compiler5#pragma import __use_two_region_memory。

   另外既然heap被放在外部sram里面,你当然要先把外部sram初始化好。一般都是在void SystemInit(void)里面初始化的,这个是在c环境被初始化(_main)之前调用的。

   这样就好了,测试一下malloc,返回的地址就是在外部sram里面。

0 X3 _# g8 o8 y! c

   上面只是一种方法,C库的文档里说直接指定启动汇编里的__heap_base__initial_sp的值也是可以的,但是我没有成功过。哪位有成功的经验的可以分享一下。

         最后还有一些我想说一下。

         mallocfree是标准c库的内管管理功能。实现代码都是经过各种工业标准认证的,长时间运行是安全的。既然是Arm公司提供的c库,那肯定是为了arm构架做过特别优化的。性能上也是有保障的。所以推荐需要内存管理的还是用库里的mallocfree比较好。

   某些国内开发板的教程说,标准c库的malloc非常不好。在内存管理上都是自己去写了程序。我看了一下他们的代码,就是最简单的一个链表实现。什么数据对齐,垃圾回收,碎片整理,错误处理都没有。这种代码做个教学演示可以,你如果用到生产上,那肯定就是出现各种莫名其妙的问题。

   

   以上如有错误的地方,敬请指出。

& g  S% ~3 M3 C- ^  m

版权声明:本文为博主smallcsduck原创文章转载请注明出处 http://smallcsduck.blog.163.com

0 U- N6 N4 E5 G; p5 [& x6 L

+ K, ]' |6 Y( \6 b( N/ B  A
& ~* T1 k6 M# R) ^( ]: i7 m/ |

; G/ E  Y/ v- t% J

评分

参与人数 1 ST金币 +2 收起 理由
MrJiu + 2 赞一个!

查看全部评分

收藏 1 评论7 发布时间:2018-3-26 22:01

举报

7个回答
MrJiu 回答时间:2018-3-27 09:58:11
不错。。。支持一个。。。
琦子 回答时间:2018-3-27 10:27:51
额 遇到大神了 这不错 支持一个
STMWoodData 回答时间:2018-3-27 10:47:07
提示: 作者被禁止或删除 内容自动屏蔽
zero99 回答时间:2018-3-31 13:37:51
感谢分享,已更新到3月原创 https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
shanji 回答时间:2018-3-31 13:47:25
知识点啊,同学们
回答时间:2020-12-3 11:37:15
感谢分享
edmundlee 回答时间:2021-1-7 14:46:45
请问 这一句具体是该放在程序的哪儿 __asm(".global __use_two_region_memory\n\t");?: R" b  k1 f" q
" z, C0 L. U" z0 Z  s/ w* x) j

) D) F9 A% p: n/ ]3 i“C库的文档里说直接指定启动汇编里的__heap_base__initial_sp的值也是可以的”
: g/ H" [# ^) ]/ O, W可否贴一下这文档关于指定__heap_base的部分? 因为没找到C库里有文档
  E4 S* G6 @- H- m$ R4 Y

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版