当前位置: 首页 >  软件学堂 >  《Mastering the FreeRTOS Real Time Kernel》读书笔记(1)堆内存管理

《Mastering the FreeRTOS Real Time Kernel》读书笔记(1)堆内存管理

导读:这是161204的版本,不完全覆盖目前最新版本的内核。.0.关于freeRTOS.首先提出了了在小型嵌入式系统中为何需要多任务管理的问题,介绍了freeRTOS的用途。然后开始做广告,吹了一波freeRTOS的好处。其中要注意一些关键的名词:任务优先级分配、任务通知、队列、信号量

这是161204的版本,不完全覆盖目前最新版本的内核。

0.关于freeRTOS

首先提出了了在小型嵌入式系统中为何需要多任务管理的问题,介绍了freeRTOS的用途。然后开始做广告,吹了一波freeRTOS的好处。其中要注意一些关键的名词:任务优先级分配、任务通知、队列、信号量、互斥锁、软定时器、事件组、钩子函数等。这些内容会在后面的章节进行介绍。

1.FreeRTOS的文件结构

主要介绍在github上下载到的FreeRTOS包含哪些内容。

1.2 分布

可以将freeRTOS看成一个库,或者看成一个软件。其通过配置,可以运行在30多种不同的处理器架构上。而配置Freertos需要通过一个叫做 FreeRTOSConfig.h 的头文件。不同编译器或者处理器的该头文件不同,可以直接从众多例程中复制出来直接使用,或者微调后使用。
官方发行版中顶级目录有FreeRTOS(主要内核)和FreeRTOS- Plus(生态系统组件),其下分别都有Source和Demo两个文件夹。在FreeRTOS/Source中有 task.clist.cqueue.ctimers.c 、 _event—groups.ccroutine.c 这些源文件,有些总是需要,有些可选。
FreeRTOS/Source/portable中是一些针对特定编译器和架构的端口文件,相当于在不同国家旅游时的通行证。
头文件包含的路径一共要准备3个:FreeRTOS/Source/include、FreeRTOS/Source/portable/[compiler]/[architecture]、和指向FreeRTOSConfig.h的路径。

1.3 演示Demo

主要是教读者如何使用已有的演示Demo

1.4 创建FreeRTOS项目

包括修改Demo和从头开始创建两种方法。主要就是复制源文件进工程和修改端口文件。

1.5 数据类型和编码风格指南

FreeRTOS针对每个端口都有唯一的protmacro.h头文件,包含了针对不同单片机的两个特定数据类型TickType_t & BaseType_t。
变量名:c对应char、s对应int16_t(short)、l对应int32_t(long)、x对应BaseType_t。p对应指针变量前缀,u是无符号变量前缀。
函数名:函数前缀同变量名前缀。
格式化:一个制表符总是等于4个空格。
宏macro:宏的主体为全大写字母,小写字母作前缀,表示宏的定义位置。如taskENTER_CRITICAL(),该宏在task.h。pdTRUE = pdPASS = 1; pdFALSE = pdFAIL = 0;

注意:由于FreeRTOS需要在不同编译器上通过编译,所以其源代码包含的类型转换很多。

2.堆内存管理

注意:V9.0.0开始可以完全静态分配FreeRTOS应用程序,不需要包含堆内存管理器。这边主要介绍动态分配。
为什么需要动态内存分配。FreeRTOS每次创建内核对象时都需要分配RAM。但是内核对象其被删除时,需要释放对应的RAM。原本C库的malloc和free不适合单片机,所以重新设计相应的申请和释放函数 pvPortMalloc()vPortFree()
为此,FreeRTOS准备了5种内存管理示例:heap_1.c, heap_2.c, heap_3.c, heap_4.c and heap_5.c。它们都在 FreeRTOS/Source/portable/MemMang 目录下。

Heap_1

