分区内存——介绍和基本服务
查看 RTOS Revealed 系列
内存分区在上一篇文章中介绍过,其中与标准Cmalloc()的对比 功能做了。分区是从分区池中获得的内存区域。这为任务以确定性和可靠的方式获取和释放数据存储提供了一种灵活的方式。
使用分区
在 Nucleus SE 中,分区池是在构建时配置的。一个应用程序最多可以配置 16 个分区池。如果未配置分区池,则应用程序中不包含属于分区池的数据结构或服务调用代码。
分区池只是一个内存区域,它被分成特定数量的固定大小的分区。用户可以完全控制每个池中分区的大小和数量。任务可能会请求分配内存分区并接收指向存储区域的指针。不向分区外写入数据是任务的责任。任何任务都可以通过将指针传递给 API 函数来释放分区。请求分配分区,当没有更多可用分区时,可能会导致错误或任务暂停,具体取决于 API 调用中选择的选项和 Nucleus SE 配置。
配置内存分区
分区池数量
与 Nucleus SE 的大多数方面一样,分区池的配置主要由 #define 控制 nuse_config.h 中的语句 .关键设置是 NUSE_PARTITION_POOL_NUMBER ,这决定了为应用程序配置了多少个分区池。默认设置为 0(即没有使用分区池),您可以将其设置为最多 16 的任何值。错误的值将导致编译时错误,这是由 nuse_config_check.h 中的测试生成的 (这包含在 nuse_config.c 中 因此使用此模块编译)导致 #error 正在编译的语句。
选择非零值是分区池的“主启用”。这导致一些数据结构被相应地定义和调整大小。 ROM 中的数据结构需要初始化为适合每个分区池特征的值。下一篇文章将详细介绍数据结构。它还激活 API 启用设置。
API 启用
Nucleus SE 中的每个 API 函数(服务调用)都有一个启用 #define nuse_config.h 中的符号 .对于分区池,它们是:
NUSE_PARTITION_ALLOCATE
NUSE_PARTITION_DEALLOCATE
NUSE_PARTITION_POOL_INFORMATION
NUSE_PARTITION_POOL_COUNT
默认情况下,所有这些都设置为 FALSE ,从而禁用每个服务调用并禁止包含任何实现代码。要为应用程序配置分区池,您需要选择要使用的 API 调用并将其启用符号设置为 TRUE .
这是默认 nuse_config.h 的摘录 文件:
如果启用了分区池 API 功能并且未配置任何分区池(NUSE_Partition_Pool_Count() 除外),则会导致编译时错误 这总是被允许的)。如果您的代码使用未启用的 API 调用,则会导致链接时间错误,因为应用程序中不会包含任何实现代码。
分区池服务调用
Nucleus RTOS 支持七个服务调用,它们属于提供以下功能的分区池:
分配一个分区:NU_Allocate_Partition() .由 NUSE_Partition_Allocate() 实现 在 Nucleus SE 中。
释放分区:NU_Deallocate_Partition() .由 NUSE_Partition_Deallocate() 实现 在 Nucleus SE 中。
提供指定分区池的信息:NU_Partition_Pool_Information() .由 NUSE_Partition_Pool_Information() 实现 在 Nucleus SE 中。
返回为应用程序(当前)配置了多少个分区池的计数:NU_Established_Partition_Pools() .由 NUSE_Partition_Pool_Count() 实现 在 Nucleus SE 中。
向应用程序添加新的分区池(创建):NU_Create_Partition_Pool() .未在 Nucleus SE 中实现。
从应用程序中移除分区池(删除):NU_Delete_Partition_Pool() .未在 Nucleus SE 中实现。
返回指向应用程序中所有分区池(当前)的指针:NU_Partition_Pool_Pointers() .未在 Nucleus SE 中实现。
详细检查了每个服务调用的实现。
可能会注意到没有提供重置功能(在 Nucleus RTOS 或 Nucleus SE 中)。这是故意的。一个任务分配一个分区并将一个指针传递给另一个任务(它可能会在稍后释放它)是非常常见的做法。如果要重置分区池,则所有分区都会被标记为未使用,但无法跟踪和通知可能正在使用这些分区的所有任务。
分区分配和释放服务
可以在分区池上执行的基本操作是从中分配分区(即将分区标记为已使用并返回其地址)和释放分区(即将分区标记为未使用)。 Nucleus RTOS 和 Nucleus SE 分别为这些操作提供了两个基本的 API 调用,这里将对其进行讨论。
分配分区
用于分配分区的 Nucleus RTOS API 调用非常灵活,如果操作无法立即完成,您可以无限期挂起或超时挂起;即您尝试从当前分配了所有分区的池中分配一个分区。 Nucleus SE 提供相同的服务,只是任务挂起是可选的,并且没有实现超时。
用于分区分配的 Nucleus RTOS API 调用
服务调用原型:
STATUS NU_Allocate_Partition(NU_PARTITION_POOL *pool,
VOID **return_pointer, UNSIGNED suspend);
退货:
NU_SUCCESS – 通话成功
NU_NO_PARTITION – 没有可用的分区
NU_INVALID_POOL – 分区池指针无效
NU_INVALID_POINTER – 数据返回指针为NULL
NU_INVALID_SUSPEND – 尝试从非任务线程挂起
NU_TIMEOUT – 即使挂起指定的超时时间后也没有可用的分区
NU_POOL_DELETED – 任务挂起时分区池被删除
用于分配的 Nucleus SE API 调用
此 API 调用支持 Nucleus RTOS API 的关键功能。
服务调用原型:
STATUS NUSE_Partition_Allocate(NUSE_PARTITION_POOL pool, ADDR *return_pointer, U8 suspend);
参数:
池 – 要使用的分区池的索引(ID)
return_pointer – 指向 ADDR 类型变量的指针 它将接收分配分区的地址
暂停 – 任务暂停规范;可能是 NUSE_NO_SUSPEND 或 NUSE_SUSPEND
退货:
NUSE_SUCCESS – 通话成功
NUSE_NO_PARTITION – 没有可用的分区
NUSE_INVALID_POOL – 分区池索引无效
NUSE_INVALID_POINTER – 数据返回指针为NULL
NUSE_INVALID_SUSPEND – 尝试从非任务线程挂起或未启用阻塞 API 调用
嵌入式