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

调试调到怀疑人生,heap我对你的误解有多深

[复制链接]
watershade 发布时间:2019-4-2 21:41
这几天在调试自己写的一个FreeRTOS的程序。程序稍微有点大,用的是F0内核的MCU。ROM只有16K。7 X4 }# u" V: D/ ^$ W/ E# M* E- @
因为我的程序内部要自己用allloc开辟一部分空间,而因为使用了多个任务和MailQueue整个空间的占用可想而知。: M" _. E, Z2 h% E; w6 r
所以我设置FreeRTOS的heap空间5120,考虑到别的占用。所以总共分的heap是5K+2K。这时候RTOS跑不起来了。0 r* x& r% r( a  \
当然我的Stack也分了2K。所以我谨慎的分了8K,还不行。这时候我把FreeRTOS的heap空间扩大了。这时候竟然连编译都通不过了。
3 i8 Y: y) n& e2 z我还在怀疑是不是我的程序有什么问题。
4 C/ [+ l, t% j& f% W! o直到今晚,我才解开这个问题。只怪我学艺不精,对heap的理解有点想当然。(差不多有快一年没有耐心做大项目了,所以之前掌握的本就似是而非的知识就成了埋在调试路上的陷阱。)' m5 v/ k* F' Y) S0 \% I6 a
原来,F0和其它的系列是一样的。都是双堆栈指针:MSP(Main Stack Pointer主堆栈指针)和PSP(Process Stack Pointer)。这种设计非常适合RTOS的设计。MSP顾名思义是给系统栈使用的。PSP是给进程栈使用的。在RTOS运行中,整个栈空间是由PSP管理的。而切换到ISR中则使用MSP。; Z2 T) a5 K$ P2 Q# A$ y4 |% V
这点其实我是知道的,知识印象有些模糊。但我真正不知道的在于下面一点。.s文件中的heap只管分配给MSP。
9 W7 J" W; \, s8 E# SSTM32cubemx中有个简单的估算heap大小的方法。(因为不包含MailQueue,所以尺寸你可以适当在上面增加一下mempool的大小。)我习惯的做法就是将两个数加起来设置一下heap但是这次遇见问题了。我给.s文件中的heap设置的越大,就表示msp管理的heap越大,因为整个空间有限。我的psp占用的栈就小了。所以在我上面的列子中。psp也许需要超过5K的空间,这时候因为我的MSP分配的多了。就导致编译通不过。这时候我就设法扩大PSP的空间,但是因为理解错误,我就需要确保.s分配的空间大于5K。所以这时候我发现我的FreeRTOS的最大空间不能扩大了。$ U: S3 ~1 V/ u! M
/ E' F% r4 r  p8 }7 b9 e# g/ S  J) C
那现在整么解决呐。很简单就是把.s的空间设置小一点。不如2K。一般够我的程序用了。而stack也是2k。所以我的FreeRTOS的heap配置可以扩大。比如8K.这时候我发现问题解决了。那一切问题就要有官方介绍才成。0 o# `' _+ k! {6 {5 P, c) D

2 R: P! C( d. B; S0 carm官网的介绍:http://www.keil.com/support/docs/4049.htm 这里面给了几个链接说明。可以看一下。: Q/ G4 S$ Z5 t9 `8 n; B
mainSteak.jpg
+ f) K  P9 v* F
, _- f7 W1 m3 t& e* T这个问题无意间才发现的。要不是调试调到怀疑人生,我将会对.s的heap误解越来越深。
9 t+ m- q$ V" m3 z) v. w7 ^; i
收藏 3 评论12 发布时间:2019-4-2 21:41

举报

