OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子全套STM32开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...
查看: 292|回复: 8

关于FreeRTOS内存管理的疑问

[复制链接]

  离线 

4

主题

16

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
229
金钱
229
注册时间
2018-5-28
在线时间
22 小时
发表于 2018-6-2 21:06:05 | 显示全部楼层 |阅读模式
      今天看了原子哥讲的FreeRTOS关于内存管理方面的书和视频,看完之后有个疑问一直不明白,贴出来大家分析一下。原子哥也讲了,实际在应用中,尤其是简单的单片机应用中,用的最多的内存管理方式还是静态分配内存,即在创建任务前就分配好各个任务需要的内存,信号量,队列等内容,代码运行过程中不再需要动态创建任务,不需要动态分配内容。而这种方式在FreeRTOS的内存管理文件里面应该用heap_1.c。
      那么问题来了,heap_1.c里面只有分配内存功能,没有释放内存功能。那么我在每个任务里申请的内存(相当于裸跑的时候的局部变量)岂不是每运行一次都静态分配一次,那么很快内存就会用完了。还是使用heap_1.c的时候都需求在创建任务前都分配好内存,就像裸跑的时候的全局变量那样。那么在任务里用的类似局部变量的内存就不用申请了?
      第二个文件就是关于局部变量的问题,在使用了FreeRTOS后,应该还是能继续使用传统方式定义局部变量和全局变量的,我也测试过了,确实可行。那么这些变量应该是分配到的了ucheap[]外面了,不受内存管理函数管理了。这样的应用方式有没有问题。传统定义方式和使用OS之后的内存管理共存的话会不会有什么问题?有什么需要注意的地方?
     这两个问题其实都是关于静态内存的使用,也就是原子哥说的80%的应用中的实际使用方法,原子哥能不能给讲一下怎么用比较好!
谢谢!
回复

使用道具 举报

  离线 

8

主题

466

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1368
金钱
1368
注册时间
2015-8-25
在线时间
261 小时
发表于 2018-6-2 23:24:30 | 显示全部楼层
局部变量是分配任务的时候已经分配给任务的堆栈。pvPortMalloc()函数分配的内存是总内存堆里剩余的内存,也就是任务堆栈外剩余的内存。这样理解没有问题
回复 支持 1 反对 0

使用道具 举报

  离线 

8

主题

466

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1368
金钱
1368
注册时间
2015-8-25
在线时间
261 小时
发表于 2018-6-2 21:50:16 | 显示全部楼层
我的理解:每个任务里申请的内存只分配一次且分配在它对应的堆栈中,然后任务开始运行进入while死循环,何来的“每运行一次都静态分配一次”?刚刚实验过了,原子的例程静态创建任务,如下图,打印了task1和task2的任务堆栈地址和大小,task1和task2运行时定义了局部变量,分配打印task1和task2局部变量的地址,局部变量的地址位于任务堆栈里面。
111.jpg
回复 支持 反对

使用道具 举报

  离线 

8

主题

466

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1368
金钱
1368
注册时间
2015-8-25
在线时间
261 小时
发表于 2018-6-2 21:57:02 | 显示全部楼层
在使用了FreeRTOS后,还是能继续使用传统方式定义局部变量和全局变量的。但是访问的时候有共享的麻烦,你任务A使用全局变量时阻塞了,任务B又修改了这个全局变量的值,然后任务A运行了,你想要的全局变量的值已经被修改过了,肯定出错。最好还是用FreeRTOS里提供的消息队列。
回复 支持 反对

使用道具 举报

  离线 

4

主题

16

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
229
金钱
229
注册时间
2018-5-28
在线时间
22 小时
 楼主| 发表于 2018-6-2 22:17:16 | 显示全部楼层
本帖最后由 jishuaihu 于 2018-6-2 22:27 编辑
szczyb1314 发表于 2018-6-2 21:57
在使用了FreeRTOS后,还是能继续使用传统方式定义局部变量和全局变量的。但是访问的时候有共享的麻烦,你任 ...

谢谢!~

每个任务里申请的内存只分配一次且分配在它对应的堆栈中,然后任务开始运行进入while死循环,何来的“每运行一次都静态分配一次”?这个问题是我发帖的时候想错了,确实是只申请一次。

我开始还是没有理解原子哥的实验程序的意思,不过经你这么一提醒就明白了。局部变量是分配任务的时候已经分配给任务的堆栈。pvPortMalloc()函数分配的内存是总内存堆里剩余的内存,也就是任务堆栈外剩余的内存。这样理解没有问题吧?一会儿我也尝试着写一个 测试程序试一下。再次感谢!


回复 支持 反对

使用道具 举报

  离线 

4

主题

16

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
229
金钱
229
注册时间
2018-5-28
在线时间
22 小时
 楼主| 发表于 2018-6-3 00:34:02 | 显示全部楼层
szczyb1314 发表于 2018-6-2 23:24
局部变量是分配任务的时候已经分配给任务的堆栈。pvPortMalloc()函数分配的内存是总内存堆里剩余的内存, ...

明白了,谢谢!
回复 支持 反对

使用道具 举报

  离线 

26

主题

151

帖子

0

精华

高级会员

Rank: 4

积分
534
金钱
534
注册时间
2017-1-7
在线时间
59 小时
发表于 2018-6-3 17:54:07 | 显示全部楼层
szczyb1314 发表于 2018-6-2 21:50
我的理解:每个任务里申请的内存只分配一次且分配在它对应的堆栈中,然后任务开始运行进入while死循环,何 ...

while循环确实没有在分配,但之前分配的内存也没有释放啊,这样不会出问题吗?
回复 支持 反对

使用道具 举报

  离线 

2

主题

164

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
312
金钱
312
注册时间
2018-5-14
在线时间
63 小时
发表于 2018-6-3 18:50:55 | 显示全部楼层
Jevin乐动 发表于 2018-6-3 17:54
while循环确实没有在分配,但之前分配的内存也没有释放啊,这样不会出问题吗?

那种分配方式本来就是对应的程序中不删除任务的应用,任务还在,内存当然不用释放了。
回复 支持 反对

使用道具 举报

  离线 

8

主题

466

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1368
金钱
1368
注册时间
2015-8-25
在线时间
261 小时
发表于 2018-6-3 20:33:13 | 显示全部楼层
Jevin乐动 发表于 2018-6-3 17:54
while循环确实没有在分配,但之前分配的内存也没有释放啊,这样不会出问题吗?

你在你的task任务中定义一个局部变量,它也是需要分配内存的,分配在任务堆栈里,你的while里面是要一直用这个变量的,你干嘛把它释放了?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则




关闭

报名原子哥新品发布会&粉丝见面会上一条 /1 下一条

正点原子公众号

QQ|联系我们|手机版|官方淘宝店|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-10-24 09:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表
/* */