keil MDK之RTX的内存管理的API函数及应用

一、RTX的内存管理函数总共有7个函数如下图

keil MDK之RTX的内存管理的API函数及应用_第1张图片

下面我们就将几个用到的函数

1、_declare_box函数原型

#define _declare_box( \ 
    pool,      \    /* Name of the memory pool variable. */
    size,      \    /* Number of bytes in each block. */
    cnt )      \    /* Number of blocks in the memory pool. */
    U32 pool[((size+3)/4)*(cnt) + 3]
函数描述:

该函数用于定义一块内存池

第一个参数是内存池的名字,也就是首地址

第二个参数是内存块的大小

第三个参数是内存的块数

使用举例:

#include <rtl.h>

/* Reserve a memory for 32 blocks of 20-bytes. */
_declare_box(mpool,20,32);

void membox_test (void) {
  U8 *box;
  U8 *cbox;

  _init_box (mpool, sizeof (mpool), 20);
  box  = _alloc_box (mpool);
  /* This block is initialized to 0. */
  cbox = _calloc_box (mpool);
   ..
  _free_box (mpool, box);
  _free_box (mpool, cbox);
}
2、_init_box函数原型

int _init_box  (
    void* box_mem,       /* Start address of the memory pool */
    U32   box_size,      /* Number of bytes in the memory pool */
    U32   blk_size );    /* Number of bytes in each block of the pool */
函数描述:
该函数初始化内存池

第一个参数是内存池的首地址

第二个参数是内存池的大小

第三个参数是内存块的大小

3、_alloc_box函数原型

void *_alloc_box (
    void* box_mem );    /* Start address of the memory pool */
函数描述:

用于从指定的地址里面申请内存块

第一个参数是内存池的首地址

使用举例:

/* Reserve a memory for 32 blocks of 20-bytes. */
U32 mpool[32*5 + 3];

void membox_test (void) {
  U8 *box;
  U8 *cbox;

  _init_box (mpool, sizeof (mpool), 20);
  box  = _alloc_box (mpool);
  /* This block is initialized to 0. */
  cbox = _calloc_box (mpool);
   ..
  _free_box (mpool, box);
  _free_box (mpool, cbox);
}
4、_free_box函数原型

#include <rtl.h>

int _free_box (
    void* box_mem,    /* Start address of the memory pool */
    void* box );      /* Pointer to the block to free */
函数描述:

该函数用于释放申请到的内存块

第一个参数是内存池的首地址

第二个参数是要释放的内存块


使用举例:

#include <rtl.h>

/* Reserve a memory for 32 blocks of 20-bytes. */
U32 mpool[32*5 + 3];

void membox_test (void) {
  U8 *box;
  U8 *cbox;

  _init_box (mpool, sizeof (mpool), 20);
  box  = _alloc_box (mpool);
  /* This block is initialized to 0. */
  cbox = _calloc_box (mpool);
   ..
  _free_box (mpool, box);
  _free_box (mpool, cbox);
}
二、使用注意事项

1、申请到的内存在合适的时候应该要释放掉否则会出现莫名的错误

三、实验目的

学习RTX的内存管理的API函数

四、实验内容

1、在按键k1按下的时候 申请内存块,并且通过消息邮箱发送里面的消息

2、在AppTaskRun任务中等待消息,接收到消息 就把内存块释放

五、实验的完整代码



#include "bsp.h" /* 底层硬件驱动 */
#include <RTL.h>