无法使用动态内存的版本,没有使用 vPortFree() 。当调用 pvPortMalloc() 时,heap_1会在FreeRTOS堆空间内进行申请更小的空间,将申请的空间划分为任务控制块(TCB)和一个该任务专用栈。

Heap_2

Heap_4的原始版本,为了向后兼容而保留,建议使用增强的完整版Heap_4。
heap_2允许释放不用内存使其空闲,可以再次申请。再次申请的逻辑为:使用大小满足,且最接近请求字节数的空闲内存块。但是其不能将相邻的空闲内存合并 ,该功能在Heap_4中可以实现。
书例:5b、25b、100b的三块空闲内存,申请20b内存,该块内存将分配与25b空闲内存处,其中多余5b仍为空闲内存,就是此时还有5b、5b、100b三块空闲内存。
Heap_2适用于重复创建和删除任务的应用程序,前提是分配给创建的任务和堆栈大小不变。

Heap_3

使用标准库的malloc()和free()函数,因此堆的大小不是像前两者,由configTOTAL_HEAP_SIZE设置,而是由链接器配置决定。
通过临时挂起FreeRTOS调度器,Heap_3使malloc()和free()线程安全。这些内容会在第7章资源管理中涉及。

Heap_4

与heap_1和heap_2一样,heap_4的工作原理是将数组细分为更小的块,数组是静态分配的,并由configTOTAL_HEAP_SIZE确定尺寸。
与heap_2在分配时就有不同,书例:堆包含三个空闲内存块,按照它们在数组中出现的顺序,分别为5字节、200字节和100字节,调用pvPortMalloc()来请求20字节的RAM,第一个适合请求的字节数的空闲块是200字节,因此pvPortMalloc在返回指针之前将200字节拆分为一个20字节的块和一个180字节的块,返回的指针指向20字节的块,新的180字节块仍可以被pvPortMalloc调用。并不是申请最接近请求字节数的空闲内存块。
但是heap_4在释放内存时,会自动将相邻的空闲内存合并。注意只是相邻的。合并后会成为一个更大的空闲内存块,可用于申请。
heap_2和4申请内存、heap_4合并内存的依据都是因为每块空闲内存都有一小段空间是记录空闲内存信息的,通过这些信息可以精准地进行操作。
heap_4代表的数组起始地址是可以设置的,具体方法详见本书。

Heap_5

heap_5用于分配和释放内存的算法和heap_4相同,不同的是heap_5不限于从单个静态声明的数组分配内存 ,heap_5可以从多个独立的内存空间分配内存,当运行 FreeRTOS 的系统提供的 RAM 没有在系统内存映射中显示为单个连续(没有空间)块时,Heap_5 很有用。
在撰写本文时,heap_5 是唯一提供的内存分配方案,必须在调用 pvPortMalloc() 之前显式初始化。 Heap_5 使用 vPortDefineHeapRegions() API 函数初始化。 使用 heap_5 时,必须在创建任何内核对象(任务、队列、信号量等)之前调用 vPortDefineHeapRegions()
vPortDefineHeapRegions用于指定每个单独的内存区域的起始地址和大小,这些区域构成heap_5使用的总内存。

void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions );

每个单独的内存区域由HeapRegion_t类型的结构体描述,所有可用内存区域的描述作为 HeapRegion_t 结构数组传递到 vPortDefineHeapRegions()。

typedef struct HeapRegion
{
/* The start address of a block of memory that will be part of the heap.*/
uint8_t *pucStartAddress;
/* The size of the block of memory in bytes. */
size_t xSizeInBytes;
} HeapRegion_t;

比如定义三个不连续内存块可以使用如下代码。

