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

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

[复制链接]
watershade 发布时间:2019-4-2 21:41
这几天在调试自己写的一个FreeRTOS的程序。程序稍微有点大,用的是F0内核的MCU。ROM只有16K。
因为我的程序内部要自己用allloc开辟一部分空间,而因为使用了多个任务和MailQueue整个空间的占用可想而知。
所以我设置FreeRTOS的heap空间5120,考虑到别的占用。所以总共分的heap是5K+2K。这时候RTOS跑不起来了。
当然我的Stack也分了2K。所以我谨慎的分了8K,还不行。这时候我把FreeRTOS的heap空间扩大了。这时候竟然连编译都通不过了。
我还在怀疑是不是我的程序有什么问题。
直到今晚,我才解开这个问题。只怪我学艺不精,对heap的理解有点想当然。(差不多有快一年没有耐心做大项目了,所以之前掌握的本就似是而非的知识就成了埋在调试路上的陷阱。)
原来,F0和其它的系列是一样的。都是双堆栈指针:MSP(Main Stack Pointer主堆栈指针)和PSP(Process Stack Pointer)。这种设计非常适合RTOS的设计。MSP顾名思义是给系统栈使用的。PSP是给进程栈使用的。在RTOS运行中,整个栈空间是由PSP管理的。而切换到ISR中则使用MSP。
这点其实我是知道的,知识印象有些模糊。但我真正不知道的在于下面一点。.s文件中的heap只管分配给MSP。
STM32cubemx中有个简单的估算heap大小的方法。(因为不包含MailQueue,所以尺寸你可以适当在上面增加一下mempool的大小。)我习惯的做法就是将两个数加起来设置一下heap但是这次遇见问题了。我给.s文件中的heap设置的越大,就表示msp管理的heap越大,因为整个空间有限。我的psp占用的栈就小了。所以在我上面的列子中。psp也许需要超过5K的空间,这时候因为我的MSP分配的多了。就导致编译通不过。这时候我就设法扩大PSP的空间,但是因为理解错误,我就需要确保.s分配的空间大于5K。所以这时候我发现我的FreeRTOS的最大空间不能扩大了。

那现在整么解决呐。很简单就是把.s的空间设置小一点。不如2K。一般够我的程序用了。而stack也是2k。所以我的FreeRTOS的heap配置可以扩大。比如8K.这时候我发现问题解决了。那一切问题就要有官方介绍才成。

arm官网的介绍:http://www.keil.com/support/docs/4049.htm 这里面给了几个链接说明。可以看一下。
mainSteak.jpg

这个问题无意间才发现的。要不是调试调到怀疑人生,我将会对.s的heap误解越来越深。
收藏 3 评论12 发布时间:2019-4-2 21:41

举报

12个回答
watershade 回答时间:2019-4-3 00:34:06
本帖最后由 watershade 于 2019-4-3 17:19 编辑

帖子应该移到哪个区?(谢谢管理员将它移动到了RTOS区)
jeffhe1 回答时间:2019-4-3 08:39:26
真是大神, 厲害的文章
一代睡神的崛起 回答时间:2019-4-3 08:41:56
谢谢分享,学习了
sky_han 回答时间:2019-4-3 08:58:11
。MSP顾名思义是给系统栈使用的。PSP是给进程栈使用的。在RTOS运行中,整个栈空间是由PSP管理的。而切换到ISR中则使用MSP。

这个是大家都知道的,不知道的是?

MSP和PSP各有各自的HEAP。

tanic 回答时间:2019-4-3 09:46:59
MSP用的.s分配的   PSP用的rtos 通过宏分配的?
七哥 回答时间:2019-4-3 10:02:07
tanic 发表于 2019-4-3 09:46
MSP用的.s分配的   PSP用的rtos 通过宏分配的?

学习了
Kevin_G 回答时间:2019-4-3 10:11:40
厉害
watershade 回答时间:2019-4-3 17:17:25
tanic 发表于 2019-4-3 09:46
MSP用的.s分配的   PSP用的rtos 通过宏分配的?

是的
watershade 回答时间:2019-4-3 17:18:00
sky_han 发表于 2019-4-3 08:58
。MSP顾名思义是给系统栈使用的。PSP是给进程栈使用的。在RTOS运行中,整个栈空间是由PSP管理的。而切换到I ...

我不知道的是.s只管msp
Cortexxx 回答时间:2019-4-9 09:30:01
有个小问题
  1. xTaskCreate(FactoryTask,"Factory",128, 0, 3, NULL);
复制代码
  1.         BaseType_t xTaskCreate(        TaskFunction_t pxTaskCode,
  2.                                                         const char * const pcName,
  3.                                                         const uint16_t usStackDepth,
  4.                                                         void * const pvParameters,
  5.                                                         UBaseType_t uxPriority,
  6.                                                         TaskHandle_t * const pxCreatedTask ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
复制代码


这个代码的第三个参数 128 申请的是stack还是Heap?
我进到这个function里面看到它用malloc开了一块内存,故认为是开辟的是heap空间,
但是他的形参名称为什么是 StackDepth。 这点我就很糊涂了,到底这个128*4 stack 还是heap?
watershade 回答时间:2019-4-15 13:06:24

不好意思,这几天没有看论坛。
下图是从freeRTOS v10.0.0的手册上截图的。(这个手册freeRTOS官方可免费下载) frtos_heap_stack.jpg
手册提到了动态创建和静态创建两种内存分配方法。我的上面提到的TOTAL_HEAP_SIZE其实只在动态创建的时候才有效.
在动态分配的时候,需要先指定heap的总共大小。但这段memory并不是划出来不用的。所有的task,queue和semaphore创建的时候都要从这里面划分。而对于任务的动态创建,TCB和stack都是从heap里面分配的。但如果使用静态创建,那这个任务就是在编译环节分配的。不是程序在heap里面动态分配的。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如果你看st封装的cmsis-rtos,他的程序创建使用的是osThreadCreate.而freeRTOS的memory allocation分为三种:一种是Dynamic,另一种是Static,第三种是Dynamic/Static。但本质上使用的还是上图提到的两个functions:xTaskCreate和xTaskCreateStatic
图片里展示了主要的内容。你可以试着将memory allocate改成static,你会看到heap的大小选择没有了。
frtos_heap_stack_2.jpg frtos_heap_stack_3.jpg

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这是我个人的理解,如果你有疑问或者不同意。可以留言给我,咱们交流交流。谢谢
Cortexxx 回答时间:2019-4-16 08:56:04
watershade 发表于 2019-4-15 13:06
不好意思,这几天没有看论坛。
下图是从freeRTOS v10.0.0的手册上截图的。(这个手册freeRTOS官方可免费 ...

感谢回复 了解了 XDDD

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版