Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
学习笔记
【rtthread学习笔记系列】第五篇:内存分配
发布于 2021-05-12 19:50:16 浏览:2392
订阅该版
[tocm] # 一、内存分配概念 计算机系统中,变量存放在ram中,只有在使用时才将它调入cpu运行,rtthread提供了两类内存分配方法: * 动态内存堆 * 静态内存池。 动态内存堆根据系统资源的情况有3种分配算法: * 小内存管理算法:一般用于内存小于2M的设备 * slab管理算法:近似多内存池的快速算法。 * memheap算法:适用于存在多个内存堆的系统。 虽然采用的内存分配算法,但提供给应用程序的api完全相同。 # 二、动态内存分配api ``` //内存堆初始化:在相同初始化时执行。 这个函数会把参数begin_addr, end_addr 区域的内存空间作为内存堆来使用。 /* begin_addr:内存堆起始地址 end_addr:内存堆结束地址 */ void rt_system_heap_init(void* begin_addr, void* end_addr); //memheap算法的内存堆初始化 /* memheap:memheap句柄 name:内存堆名称 start_addr:内存堆起始地址 size:内存堆大小 */ rt_err_t rt_memheap_init(struct rt_memheap *memheap, const char *name, void *start_addr, rt_uint32_t size) //分配内存 /* nbytes:内存大小,单位:字节 返回:内存地址 */ void *rt_malloc(rt_size_t nbytes); //释放内存 /* ptr:内存地址 */ void rt_free (void *ptr); //重新分配内存 /* rmem:已分配的内存地址 newsize:重新分配的大小,原内容不变,缩小的情况后面数据被截断。 */ void *rt_realloc(void *rmem, rt_size_t newsize); //分配连续的多个内存 /* count:内存块数量 size:每个内存块大小 */ void *rt_calloc(rt_size_t count, rt_size_t size); //设置内存分配完成钩子函数:内存分配完成执行设置的钩子回调函数 /* hook:钩子函数指针 */ void rt_malloc_sethook(void (*hook)(void *ptr, rt_size_t size)); //设置内存释放钩子函数 /* hook:钩子函数指针 */ void rt_free_sethook(void (*hook)(void *ptr)); ``` # 三、内存池api ## 3.1 内存池概念 rtthread将内存池抽象成 rt_mempool。 ## 3.2 内存池api ``` //创建内存池 /* name:内存池名称 block_count:内存块数量 block_size:内存块大小 */ rt_mp_t rt_mp_create(const char* name, rt_size_t block_count, rt_size_t block_size); //删除内存池 /* mp:内存池句柄 */ rt_err_t rt_mp_delete(rt_mp_t mp); //初始化内存池 /* mp:内存池句柄 name:内存池名称 start:内存池起始地址 size:内存池大小 block_size:每个内存块大小 */ rt_err_t rt_mp_init(rt_mp_t mp, const char* name, void *start, rt_size_t size, rt_size_t block size); //内存池脱离 /* mp:内存池句柄 */ rt_err_t rt_mp_detach(rt_mp_t mp); //分配内存 /* mp:内存池句柄 time:等待分配超时时间 */ void *rt_mp_alloc (rt_mp_t mp, rt_int32_t time); //释放内存 /* block:内存块地址 */ void rt_mp_free (void *block); ``` # 四、内存分配示例 ## 4.1 动态内存分配示例 ``` /* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-08-24 yangjie the first version */ /* * 程序清单:动态内存管理例程 * * 这个程序会创建一个动态的线程,这个线程会动态申请内存并释放 * 每次申请更大的内存,当申请不到的时候就结束 */ #include
#define THREAD_PRIORITY 25 #define THREAD_STACK_SIZE 512 #define THREAD_TIMESLICE 5 /* 线程入口 */ void thread1_entry(void *parameter) { int i; char *ptr = RT_NULL; /* 内存块的指针 */ for (i = 0; ; i++) { /* 每次分配 (1 << i) 大小字节数的内存空间 */ ptr = rt_malloc(1 << i); /* 如果分配成功 */ if (ptr != RT_NULL) { rt_kprintf("get memory :%d byte\n", (1 << i)); /* 释放内存块 */ rt_free(ptr); rt_kprintf("free memory :%d byte\n", (1 << i)); ptr = RT_NULL; } else { rt_kprintf("try to get %d byte memory failed!\n", (1 << i)); return; } } } int dynmem_sample(void) { rt_thread_t tid = RT_NULL; /* 创建线程1 */ tid = rt_thread_create("thread1", thread1_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if (tid != RT_NULL) rt_thread_startup(tid); return 0; } /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(dynmem_sample, dynmem sample); ``` ## 4.2 内存池分配示例 ``` /* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-08-24 yangjie the first version */ /* * 程序清单:内存池例程 * * 这个程序会创建一个静态的内存池对象,2个动态线程。 * 一个线程会试图从内存池中获得内存块,另一个线程释放内存块 * 内存块 */ #include
static rt_uint8_t *ptr[50]; static rt_uint8_t mempool[4096]; static struct rt_mempool mp; #define THREAD_PRIORITY 25 #define THREAD_STACK_SIZE 512 #define THREAD_TIMESLICE 5 /* 指向线程控制块的指针 */ static rt_thread_t tid1 = RT_NULL; static rt_thread_t tid2 = RT_NULL; /* 线程1入口 */ static void thread1_mp_alloc(void *parameter) { int i; for (i = 0 ; i < 50 ; i++) { if (ptr[i] == RT_NULL) { /* 试图申请内存块50次,当申请不到内存块时, 线程1挂起,转至线程2运行 */ ptr[i] = rt_mp_alloc(&mp, RT_WAITING_FOREVER); if (ptr[i] != RT_NULL) rt_kprintf("allocate No.%d\n", i); } } } /* 线程2入口,线程2的优先级比线程1低,应该线程1先获得执行。*/ static void thread2_mp_release(void *parameter) { int i; rt_kprintf("thread2 try to release block\n"); for (i = 0; i < 50 ; i++) { /* 释放所有分配成功的内存块 */ if (ptr[i] != RT_NULL) { rt_kprintf("release block %d\n", i); rt_mp_free(ptr[i]); ptr[i] = RT_NULL; } } } int mempool_sample(void) { int i; for (i = 0; i < 50; i ++) ptr[i] = RT_NULL; /* 初始化内存池对象 */ rt_mp_init(&mp, "mp1", &mempool[0], sizeof(mempool), 80); /* 创建线程1:申请内存池 */ tid1 = rt_thread_create("thread1", thread1_mp_alloc, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if (tid1 != RT_NULL) rt_thread_startup(tid1); /* 创建线程2:释放内存池*/ tid2 = rt_thread_create("thread2", thread2_mp_release, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE); if (tid2 != RT_NULL) rt_thread_startup(tid2); return 0; } /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(mempool_sample, mempool sample); ```
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
happycode999
这家伙很懒,什么也没写!
文章
28
回答
6
被采纳
0
关注TA
发私信
相关文章
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部