/* Define the start address and size of the three RAM regions. */
#define RAM1_START_ADDRESS ( ( uint8_t * ) 0x00010000 )
#define RAM1_SIZE ( 65 * 1024 )
#define RAM2_START_ADDRESS ( ( uint8_t * ) 0x00020000 )
#define RAM2_SIZE ( 32 * 1024 )
#define RAM3_START_ADDRESS ( ( uint8_t * ) 0x00030000 )
#define RAM3_SIZE ( 32 * 1024 )
/* Create an array of HeapRegion_t definitions, with an index for each of the three RAM regions, and terminating the array with a NULL address. The HeapRegion_t structures must appear in start address order, with the structure that contains the lowest start address appearing first. */
const HeapRegion_t xHeapRegions[] =
{
{ RAM1_START_ADDRESS, RAM1_SIZE },
{ RAM2_START_ADDRESS, RAM2_SIZE },
{ RAM3_START_ADDRESS, RAM3_SIZE },
{ NULL, 0 } /* Marks the end of the array. */
};
int main( void )
{
/* Initialize heap_5. */
vPortDefineHeapRegions( xHeapRegions );
/* Add application code here. */
}

堆相关函数

xPortGetFreeHeapSize

返回调用该函数时未分配的堆空间总量

size_t xPortGetFreeHeapSize( void );

xPortGetMinimumEverFreeHeapSize

返回 FreeRTOS 应用程序自启动以来系统的历史最小可用堆空间量。
这两个函数都没有提供有关如何将未分配的内存分成更小的块的信息。

vPortGetHeapStats()

提供关于堆状态的附加信息。

Malloc调用失败的Hook函数

如果 pvPortMalloc() 因为请求大小的块不存在而无法返回 RAM 块,那么它将返回 NULL,则不会创建内核对象。此时执行,以处理这种情况。

