三)内存管理

腾讯为我们提供了内存管理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)
	{}
	 
}

实验现象;
在这里插入图片描述

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