Prototype
source\kernel\partition.c
#include <partition.h>
_partition_id _partition_create_at(
void *partition_location,
_mem_size partition_size,
_mem_size block_size)
Parameters
partition_location [IN]— Pointer to the start of the partition
partition_size [IN] — Number of single-addressable units in the partition
block_size [IN] — Number of single-addressable units ineach partition block in the partition
Returns
• Partition ID (success)
• PARTITION_NULL_ID (failure)
在RTOS中可以用malloc()和free()两个函数动态地分配内存和释放内存。但是,在RTOS中多次调用这两个函数会造成很多内存碎片。本来嵌入式系统的内存资源非常有限,由于这些碎片的大量存在,使得程序到后来连非常小的内存也分配不到。
因此,在MQX中,操作系统内存分为可变大小内存块和固定大小内存块。内存块可以是私有内存块(属于分配它的任务所有)或者系统内存块(不属于任何任务)。当任务结束时,MQX返回该任务的私有内存块给内存。MQX采用这样的内存管理算法,既可以满足任务内存需求,又解决了内存碎片问题。
1.使用可变块管理内存
MQX的内存池分为两种,一种是默认内存池,另外一种是默认内存池之外的内存池。
内存块也分为两种,一种是私有内存块(属于分配它的任务所有),另外一种是系统内存块(不属于任何任务)。
_mem_alloc 从默认内存池分配私有内存块
_mem_alloc_from 从指定的内存池分配私有内存块
_mem_alloc_zero 从默认的内存池分配以0填充的私有内存块
_mem_alloc_zero_from 从指定的内存池分配以0填充的私有内存块
_mem_alloc_system 从默认的内存池分配系统内存块
_mem_alloc_system_from 从指定内存池分配系统内存块
_mem_alloc_system_zero 从默认内存池分配以0填充的系统内存块
_mem_alloc_system_zero_from 从指定内存池分配以0填充的系统内存块
_mem_copy 拷贝某位置的内存数据到其它位置
_mem_create_pool 在默认内存池之外生成内存池
_mem_extend 追加额外的内存给默认内存池;附加的内存必须在当前默认内存池之外,但不必与其邻接
_mem_extend_pool 追加额外的内存给某非默认内存池;额外的内存必须在该内存池之外,但不必与其邻接
_mem_free 释放默认内存池内、外的内存块
_mem_free_part 释放部分内存块(如果内存块比申请的大,或者比需求的大)
_mem_get_error 获取使用_mem_test()函数产生错误时指向内存位置的指针
_mem_get_error_pool 获取使用_mem_test_pool()函数产生错误时指
向内存位置的指针
_mem_get_highwater 获取默认内存池分配的内存块的高位地址(尽管可能已经被释放)
_mem_get_highwater_pool 获取已分配内存池的高位地址(尽管可能已经被释放)
_mem_get_size 获取内存块的大小,其大小可能大于申请值
_mem_swap_endian 转换为其它端格式
_mem_test 测试默认的内存池;即检查内部校验码以确定内存完整性是否被破坏(通常被破坏是由于应
用程序写内存块出界)
_mem_test_and_set 测试并设置内存位置
_mem_test_pool 测试内存池的错误,参见_mem_test()
_mem_transfer 转交内存块所有权给另一任务
_mem_zero 设置全部/部分内存块为全0
2.使用可变块管理轻量级内存
为了更好的节省内存资源,以供代码和数据量较小的的任务使用,MQX还利用可变大小块管理轻量级内存。轻量级内存函数与常规内存函数较为类似,但它们的代码和数据量开销较小。
3.使用固定大小块管理内存(区块)
使用区块组件,你可以管理固定大小内存块的分区,区块的大小是当任务创建分区的时候指定的。在默认的内存池中有可增长的动态区块,而在默认内存池之外又有不可增长的静态区块。
_partion_create()的原型如下:
partition_id _partition_create<span style="font-family: Arial, Helvetica, sans-serif;">(</span>
_mem_size block_size,
_mqx_uint initial_blocks,
_mqx_uint grow_blocks,
_mqx_uint maximum_blocks)
Parameters
block_size [IN]— Number of single-addressable units in each partition block
initial_blocks [IN]— Initial number of blocks in the partition
grow_blocks [IN]— Number of blocks by which to grow the partition if all the partition blocks
are allocated
maximum_blocks [IN] — If grow_blocksis not 0; one of:
maximum number of blocks in the partition
0 (unlimited growth)
Returns
• Partition ID (success)
• PARTITION_NULL_ID (failure)
_partion_create_at()的原型如下:
_partition_id _partition_create_at(
void *partition_location,
_mem_size partition_size,
_mem_size block_size)
Parameters
partition_location [IN]— Pointer to the start of the partition
partition_size [IN] — Number of single-addressable units in the partition
block_size [IN] — Number of single-addressable units ineach partition block in the partition
Returns
• Partition ID (success)
• PARTITION_NULL_ID (failure)
分配函数如下:
下面是一个例子:
Example
Create a dynamic partition, allocate a private partition block, and then free the block.
#include <mqx.h>
#include <partition.h>
#define PACKET_SIZE 0x200
#define PACKET_COUNT 100
void part_function(void)
{
_partition_id packet_partition;
void *packet_ptr;
/* Create a dynamic partition: */
packet_partition = _partition_create(PACKET_SIZE, PACKET_COUNT,
0, 0);
...
/* Allocate a partition block: */
packet_ptr = _partition_alloc(packet_partition);
...
/* Free the partition block: */
_partition_free(packet_ptr);
}
撤销区块的函数为:_partiton_destroy(),它的用法如下:
4.控制MMU
对于某些CPU来说,你在启用缓存之前必须初始化内存管理单元(Memory Management Unit, MMU)。MQX函数允许初始化、启用、禁用MMU,或者为其增加一个存储区域。你能够通过MMU页表管理MMU。虚拟存储器组件允许应用程序控制MMU页表。下图表示了虚拟地址、MMU页表、MMU页、物理页以及物理地址之间的关系。