三)内存管理
腾讯为我们提供了内存管理API
动态内存管理模块,提供了一套动态管理系统内存的机制,支持用户动态的申请、释放不定长内存块。
堆内存管理
tos_mmheap_pool_add
k_err_t tos_mmheap_pool_add(void *pool_start, size_t pool_size);
• 功能描述
向堆内存中添加内存池。
• 参数解释
IN/OUT 参数名 描述
[in] pool_start 待添加内存池起始地址
[in] pool_size 待添加内存池大小
• 返回值
K_ERR_NONE 添加成功。
K_ERR_MMHEAP_INVALID_POOL_ADDR 内存池起始地址非法。
K_ERR_MMHEAP_INVALID_POOL_SIZE 内存池大小非法。
tos_mmheap_pool_rmv
k_err_t tos_mmheap_pool_rmv(void *pool_start);
• 功能描述
从堆内存中删除内存池。
• 参数解释
IN/OUT 参数名 描述
[in] pool_start 待删除的内存池起始地址
• 返回值
无
tos_mmheap_alloc
void *tos_mmheap_alloc(size_t size);
• 功能描述
从堆内存中分配一块内存。
• 参数解释
IN/OUT 参数名 描述
[in] size 期望分配的内存大小
• 返回值
分配到的内存起始地址(返回K_NULL表示分配失败)。
tos_mmheap_aligned_alloc
void *tos_mmheap_aligned_alloc(size_t size, size_t align);
• 功能描述
从堆内存中分配一块内存,此内存起始地址按align参数对齐。
• 参数解释
IN/OUT 参数名 描述
[in] size 期望分配的内存大小
[in] align 对齐参数
• 返回值
分配到的内存起始地址(返回K_NULL表示分配失败)。
tos_mmheap_realloc
void *tos_mmheap_realloc(void *ptr, size_t size);
• 功能描述
从堆内存中重新分配一块内存。
• 参数解释
IN/OUT 参数名 描述
[in] ptr 原内存起始地址
[in] size 期望重新分配的内存大小
• 返回值
分配到的内存起始地址(返回K_NULL表示分配失败)。
tos_mmheap_free
void *tos_mmheap_free(void *ptr);
• 功能描述
释放一片从堆内存中分配到的内存。
• 参数解释
IN/OUT 参数名 描述
[in] ptr 待释放的内存起始地址
• 返回值
无。
块内存管理
tos_mmblk_pool_create
k_err_t tos_mmblk_pool_create(k_mmblk_pool_t *mbp, void *pool_start, size_t blk_num, size_t blk_size);
• 功能描述
创建一个块内存池。
• 参数解释
IN/OUT 参数名 描述
[in] mbp 待创建的块内存句柄
[in] pool_start 块内存池起始地址
[in] blk_num 内存块数量
[in] blk_size 单个内存块大小
• 返回值
K_ERR_NONE 块内存创建成功。
K_ERR_MMBLK_INVALID_POOL_ADDR 块内存池起始地址非法。
K_ERR_MMBLK_INVALID_BLK_SIZE 块内存大小非法。
tos_mmblk_alloc
k_err_t tos_mmblk_alloc(k_mmblk_pool_t *mbp, void **blk);
• 功能描述
从内存池中分配一个内存块。
• 参数解释
IN/OUT 参数名 描述
[in] mbp 块内存句柄
[out] blk 返回的块内存起始地址
• 返回值
K_ERR_NONE 块内存分配成功,blk指向分配到的内存块起始地址。
K_ERR_MMBLK_POOL_EMPTY 内存池是空的,blk为K_NULL。
tos_mmblk_free
k_err_t tos_mmblk_free(k_mmblk_pool_t *mbp, void *blk);
• 功能描述
释放一个内存块。
• 参数解释
IN/OUT 参数名 描述
[in] mbp 块内存句柄
[in] blk 待释放的块内存起始地址
• 返回值
K_ERR_NONE 块内存释放成功。
K_ERR_MMBLK_POOL_FULL 内存池是满的。
程序实例:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "lcd.h"
#include "string.h"
#include "cmsis_os.h"
#include "tos.h"
#define STK_SIZE_TASK_DEMO 512
k_stack_t stack_task_demo[STK_SIZE_TASK_DEMO];
k_task_t task_demo;
extern void entry_task_demo(void *arg);
void entry_task_demo(void *arg)
{
void *p = K_NULL, *p_aligned = K_NULL;
int i = 0;
while (K_TRUE)
{
//从堆中分配内存
if (i == 1)
{
p = tos_mmheap_alloc(0x30);
if (p)
{
printf("alloc: %x\n", (cpu_addr_t)p);
}
}
//释放分配的内存
else if (i == 2)
{
if (p)
{
printf("free: %x\n", p);
tos_mmheap_free(p);
}
}
//分配内存
else if (i == 3)
{
p = tos_mmheap_alloc(0x30);
if (p)
{
printf("alloc: %x\n", (cpu_addr_t)p);
}
}
//以十六位对齐的方式分配内存
else if (i == 4)
{
p_aligned = tos_mmheap_aligned_alloc(0x50, 16);
if (p_aligned) {
printf("aligned alloc: %x\n", (cpu_addr_t)p_aligned);
if ((cpu_addr_t)p_aligned % 16 == 0) {
printf("%x is 16 aligned\n", (cpu_addr_t)p_aligned);
} else {
printf("should not happen\n");
}
}
}
//重新分配内存
else if (i == 5)
{
p = tos_mmheap_realloc(p, 0x40);
if (p) {
printf("realloc: %x\n", (cpu_addr_t)p);
}
}
//释放内存
else if (i == 6)
{
if (p)
{
tos_mmheap_free(p);
}
if (p_aligned)
{
tos_mmheap_free(p_aligned);
}
}
tos_task_delay(1000);
++i;
}
}
int main(void)
{
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
delay_init(180); //初始化延时函数
uart_init(115200); //初始化USART
LED_Init(); //初始化LED
KEY_Init(); //初始化按键
LCD_Init();
tos_knl_init();
(void)tos_task_create(&task_demo,
"receiver_higher_prio",
entry_task_demo,
NULL,
4,
stack_task_demo,
STK_SIZE_TASK_DEMO,
0);
tos_knl_start();
while(1)
{}
}
实验现象;