RTX之——内存管理
Posted Albert Nie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RTX之——内存管理相关的知识,希望对你有一定的参考价值。
内存管理
在创建一个线程的时候,我们会为该线程专门分配一个栈,称之为线程栈,用于线程切换时保存相关数据。这个栈区别于微处理器本身的栈。线程栈(thread stack)是一块内存。线程栈的默认大小定义在RTOS配置文件RTX_Config.h
中,当然我们也可以在线程属性结构体中自定义线程栈的大小。
有关线程的知识,请见:☞多线程-RGB_LED灯闪烁
要自定义线程栈大小,首先得知道RTX的内存分配模型。
内存分配模型
keil RTX5通常支持三种对象内存分配模型,分别是:
Global Memory Pool
: 全局内存池,将所有对象放在一个内存池里面,对象用多少内存,就分配多少内存。优点是配置简单;缺点是在对象创建和删除的过程中,容易造成内存碎片。keil RTX5默认的对象内存分配模型是全局内存池模型。
Object-specific Memory Pools
: 对象专用内存池,即为每种对象类型分配一块固定大小的内存。由于对象的大小是固定的,所以在创建和删除的过程中不会造成内存碎片。
Static Object Memory
: 静态对象内存,需要编译期即为对象分配内存。这就要求用户在定义某个对象的时候指定其大小。
全局内存池
在全局内存池模型中,对象的创建和销毁可能会造成内存碎片的问题。全局内存池的大小定义在配置文件RTX_Config.h
中。
#define OS_DYNAMIC_MEM_SIZE 4096 // 4KB
对象专用内存池
我们也可以选择Object-specific Memory Pools
为专用对象分配内存。不过,我们需要指定专用对象类型的最大数量和其内存大小。RTOS负责为专用对象计算和保留所需的内存大小。Object-specific Memory Pools
也在配置文件RTX_Config.h
中,通过使能Object specific Memory allocation
选项即可可视化配置。
#define OS_THREAD_OBJ_MEM 1 // 1KB
#define OS_THREAD_NUM 3 // 总线程个数
#define OS_THREAD_DEF_STACK_NUM 2 // 使用默认栈大小的线程个数
#define OS_STACK_SIZE 200 // 线程栈大小
#define OS_THREAD_USER_STACK_SIZE 1024 // 用户提供的总线程栈大小
上面,总共创建了三个线程,其中两个线程使用默认栈大小 200 bytes
,另外一个线程使用自定义栈大小为1024 bytes
,如下:
// 自定义线程栈大小
static const osThreadAttr_t threadAttr_thread3 = {
"thread3",
NULL,
NULL,
NULL,
NULL,
1024, // stack size
osPriorityNormal,
NULL,
NULL
};
静态对象内存池
我们也可以静态定义对象内存大小。首先,定义一个静态线程栈数组。
static uint64_t thread_stk[64]; //使用uint64_t 确保8字节对齐
然后定义一个RTX线程控制块,osRtxThread
类型定义在rtx_os.h
头文件中,所以要包含头文件。
#include "rtx_os.h"
static osRtxThread_t thread_tcb;
最后,配置线程属性结构体,就实现了静态配置对象内存了。
// 自定义线程栈大小
static const osThreadAttr_t threadAttr_thread4 = {
"thread4",
NULL,
&thread_tcb, // cb memory
sizeof(thread_tcb), // cb size
&thread_stk[0], // stack memory
sizeof(thread_stk), // stack size
osPriorityNormal,
NULL,
NULL
};
官方案例
为方便大家理解,贴出官方案例。
/*----------------------------------------------------------------------------
* CMSIS-RTOS 'main' function template
*---------------------------------------------------------------------------*/
#include "RTE_Components.h"
#include CMSIS_device_header
#include "cmsis_os2.h"
//include rtx_os.h for types of RTX objects
#include "rtx_os.h"
//The thread function instanced in this example
void worker(void *arg)
{
while(1)
{
//work
osDelay(10000);
}
}
// Define objects that are statically allocated for worker thread 1
__attribute__((section(".bss.os.thread.cb")))
osRtxThread_t worker_thread_tcb_1;
// Reserve two areas for the stacks of worker thread 1
// uint64_t makes sure the memory alignment is 8
uint64_t worker_thread_stk_1[64];
// Define the attributes which are used for thread creation
// Optional const saves RAM memory and includes the values in periodic ROM tests
const osThreadAttr_t worker_attr_1 = {
"wrk1",
osThreadJoinable,
&worker_thread_tcb_1,
sizeof(worker_thread_tcb_1),
&worker_thread_stk_1[0],
sizeof(worker_thread_stk_1),
osPriorityAboveNormal,
0
};
// Define ID object for thread
osThreadId_t th1;
/*----------------------------------------------------------------------------
* Application main thread
*---------------------------------------------------------------------------*/
void app_main (void *argument) {
uint32_t param = NULL;
// Create an instance of the worker thread with static resources (TCB and stack)
th1 = osThreadNew(worker, ¶m, &worker_attr_1);
for (;;) {}
}
int main (void) {
// System Initialization
SystemCoreClockUpdate();
// ...
osKernelInitialize(); // Initialize CMSIS-RTOS
osThreadNew(app_main, NULL, NULL); // Create application main thread
osKernelStart(); // Start thread execution
for (;;) {}
}
小结
本文主要介绍了RTX5的三大内存分配模型:
- 全局内存池
- 对象专用内存池
- 静态对象内存
了解了对象内存分配模型,才好更方便地配置我们需要的对象资源~
参考资料
想看原滋原味的英文资料?,喏~
以上是关于RTX之——内存管理的主要内容,如果未能解决你的问题,请参考以下文章