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

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

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

" h4 B" m7 l4 A: F9 W这个问题无意间才发现的。要不是调试调到怀疑人生,我将会对.s的heap误解越来越深。* |4 E; m$ F, {- V. n
赞 收藏 3 评论12 发布时间:2019-4-2 21:41

举报

12个回答
watershade 回答时间:2019-4-3 00:34:06
本帖最后由 watershade 于 2019-4-3 17:19 编辑
6 |7 t2 w, a" D3 Z5 O! V+ k8 I9 T' O- }
帖子应该移到哪个区?(谢谢管理员将它移动到了RTOS区)
& [5 R) |1 a9 Y+ |5 t9 k
jeffhe1 回答时间:2019-4-3 08:39:26
真是大神, 厲害的文章
一代睡神的崛起 回答时间:2019-4-3 08:41:56
谢谢分享,学习了3 O% z" p0 \4 b2 m
sky_han 回答时间:2019-4-3 08:58:11
。MSP顾名思义是给系统栈使用的。PSP是给进程栈使用的。在RTOS运行中,整个栈空间是由PSP管理的。而切换到ISR中则使用MSP。
( H4 Y: }4 b, o6 t9 v: }1 U  H  E/ @' g# g, t, U
这个是大家都知道的,不知道的是?  [# W& s' n5 U+ U5 Z9 ~

. P. O9 N3 S3 Y3 _; yMSP和PSP各有各自的HEAP。
0 \% Y/ P# I. q! I: \9 [7 d* O' {4 \* i& J6 ?7 ?
tanic 回答时间:2019-4-3 09:46:59
MSP用的.s分配的   PSP用的rtos 通过宏分配的?
七哥 回答时间:2019-4-3 10:02:07
tanic 发表于 2019-4-3 09:46
5 z) F' t( D& T! vMSP用的.s分配的   PSP用的rtos 通过宏分配的?

+ {, n* F! n  f学习了
Kevin_G 回答时间:2019-4-3 10:11:40
厉害
watershade 回答时间:2019-4-3 17:17:25
tanic 发表于 2019-4-3 09:46+ K; x# k4 L7 _6 ?8 D' W6 C
MSP用的.s分配的   PSP用的rtos 通过宏分配的?

( f/ Y7 C6 z  @( P4 h7 p6 ?6 J2 R% U是的
watershade 回答时间:2019-4-3 17:18:00
sky_han 发表于 2019-4-3 08:58
& {! \$ |. c0 `- M$ \。MSP顾名思义是给系统栈使用的。PSP是给进程栈使用的。在RTOS运行中,整个栈空间是由PSP管理的。而切换到I ...

0 U6 S$ f% e: c8 ~8 {% }我不知道的是.s只管msp
Cortexxx 回答时间:2019-4-9 09:30:01
有个小问题 , b6 [7 }9 y* N
  1. xTaskCreate(FactoryTask,"Factory",128, 0, 3, NULL);
复制代码
  1.         BaseType_t xTaskCreate(        TaskFunction_t pxTaskCode,8 H' A; a; Z) g) `. [! j1 B
  2.                                                         const char * const pcName,+ t8 X1 o" b+ H  {+ o
  3.                                                         const uint16_t usStackDepth,
    0 W# b4 u6 o6 ?. B+ ~
  4.                                                         void * const pvParameters,. s/ G+ [* p4 x5 c0 j" i; x
  5.                                                         UBaseType_t uxPriority,  I8 m' e1 S9 n5 Z
  6.                                                         TaskHandle_t * const pxCreatedTask ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
复制代码

+ q& J/ z( n! j' R; \6 F3 @2 L
9 H5 n1 O* `6 d! v# J& C0 g, p4 E这个代码的第三个参数 128 申请的是stack还是Heap?
& \/ ^* L2 r0 E$ `我进到这个function里面看到它用malloc开了一块内存,故认为是开辟的是heap空间," q  ?) W- Y- |! I! u% d- ?8 h
但是他的形参名称为什么是 StackDepth。 这点我就很糊涂了,到底这个128*4 stack 还是heap?
watershade 回答时间:2019-4-15 13:06:24
Cortexxx 发表于 2019-4-9 09:304 u1 [* K: H, C7 W
有个小问题
. j1 T2 [2 S) ]; Y. `- m9 e1 c
不好意思,这几天没有看论坛。
* G* N; V% _6 K: r2 Y5 d, S9 n) p+ ~下图是从freeRTOS v10.0.0的手册上截图的。(这个手册freeRTOS官方可免费下载) frtos_heap_stack.jpg
+ i2 Q: A( \  J手册提到了动态创建和静态创建两种内存分配方法。我的上面提到的TOTAL_HEAP_SIZE其实只在动态创建的时候才有效.: T7 i; `+ x) U" h0 P
在动态分配的时候,需要先指定heap的总共大小。但这段memory并不是划出来不用的。所有的task,queue和semaphore创建的时候都要从这里面划分。而对于任务的动态创建,TCB和stack都是从heap里面分配的。但如果使用静态创建,那这个任务就是在编译环节分配的。不是程序在heap里面动态分配的。
& s3 Z0 e* `  H( I: g0 w: [& m
2 R0 t1 b( K7 U. M  i~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 _, L  \! V& C, g6 u% c4 D如果你看st封装的cmsis-rtos,他的程序创建使用的是osThreadCreate.而freeRTOS的memory allocation分为三种:一种是Dynamic,另一种是Static,第三种是Dynamic/Static。但本质上使用的还是上图提到的两个functions:xTaskCreate和xTaskCreateStatic0 G+ J) O, S5 T1 N
图片里展示了主要的内容。你可以试着将memory allocate改成static,你会看到heap的大小选择没有了。7 F. ?. p( M  E% N- q3 k
frtos_heap_stack_2.jpg frtos_heap_stack_3.jpg
! H* X' a" X7 x* r1 s3 q& N, K
7 C% C# y5 Y( {$ e) M0 U  l~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ Y3 a% G9 I" @2 a: `
这是我个人的理解,如果你有疑问或者不同意。可以留言给我,咱们交流交流。谢谢
8 z, N2 T/ c1 [2 r' u  d  j
Cortexxx 回答时间:2019-4-16 08:56:04
watershade 发表于 2019-4-15 13:06
- T* t+ H- v2 {: U# ~& a7 m1 T不好意思,这几天没有看论坛。( [1 `3 O, M) w- ~3 C
下图是从freeRTOS v10.0.0的手册上截图的。(这个手册freeRTOS官方可免费 ...
/ b7 ~; x# z2 T6 x# t/ y  M
感谢回复 了解了 XDDD
6 b9 m# h' p/ e& d6 A. x" X% V
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版