static uint64_t AppTaskLEDStk[256/8];/*任务栈*/
static uint64_t AppTaskStartStk[512/8];/*任务栈*/
static uint64_t AppTaskUserStk[512/8];/*任务栈*/
static uint64_t AppTaskRunStk[512/8];
/*任务句柄*/
OS_TID HandleTaskLED = NULL;
OS_TID HandleTaskKey = NULL; 
OS_TID HandleTaskRun = NULL;
/*函数声明*/
static void AppTaskCreate(void);
__task void AppTaskLED(void);
__task void AppTaskStart(void);
__task void AppTaskUserKey(void);
__task void AppTaskRun(void);
/*定义消息邮箱*/
os_mbx_declare(mailbox,5);
/*内存管理*/
_declare_box(mpool,8,10);
/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: c程序入口
* 形    参:无
* 返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{


/*
ST固件库中的启动文件已经执行了 SystemInit() 函数,该函数在 system_stm32f4xx.c 文件,主要功能是
配置CPU系统的时钟,内部Flash访问时序,配置FSMC用于外部SRAM
*/
bsp_Init();/**/
os_sys_init_user(AppTaskStart,            /*任务函数*/
4,                       /*任务优先级*/
&AppTaskStartStk,        /*任务栈*/
sizeof(AppTaskStartStk));/*任务栈大小*/
/* 进入主程序循环体 */
while (1)
{
;
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskUserKey
* 功能说明: 按键键值
* 形    参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskUserKey(void)
{
uint8_t ucKeycode = 0;
static uint8_t ucMsg = 0;
uint8_t *pMsg;
while(1)
{
ucKeycode = bsp_GetKey();
switch(ucKeycode)
{
case KEY_DOWN_K1:
printf("申请内存空间\r\n");

pMsg = _alloc_box(mpool);
*pMsg = ucMsg++;
printf("向消息邮箱发送数据%d %d\r\n",ucMsg-1, *pMsg);
os_mbx_send(mailbox,pMsg,0xFFFF);
break;
case KEY_DOWN_K2:
_free_box(mpool,pMsg);
break;
case KEY_DOWN_K3:
break;
default:
break;
}
os_dly_wait(20);
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskRun
* 功能说明: LED闪烁的任务
* 形    参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskRun(void)
{
uint8_t *pMsg;
OS_RESULT num = 0;
while(1)
{
num = os_mbx_check(mailbox);
os_mbx_wait(mailbox,(void *)&pMsg,0xFFFF);/*等待消息*/
printf("邮箱剩余的空间%d  消息的值%d\r\n",num,*pMsg);
_free_box(mpool,pMsg);/*释放申请的内存空间*/
if(*pMsg % 2 == 0)
{
GPIO_ResetBits(GPIOF,GPIO_Pin_7);
}
else
{
GPIO_SetBits(GPIOF,GPIO_Pin_7);
}
os_dly_wait(50);
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskLED
* 功能说明: LED闪烁的任务
* 形    参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskLED(void)
{
static uint8_t i = 0;
while(1)
{
if(i % 2 == 0)
{
GPIO_ResetBits(GPIOI,GPIO_Pin_10);/*点亮LED*/
}
else
{
GPIO_SetBits(GPIOI,GPIO_Pin_10);/*熄灭LED*/
}
i++;
os_dly_wait(100);/*系统延时函数 因为时钟节拍为1000 所以这里是延时800ms,也就是使AppTaskLED任务挂起800MS*/
}
}
/*
*********************************************************************************************************
* 函 数 名:AppTaskCreate
* 功能说明: 任务创建
* 形    参:无
* 返 回 值: 无
*********************************************************************************************************
*/
static void AppTaskCreate(void)
{
HandleTaskLED = os_tsk_create_user(AppTaskLED,            /*任务函数*/
 1,                     /*优先级 注意RTX的数字越小,优先级越低*/
&AppTaskLEDStk,        /*任务栈起始地址*/
sizeof(AppTaskLEDStk));/*任务栈大小*/
HandleTaskKey = os_tsk_create_user(AppTaskUserKey,        /*任务函数*/
 3,                     /*优先级 注意RTX的数字越小,优先级越低*/
        &AppTaskUserStk,       /*任务栈起始地址*/
sizeof(AppTaskUserStk));/*任务栈大小*/
HandleTaskRun = os_tsk_create_user(AppTaskRun,            /*任务函数*/
2,                     /*优先级 注意RTX的数字越小,优先级越低*/
 &AppTaskRunStk,        /*任务栈起始地址*/
 sizeof(AppTaskRunStk));/*任务栈大小*/
}
/*
*********************************************************************************************************
* 函 数 名:AppTaskStart
* 功能说明: 开始任务
* 形    参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskStart(void)
{
AppTaskCreate();/*创建AppTaskLED任务*/
os_mbx_init(mailbox,sizeof(mailbox));/*初始化邮箱*/
_init_box(mpool,sizeof(mpool),8);
while(1)
{
bsp_KeyScan();/*按键扫描*/
os_dly_wait(10);/*系统延时函数*/
}
}

六、实验现象

通过串口工具可以清楚的看到如下

keil MDK之RTX的内存管理的API函数及应用_第2张图片



你可能感兴趣的:(keil MDK之RTX的内存管理的API函数及应用)