void vApplicationMallocFailedHook( void );
内容
  • 重磅更新!Sermant 1.2.0 release版本新特性速览
    重磅更新!Sermant 1.2
    2023-12-12
    本文分享自华为云社区《重磅更新!Sermant 1.2.0 release版本新特性速览》,作者:华为云开源。.10月,
  • 宝塔面板配置MongoDB数据库
    宝塔面板配置MongoDB数据库
    2023-12-12
    1-安装MongoDB.在面板中的【软件商店】搜索MongoDB并安装,推荐下载4.x以上的版本(可视化工具MongoD
  • 高效联调,可靠发布!华为云推出CodeArts Release发布管理服务
    高效联调,可靠发布!华为云推出C
    2023-12-09
    摘要: 华为云全新推出CodeArts.Release发布管理服务,旨在将华为多年形成的发布实践外溢,帮助企业提升软件发
  • Kurator v0.3.0版本发布
    Kurator v0.3.0版本
    2023-12-08
    摘要: 2023年4月8日,Kurator正式发布v0.3.0版本。.本文分享自华为云社区《华为云 Kurator v0
  • 产品质量管理利器,华为云发布CodeArts Defect缺陷管理服务
    产品质量管理利器,华为云发布Co
    2023-12-08
    摘要: 近日,华为云CodeArts Defect缺陷管理服务正式上线,提供结构化缺陷跟踪流程和标准化的质量度量模型。.
  • Docker的Portainer认识、安装、使用
    Docker的Portainer
    2023-12-08
    一、认识.docker的图形化界面.Portainer 是一个轻量级的容器管理界面,可以让用户更轻松地管理 Docker
  • SSH教程0简介
    SSH教程0简介
    2023-12-06
    0 简介.OpenSSH (http://www.OpenSSH.com).已成为远程管理UNIX类系统和许多网络设备的
  • 基于ITIL的ITSM工具
    基于ITIL的ITSM工具
    2023-12-05
    随着企业的ITSM(IT服务管理)的逐渐成熟进而深入应用,如果您希望以低成本寻找一款基于ITIL的ITSM管理工具,然后
  • 学系统集成项目管理工程师(中项)系列06b_信息系统安全管理(下)
    学系统集成项目管理工程师(中项)
    2023-12-04
    1. 物理安全管理.1.1. 计算机机房与设施安全.1.1.1. 计算机机房.1.1.1.1. 机房场地选择.1.1.1
  • 学系统集成项目管理工程师(中项)系列06a_信息系统安全管理(上)
    学系统集成项目管理工程师(中项)
    2023-12-04
    1. 信息安全.1.1. 保护信息的保密性、完整性、可用性.1.2. 另外也包括其他属性,如:真实性、可核查性、不可抵赖
  • Centos7安装Gitlab
    Centos7安装Gitlab
    2023-12-03
    1. 什么是Gitlab?.后续内容会更新在个人站点: https.malusspectabilis.top.GitLa
  • Centos7.6下corosync+pacemaker+pcs高可用集群环境安装
    Centos7.6下corosy
    2023-12-03
    在容灾备份领域,有多种高可用方案,corosync+pacemaker无疑是开源方案中的佼佼者。.1. 什么是coros
  • SonarQube系列-架构与外部集成
    SonarQube系列-架构与外
    2023-12-02
    介绍.Sonar是一个代码质量管理的开源平台,基于Java开发的,用于管理源代码的质量,通过插件形式,可以支持包括jav
  • 代码管理工具git的使用
    代码管理工具git的使用
    2023-12-01
    1. git 概述.git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。也是Linu
  • 【OpenCV】在VS2017中配置OpenCV开发环境
    【OpenCV】在VS2017中
    2023-12-01
    开发环境:OpenCV4.5.4、VS2017、x64.打开属性管理器:视图–>其他窗口–>属性管理器.找到 Relea
  • 创新电子元件设计与**
    创新电子元件设计与**
    2023-12-16
    创新电子元件设计与**.在当今科技飞速发展的时代,电子元件作为电子产品的基础组成部分,其设计与**的创新举足轻重。随着人
  • ***迁移与升级解决方案
    ***迁移与升级解决方案
    2024-01-05
    ***迁移与升级解决方案.随着业务的不断扩大和发展,很多企业逐渐意识到原有的***已经不能满足日益增长的需求,因此需要进
  • 电子元件质量检测与认证服务
    电子元件质量检测与认证服务
    2024-01-05
    电子元件质量检测与认证服务.为什么需要电子元件质量检测与认证服务?.随着电子产业的不断发展,电子元件在各个生产领域都起着
  • 私有云搭建与**服务
    私有云搭建与**服务
    2023-12-11
    私有云搭建与**服务.在当今信息化快速发展的社会环境下,随着企业对数据安全和隐私保护的需求不断增加,越来越多的企业开始将
  • 电子元件**链**解决方案
    电子元件**链**解决方案
    2023-12-11
    电子元件**链**解决方案.在当今全球化的市场中,**链**是企业成功的关键因素之一。特别是在电子元件行业,**链**尤
  • 云存储解决方案
    云存储解决方案
    2024-01-10
    云存储解决方案.随着互联网技术的不断发展,越来越多的企业开始意识到数据存储和管理的重要性。传统的本地存储方式已经不能满足
  • 移动应用程序开发
    移动应用程序开发
    2024-01-20
    移动应用程序开发.移动应用程序开发是指开发适用于**和平板电脑的应用程序。随着移动设备的普及和移动互联网的快速发展,移动
  • 互联网金融服务平台
    互联网金融服务平台
    2023-12-31
    互联网金融服务平台.互联网金融服务平台是指利用互联网技术提供金融服务的平台,它的出现极大地改变了传统金融行业的运营模式,
  • ***数据备份与恢复解决方案
    ***数据备份与恢复解决方案
    2024-01-20
    ***数据备份与恢复解决方案.在当今数字化时代,数据备份和恢复变得越来越重要。对于企业来说,***数据的备份和恢复解决方
  • 高性能电子元件**
    高性能电子元件**
    2024-01-10
    高性能电子元件**.随着科技的不断进步,电子行业的发展日新月异。高性能电子元件作为电子产品的关键组成部分,对于产品的性能