阿九讲学(九)——FreeRTOS堆内存管理(一)

从FreeRTOS V9.0.0开始内核对象既可以在编译的时候静态分配,也可以在运行时动态分配。为了尽可能让FreeRTOS易于使用,这些内核对象并不是在编译时静态分配的,而是在运行时动态分配的。内核对象创建时FreeRTOS分配RAM而在内核对象删除时释放内存。这样简化了API,并且减少了RAM的占用。

动态内存分配是C语言编程的概念,而不是针对FreeRTOS或者多任务编程的概念。它和FreeRTOS是相关的,因为内核对象是动态分配的,并且通用编译器提供的动态内存分配方案对于实时应用程序并不总是适合的。

内存可以使用标准C库的malloc()和free()函数来分配,但直接调用这两个函数可能不适合,原因有以下几点:

1. malloc()和free()函数在小型嵌入式系统中并不总是可用的

2. 它们的实现可能非常的大,占据了相当大的一块代码空间

3. 他们几乎都不是线程安全的

4. 它们并不是确定的,每次调用这些函数执行的时间可能都不一样

5. 它们有可能产生碎片

6. 它们有可能打乱链接器的配置

7. 如果允许堆空间的生长方向覆盖其他变量占据的内存,它们会成为debug的灾难

动态内存分配的可选

从FreeRTOS V9.0.0开始内核对象既可以在编译时静态分配也可以在运行时动态分配。如今FreeRTOS把内存分配放在可移植层。这是考虑到不同的嵌入式系统有不同的动态内存管理方法和时间要求,因此单个的动态内存分配算法将只适合于应用程序的一个子集。同样,如果有需要的话,开发人员可以从核心代码库中移除动态内存分配。

当FreeRTOS需要RAM的时候,并不是调用malloc(),而是调用pvPortMalloc()。当需要释放RAM的时候,并不是调用free(),而是调用vPortFree()。pvPortMalloc()和标准C库的malloc()有同样的函数原型,vPortFree()和标准C库的free()有同样的函数原型。

pvPortMalloc()和vPortFree()都是公共函数,因此能够被应用代码调用。

FreeRTOS对于pvPortMalloc()和vPortFree()提供了5种实现。FreeRTOS应用程序可以使用其中的一种,或者使用自己的实现。

5种实现分别在heap_1.c,heap_2.c,heap_3.c,heap_4.c和heap_5.c文件中,都存在于文件夹FreeRTOS/Source/portable/MemMang下。


下面来介绍一下其中的一种实现 Heap_1:

小型嵌入式系统通常只在启动调度程序之前创建任务和其他内核对象。在这种情况下,内存只能在应用程序开始执行任何实时功能之前由内核动态分配,并且内存将在应用程序的生命周期内保持不被释放。这意味着所选择的分配方案不需要考虑任何更复杂的内存分配问题,比如确定性和碎片化,而只需要考虑代码大小和简单性等属性。

Heap_1.c实现了一个非常基本的pvPortMalloc()版本,但没有实现vPortFree()。heap_1适用于从不删除任务或其他内核对象的应用程序。

一些禁止使用动态内存分配的关键的商业系统和关键的安全系统也有可能使用heap_1。由于担心出现不确定性、内存碎片化和内存分配失败等问题,关键系统通常禁止动态内存分配,但是Heap_1总是确定性的,并且不能分割内存。

当调用pvPortMalloc()时,heap_1分配方案将简单数组细分为更小的块。这个数组称为FreeRTOS堆。

数组的大小(以字节为单位)由FreeRTOSConfig.h中的configTOTAL_HEAP_SIZE定义设置。以这种方式定义一个大数组会使应用程序看起来消耗大量ram——甚至在从数组中分配任何内存之前也是如此。

每个创建的任务都需要一个任务控制块(TCB)和一个从堆中分配的堆栈。图5演示了heap_1如何在创建任务时细分简单数组。

如上图所示:

A. 在创建任何任务之前显示数组——整个数组是空闲的。

B. 显示创建一个任务后的数组。

C. 显示创建了三个任务之后的数组。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 193,968评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,682评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,254评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,074评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,964评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,055评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,484评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,170评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,433评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,512评论 2 308
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,296评论 1 325
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,184评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,545评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,150评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,437评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,630评论 2 335

推荐阅读更多精彩内容

  • 内存是计算机非常关键的部件之一,是暂时存储程序以及数据的空间,CPU只有有限的寄存器可以用于 存储计算数据,而大部...
    dreamer_lk阅读 1,154评论 2 10
  • FreeRTOS的内存管理较为只有,它提供了多套管理法案有简单的有复杂的,它还允许用户同时使用两种管理方案,甚至允...
    EleZtian阅读 870评论 0 0
  • 内存的历史 现代的intel处理器可以追溯到最早期的intel芯片。1.8085处理器充分利用了芯片整合技术,它将...
    Mr_Bluyee阅读 701评论 0 0
  • 内核使用标准的 malloc()与 free()库函数进行动态内存分配的缺点 这两个函数在小型嵌入式系统中可能不可...
    Mr_Michael阅读 757评论 0 0
  • 本文转载自 https://juejin.im/post/59f8691b51882534af254317 参考:...
    xingdong阅读 2,705评论 0 3