12个回答
watershade 回答时间:2019-4-3 00:34:06
本帖最后由 watershade 于 2019-4-3 17:19 编辑
% @9 a0 d" ^! M( r5 f5 N' k/ |, f, V& J1 t: U9 J
帖子应该移到哪个区?(谢谢管理员将它移动到了RTOS区)+ o+ B. a0 V8 a0 {1 M6 w
jeffhe1 回答时间:2019-4-3 08:39:26
真是大神, 厲害的文章
一代睡神的崛起 回答时间:2019-4-3 08:41:56
谢谢分享,学习了
: J1 Y0 X( `6 Y( w! m" u& n
sky_han 回答时间:2019-4-3 08:58:11
。MSP顾名思义是给系统栈使用的。PSP是给进程栈使用的。在RTOS运行中,整个栈空间是由PSP管理的。而切换到ISR中则使用MSP。, b% a: |1 K# L* U/ A* N$ R

* ]* s, \: J6 h8 K& s1 M: J$ k这个是大家都知道的,不知道的是?5 x7 A" C" v9 I7 _/ y

) c) Z7 Y' |. W  f( `0 ^$ |MSP和PSP各有各自的HEAP。
" ~! R& K4 |& H( G' S
. Z6 e3 O( I; r  l
tanic 回答时间:2019-4-3 09:46:59
MSP用的.s分配的   PSP用的rtos 通过宏分配的?
七哥 回答时间:2019-4-3 10:02:07
tanic 发表于 2019-4-3 09:46
" P6 d" \2 d/ U0 q3 hMSP用的.s分配的   PSP用的rtos 通过宏分配的?
: g' w' {8 L3 W; \5 d
学习了
Kevin_G 回答时间:2019-4-3 10:11:40
厉害
watershade 回答时间:2019-4-3 17:17:25
tanic 发表于 2019-4-3 09:46
6 N. B# I0 R3 d! Z) A: ZMSP用的.s分配的   PSP用的rtos 通过宏分配的?
% L  i5 j  L, h1 P5 X, k
是的
watershade 回答时间:2019-4-3 17:18:00
sky_han 发表于 2019-4-3 08:58+ n% \2 d& n. X' J6 G$ \( u
。MSP顾名思义是给系统栈使用的。PSP是给进程栈使用的。在RTOS运行中,整个栈空间是由PSP管理的。而切换到I ...

3 o4 U" t* V  E我不知道的是.s只管msp
Cortexxx 回答时间:2019-4-9 09:30:01
有个小问题
8 |$ {& m9 ?8 ?- h2 q7 U' V
  1. xTaskCreate(FactoryTask,"Factory",128, 0, 3, NULL);
复制代码
  1.         BaseType_t xTaskCreate(        TaskFunction_t pxTaskCode,
    / L$ N* z& F! b0 t; p' X# ]
  2.                                                         const char * const pcName,- a7 M, m" Q% t, H" Q
  3.                                                         const uint16_t usStackDepth,/ x- n/ [3 s- m" n: c8 T% Y, N/ d8 H
  4.                                                         void * const pvParameters,
    & X3 \! |( H; ~* f
  5.                                                         UBaseType_t uxPriority,# ~; L' r& V7 U1 T1 u$ d
  6.                                                         TaskHandle_t * const pxCreatedTask ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
复制代码

/ W+ O' y, y" ~; u! d7 a1 ^( q6 u
这个代码的第三个参数 128 申请的是stack还是Heap? 6 p# ?0 e9 E2 X  F( U4 h) w
我进到这个function里面看到它用malloc开了一块内存,故认为是开辟的是heap空间,$ y' C% p5 R1 t$ `: p7 F. B" G
但是他的形参名称为什么是 StackDepth。 这点我就很糊涂了,到底这个128*4 stack 还是heap?
watershade 回答时间:2019-4-15 13:06:24
Cortexxx 发表于 2019-4-9 09:30
* w) T0 D; w  Y7 b+ ]有个小问题

5 ?! }' ~9 C$ r8 Q1 i1 |不好意思,这几天没有看论坛。
1 E3 n8 j' N% q; w  L下图是从freeRTOS v10.0.0的手册上截图的。(这个手册freeRTOS官方可免费下载) frtos_heap_stack.jpg - f& C& Y; o3 y+ U4 b/ b' i
手册提到了动态创建和静态创建两种内存分配方法。我的上面提到的TOTAL_HEAP_SIZE其实只在动态创建的时候才有效.  f3 Q" {4 I9 {2 O) I
在动态分配的时候,需要先指定heap的总共大小。但这段memory并不是划出来不用的。所有的task,queue和semaphore创建的时候都要从这里面划分。而对于任务的动态创建,TCB和stack都是从heap里面分配的。但如果使用静态创建,那这个任务就是在编译环节分配的。不是程序在heap里面动态分配的。
" B% s1 j+ u8 ~( q6 `+ j/ O
7 E: Y' `0 D2 {8 G( a/ J( p) F; u~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~& Y9 ?* D# z3 E3 e5 j4 t$ ~
如果你看st封装的cmsis-rtos,他的程序创建使用的是osThreadCreate.而freeRTOS的memory allocation分为三种:一种是Dynamic,另一种是Static,第三种是Dynamic/Static。但本质上使用的还是上图提到的两个functions:xTaskCreate和xTaskCreateStatic! c" V# `$ Q1 g9 S* T0 [
图片里展示了主要的内容。你可以试着将memory allocate改成static,你会看到heap的大小选择没有了。+ O' H" L% Q+ l8 o2 o2 {" @8 G
frtos_heap_stack_2.jpg frtos_heap_stack_3.jpg
6 Y# Q! i( w3 c2 q; }5 t% o4 n; _* N: S( v, |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~, W, Y/ e' C0 c0 ?# _) U
这是我个人的理解,如果你有疑问或者不同意。可以留言给我,咱们交流交流。谢谢
9 V$ c+ Q0 v+ o1 h
Cortexxx 回答时间:2019-4-16 08:56:04
watershade 发表于 2019-4-15 13:06
- e# \  j; y: p9 L5 x4 c% J* {不好意思,这几天没有看论坛。- U$ {5 |+ O2 I
下图是从freeRTOS v10.0.0的手册上截图的。(这个手册freeRTOS官方可免费 ...
! i, t, Y( X, E* q4 u9 M
感谢回复 了解了 XDDD5 Z) G3 h6 x- Q/ N+ ~* D( @* l. n

所属标签

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