完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980

第27章       STM32H7的TCM,SRAM等五块内存的动态内存分配实现

本章教程为大家分享一种DTCM,SRAM1,SRAM2,SRAM3和SRAM4可以独立管理的动态内存管理方案,在实际项目中有一定的实用价值,比如MP3编解码,JPEG编解码,视频播放器,矢量字体等需要动态内存的场合。

27.1 初学者重要提示

27.2 动态内存管理移植

27.3 动态内存的使用方法

27.4 实验例程说明(MDK)

27.5 实验例程说明(IAR)

27.6 总结

27.1 初学者重要提示

  1. 学习本章节前,务必优先学习第25章,了解TCM,SRAM等五块内存区的基础知识,比较重要。
  2. 将RTX5系统的动态内存管理整理了出来,可以同时管理多个分区。如果其它RTOS中使用,记得做互斥保护或者加个调度锁均可。
  3. 支持动态内存使用情况统计。

27.2 动态内存管理移植

移植比较简单,仅需添加两个文件到工程即可。

27.2.1 MDK版的移植

  • 第1步,添加如下两个文件到MDK中

注,以本章配套例子为例,这两个文件的路径\User\malloc。

  • 第2步,添加路径。

  • 第3步,添加头文件。

如果哪个源文件要用到动态内存,包含rtx_lib.h即可,本章配套例子是直接将其放在了bsp.h文件里面,哪个源文件要用到动态内存,直接包含bsp.h头文件即可。

通过这简单的三步就完成了MDK的移植。

27.2.2 IAR版的移植

  • 第1步,添加如下两个文件到IAR中

注,以本章配套例子为例,这两个文件的路径\User\malloc。

  • 第2步,添加路径。

  • 第3步,添加头文件。

如果哪个源文件要用到动态内存,包含rtx_lib.h即可,本章配套例子是直接将其放在了bsp.h文件里面,哪个源文件要用到动态内存,直接包含bsp.h头文件即可。

通过这简单的三步就完成了IAR的移植。

27.3 动态内存的使用方法

下面分别以MDK和IAR为例进行说明:

27.3.1 MDK上的动态内存用法

  • 定义动态内存区

比如当前的主RAM用的DTCM,我们就可以直接定义一块大的数组作为动态内存空间:

/* DTCM, 64KB */
/* 用于获取当前使用的空间大小 */
mem_head_t *DTCMUsed;
/* 定义为64位变量,首地址是8字节对齐 */
uint64_t AppMallocDTCM[*/];

如果要使用AXI SRAM作为动态内存空间,可以使用__attribute__((at( )))指定地址。

/* D1域, AXI SRAM, 512KB */
/* 用于获取当前使用的空间大小 */
mem_head_t *AXISRAMUsed;
/* 定义为64位变量,首地址是8字节对齐 */
uint64_t AppMallocAXISRAM[*/]__attribute__((at(0x24000000)));
  • 初始化动态内存区

调用动态内存管理提供的函数osRtxMemoryInit即可做初始化:

osRtxMemoryInit(AppMallocDTCM,    sizeof(AppMallocDTCM));
osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));
  • 申请动态内存

通过函数void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type)做动态内存申请。

第1个参数填写内存区首地址,比如申请的AppMallocDTCM,就填AppMallocDTCM即可。

第2个参数填写申请的字节大小,单位字节。

第3个参数固定填0即可。

返回值是所申请缓冲区的首地址,如果没有空间可用,将返回NULL,这点要特别注意!

举个例子:

uint32_t *DTCM_Addres0, *AXISRAM_Addres0;

/* 从DTCM申请280字节空间,使用指针变量DTCM_Addres0操作这些空间时不要超过280字节大小 */
DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, , );
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM总大小 = %d字节,申请大小 = 0280字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->size, DTCMUsed->used); /* 从AXI SRAM 申请160字节空间,使用指针变量AXISRAM_Addres0操作这些空间时不要超过160字节大小 */
AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, , );
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("AXI SRAM总大小 = %d字节,申请大小 = 0162字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->size, AXISRAMUsed->used);

申请了空间后,就可以直接使用了。另外注意红色字体部分,通过DTCMUsed->used和AXISRAMUsed->used可以获取当前使用的空间大小。

  • 释放动态内存

通过函数uint32_t osRtxMemoryFree (void *mem, void *block)做动态内存释放。

第1个参数填写内存区首地址,比如释放的AppMallocDTCM,就填AppMallocDTCM即可。

第2个参数填写申请内存时所获取的内存区首地址,这里用于释放。

返回值,返回1表示成功,返回0表示失败。

举个例子:

/* 释放从DTCM申请的280字节空间 */
osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("释放DTCM动态内存区申请的0280字节,当前共使用大小 = %d字节\r\n", DTCMUsed->used); /* 释放从AXI SRAM申请的160字节空间 */
osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("释放AXI SRAM动态内存区申请的0160字节,当前共使用大小 = %d字节\r\n", AXISRAMUsed->used);

27.3.2 IAR上的动态内存用法

注:IAR使用这个动态内存管理,仅在定义时跟MDK略有不同,其它地方是一样的。

  • 定义动态内存区

比如当前的主RAM用的DTCM,我们就可以直接定义一块大的数组作为动态内存空间:

/* DTCM, 64KB */
/* 用于获取当前使用的空间大小 */
mem_head_t *DTCMUsed;
/* 定义为64位变量,首地址是8字节对齐 */
uint64_t AppMallocDTCM[*/];

如果要使用AXI SRAM作为动态内存空间,可以使用__attribute__((at( )))指定地址。

/* D1域, AXI SRAM, 512KB */
/* 用于获取当前使用的空间大小 */
mem_head_t *AXISRAMUsed;
/* 指定下面数组的地址为0x24000000 */
#pragma location = 0x24000000
uint64_t AppMallocAXISRAM[*/];
  • 初始化动态内存区

调用动态内存管理提供的函数osRtxMemoryInit即可做初始化:

osRtxMemoryInit(AppMallocDTCM,    sizeof(AppMallocDTCM));
osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));
  • 申请动态内存

通过函数void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type)做动态内存申请。

第1个参数填写内存区首地址,比如申请的AppMallocDTCM,就填AppMallocDTCM即可。

第2个参数填写申请的字节大小,单位字节。

第3个参数固定填0即可。

返回值是所申请缓冲区的首地址,如果没有空间可用,将返回NULL,这点要特别注意!

举个例子:

uint32_t *DTCM_Addres0, *AXISRAM_Addres0;

/* 从DTCM申请280字节空间,使用指针变量DTCM_Addres0操作这些空间时不要超过280字节大小 */
DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, , );
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM总大小 = %d字节,申请大小 = 0280字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->size, DTCMUsed->used); /* 从AXI SRAM 申请160字节空间,使用指针变量AXISRAM_Addres0操作这些空间时不要超过160字节大小 */
AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, , );
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("AXI SRAM总大小 = %d字节,申请大小 = 0162字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->size, AXISRAMUsed->used);

申请了空间后,就可以直接使用了。另外注意红色字体部分,通过DTCMUsed->used和AXISRAMUsed->used可以获取当前使用的空间大小。

  • 释放动态内存

通过函数uint32_t osRtxMemoryFree (void *mem, void *block)做动态内存释放。

第1个参数填写内存区首地址,比如释放的AppMallocDTCM,就填AppMallocDTCM即可。

第2个参数填写申请内存时所获取的内存区首地址,这里用于释放。

返回值,返回1表示成功,返回0表示失败。

举个例子:

/* 释放从DTCM申请的280字节空间 */
osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("释放DTCM动态内存区申请的0280字节,当前共使用大小 = %d字节\r\n", DTCMUsed->used); /* 释放从AXI SRAM申请的160字节空间 */
osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("释放AXI SRAM动态内存区申请的0160字节,当前共使用大小 = %d字节\r\n", AXISRAMUsed->used)

27.4 实验例程说明(MDK)

配套例子:

V7-006_TCM,SRAM等五块内存的动态内存分配实现

实验目的:

  1. 学习TCM,SRAM等五块内存的动态内存分配实现。

实验内容:

  1. 启动自动重装软件定时器0,每100ms翻转一次LED2。

实验操作:

  1. K1键按下,从DTCM依次申请280字节,64字节和6111字节。
  2. K1键松开,释放从DTCM申请的空间。
  3. K2键按下,从AXI SRAM依次申请160字节,32字节和2333字节。
  4. K2键松开,释放从AXI SRAM申请的空间。
  5. K3键按下,从D2域SRAM依次申请200字节,96字节和4111字节。
  6. K3键松开,释放从D2域SRAM申请的空间。
  7. 摇杆OK键按下,从D3域SRAM依次申请300字节,128字节和5111字节。
  8. 摇杆OK键松开,释放从D3域SRAM申请的空间。

上电后串口打印的信息:

波特率 115200,数据位 8,奇偶校验位无,停止位 1

程序设计:

系统栈大小分配:

RAM空间用的DTCM:

硬件外设初始化

硬件外设的初始化是在 bsp.c 文件实现:

/*
*********************************************************************************************************
* 函 数 名: bsp_Init
* 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{
/* 配置MPU */
MPU_Config(); /* 使能L1 Cache */
CPU_CACHE_Enable(); /*
STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟:
- 调用函数HAL_InitTick,初始化滴答时钟中断1ms。
- 设置NVIV优先级分组为4。
*/
HAL_Init(); /*
配置系统时钟到400MHz
- 切换使用HSE。
- 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。
*/
SystemClock_Config(); /*
Event Recorder:
- 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。
- 默认不开启,如果要使能此选项,务必看V7开发板用户手册第xx章
*/
#if Enable_EventRecorder == 1
/* 初始化EventRecorder并开启 */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
#endif bsp_InitKey(); /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */
bsp_InitTimer(); /* 初始化滴答定时器 */
bsp_InitUart(); /* 初始化串口 */
bsp_InitExtIO(); /* 初始化FMC总线74HC574扩展IO. 必须在 bsp_InitLed()前执行 */
bsp_InitLed(); /* 初始化LED */
}
  • MPU配置和Cache配置:

数据Cache和指令Cache都开启。

AXI SRAM的MPU属性:

Write back, Read allocate,Write allocate。

FMC的扩展IO的MPU属性:

必须Device或者Strongly Ordered。

D2 SRAM1,SRAM2和SRAM3的MPU属性:

Write through, read allocate,no write allocate。

D3 SRAM4的MPU属性:

Write through, read allocate,no write allocate。

/*
*********************************************************************************************************
* 函 数 名: MPU_Config
* 功能说明: 配置MPU
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void MPU_Config( void )
{
MPU_Region_InitTypeDef MPU_InitStruct; /* 禁止 MPU */
HAL_MPU_Disable(); /* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* 配置SRAM1的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_128KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* 配置SRAM2的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30020000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_128KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* 配置SRAM3的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_32KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* 配置SRAM4的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x38000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER5;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /*使能 MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
} /*
*********************************************************************************************************
* 函 数 名: CPU_CACHE_Enable
* 功能说明: 使能L1 Cache
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void CPU_CACHE_Enable(void)
{
/* 使能 I-Cache */
SCB_EnableICache(); /* 使能 D-Cache */
SCB_EnableDCache();
}

主功能:

主程序实现如下操作:

  • 启动自动重装软件定时器0,每100ms翻转一次LED2。
  • K1键按下,从DTCM依次申请280字节,64字节和6111字节。
  • K1键松开,释放从DTCM申请的空间。
  • K2键按下,从AXI SRAM依次申请160字节,32字节和2333字节。
  • K2键松开,释放从AXI SRAM申请的空间。
  • K3键按下,从D2域SRAM依次申请200字节,96字节和4111字节。
  • K3键松开,释放从D2域SRAM申请的空间。
  • 摇杆OK键按下,从D3域SRAM依次申请300字节,128字节和5111字节。
  • 摇杆OK键松开,释放从D3域SRAM申请的空间。
/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: c程序入口
* 形 参: 无
* 返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{
uint8_t ucKeyCode; /* 按键代码 */
uint32_t *DTCM_Addres0, *AXISRAM_Addres0, *SRAM1_Addres0, *SRAM4_Addres0;
uint16_t *DTCM_Addres1, *AXISRAM_Addres1, *SRAM1_Addres1, *SRAM4_Addres1;
uint8_t *DTCM_Addres2, *AXISRAM_Addres2, *SRAM1_Addres2, *SRAM4_Addres2; bsp_Init(); /* 硬件初始化 */ /* 初始化动态内存空间 */
osRtxMemoryInit(AppMallocDTCM, sizeof(AppMallocDTCM));
osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));
osRtxMemoryInit(AppMallocSRAM1, sizeof(AppMallocSRAM1));
osRtxMemoryInit(AppMallocSRAM4, sizeof(AppMallocSRAM4)); PrintfLogo(); /* 打印例程名称和版本等信息 */
PrintfHelp(); /* 打印操作提示 */ bsp_StartAutoTimer(, ); /* 启动1个100ms的自动重装的定时器 */ /* 进入主程序循环体 */
while ()
{
bsp_Idle(); /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */ /* 判断定时器超时时间 */
if (bsp_CheckTimer())
{
/* 每隔100ms 进来一次 */
bsp_LedToggle();
} /* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
if (ucKeyCode != KEY_NONE)
{
switch (ucKeyCode)
{
/* 从DTCM依次申请280字节,64字节和6111字节 */
case KEY_DOWN_K1:
/* 从DTCM申请280字节空间,使用指针变量DTCM_Addres0操作这些空间时不要超过280字节大小 */
printf("=========================================================\r\n");
DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, , );
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM总大小 = %d字节,申请大小 = 0280字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->size, DTCMUsed->used); /* 从DTCM申请64字节空间,使用指针变量DTCM_Addres1操作这些空间时不要超过64字节大小 */
DTCM_Addres1 = osRtxMemoryAlloc(AppMallocDTCM, , );
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM总大小 = %d字节,申请大小 = 0064字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->size, DTCMUsed->used); /* 从DTCM申请6111字节空间,使用指针变量DTCM_Addres2操作这些空间时不要超过6111字节大小 */
DTCM_Addres2 = osRtxMemoryAlloc(AppMallocDTCM, , );
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM总大小 = %d字节,申请大小 = 6111字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->size, DTCMUsed->used);
break; /* 释放从DTCM申请的空间 */
case KEY_UP_K1:
/* 释放从DTCM申请的280字节空间 */
osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("释放DTCM动态内存区申请的0280字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->used); /* 释放从DTCM申请的64字节空间 */
osRtxMemoryFree(AppMallocDTCM, DTCM_Addres1);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("释放DTCM动态内存区申请的0064字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->used); /* 释放从DTCM申请的6111字节空间 */
osRtxMemoryFree(AppMallocDTCM, DTCM_Addres2);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("释放DTCM动态内存区申请的6111字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->used);
break; /* 从AXI SRAM依次申请160字节,32字节和2333字节 */
case KEY_DOWN_K2:
/* 从AXI SRAM 申请160字节空间,使用指针变量AXISRAM_Addres0操作这些空间时不要超过160字节大小 */
printf("=========================================================\r\n");
AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, , );
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("AXI SRAM总大小 = %d字节,申请大小 = 0162字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->size, AXISRAMUsed->used); /* 从AXI SRAM 申请32字节空间,使用指针变量AXISRAM_Addres1操作这些空间时不要超过32字节大小 */
AXISRAM_Addres1 = osRtxMemoryAlloc(AppMallocAXISRAM, , );
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("AXI SRAM总大小 = %d字节,申请大小 = 0032字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->size, AXISRAMUsed->used); /* 从AXI SRAM 申请2333字节空间,使用指针变量AXISRAM_Addres2操作这些空间时不要超过2333字节大小 */
AXISRAM_Addres2 = osRtxMemoryAlloc(AppMallocAXISRAM, , );
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("AXI SRAM总大小 = %d字节,申请大小 = 2333字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->size, AXISRAMUsed->used);
break; /* 释放从AXI SRAM申请的空间 */
case KEY_UP_K2:
/* 释放从AXI SRAM申请的160字节空间 */
osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("释放AXI SRAM动态内存区申请的0160字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->used); /* 释放从AXI SRAM申请的32字节空间 */
osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres1);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("释放AXI SRAM动态内存区申请的0032字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->used); /* 释放从AXI SRAM申请的2333字节空间 */
osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres2);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("释放AXI SRAM动态内存区申请的2333字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->used);
break; /* 从D2域SRAM依次申请200字节,96字节和4111字节 */
case KEY_DOWN_K3:
/* 从D2域的SRAM申请200字节空间,使用指针变量SRAM1_Addres0操作这些空间时不要超过200字节大小 */
printf("=========================================================\r\n");
SRAM1_Addres0 = osRtxMemoryAlloc(AppMallocSRAM1, , );
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("D2域SRAM总大小 = %d字节,申请大小 = 0200字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->size, SRAM1Used->used); /* 从D2域的SRAM申请96字节空间,使用指针变量SRAM1_Addres1操作这些空间时不要超过96字节大小 */
SRAM1_Addres1 = osRtxMemoryAlloc(AppMallocSRAM1, , );
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("D2域SRAM总大小 = %d字节,申请大小 = 0096字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->size, SRAM1Used->used); /* 从D2域的SRAM申请4111字节空间,使用指针变量SRAM1_Addres2操作这些空间时不要超过4111字节大小 */
SRAM1_Addres2 = osRtxMemoryAlloc(AppMallocSRAM1, , );
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("D2域SRAM总大小 = %d字节,申请大小 = 4111字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->size, SRAM1Used->used);
break; /* 释放从D2域SRAM申请的空间 */
case KEY_UP_K3:
/* 释放从D2域的SRAM申请的200字节空间 */
osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres0);
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("释放D2域SRAM动态内存区申请的0200字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->used); /* 释放从D2域的SRAM申请的96字节空间 */
osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres1);
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("释放D2域SRAM动态内存区申请的0096字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->used); /* 释放从D2域的SRAM申请的4111字节空间 */
osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres2);
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("释放D2域SRAM动态内存区申请的4111字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->used);
break; /* 从D3域SRAM依次申请300字节,128字节和5111字节 */
case JOY_DOWN_OK:
/* 从D3域的SRAM申请300字节空间,使用指针变量SRAM4_Addres0操作这些空间时不要超过300字节大小 */
printf("=========================================================\r\n");
SRAM4_Addres0 = osRtxMemoryAlloc(AppMallocSRAM4, , );
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("D3域SRAM总大小 = %d字节,申请大小 = 0300字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->size, SRAM4Used->used); /* 从D3域的SRAM申请96字节空间,使用指针变量SRAM4_Addres1操作这些空间时不要超过96字节大小 */
SRAM4_Addres1 = osRtxMemoryAlloc(AppMallocSRAM4, , );
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("D3域SRAM总大小 = %d字节,申请大小 = 0128字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->size, SRAM4Used->used); /* 从D3域的SRAM申请5111字节空间,使用指针变量SRAM4_Addres2操作这些空间时不要超过5111字节大小 */
SRAM4_Addres2 = osRtxMemoryAlloc(AppMallocSRAM4, , );
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("D3域SRAM总大小 = %d字节,申请大小 = 5111字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->size, SRAM4Used->used);
break; /* 释放从D3域SRAM申请的空间 */
case JOY_UP_OK:
/* 释放从D3域的SRAM申请的300字节空间 */
osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres0);
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("释放D3域SRAM动态内存区申请的0300字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->used); /* 释放从D3域的SRAM申请的128字节空间 */
osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres1);
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("释放D3域SRAM动态内存区申请的0128字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->used); /* 释放从D3域的SRAM申请的5111字节空间 */
osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres2);
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("释放D3域SRAM动态内存区申请的5111字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->used);
break; default:
/* 其它的键值不处理 */
break;
}
}
}
}

27.5 实验例程说明(IAR)

配套例子:

V7-006_TCM,SRAM等五块内存的动态内存分配实现

实验目的:

  1. 学习TCM,SRAM等五块内存的动态内存分配实现。

实验内容:

  1. 启动自动重装软件定时器0,每100ms翻转一次LED2。

实验操作:

  1. K1键按下,从DTCM依次申请280字节,64字节和6111字节。
  2. K1键松开,释放从DTCM申请的空间。
  3. K2键按下,从AXI SRAM依次申请160字节,32字节和2333字节。
  4. K2键松开,释放从AXI SRAM申请的空间。
  5. K3键按下,从D2域SRAM依次申请200字节,96字节和4111字节。
  6. K3键松开,释放从D2域SRAM申请的空间。
  7. 摇杆OK键按下,从D3域SRAM依次申请300字节,128字节和5111字节。
  8. 摇杆OK键松开,释放从D3域SRAM申请的空间。

上电后串口打印的信息:

波特率 115200,数据位 8,奇偶校验位无,停止位 1

程序设计:

系统栈大小分配:

RAM空间用的DTCM:

硬件外设初始化

硬件外设的初始化是在 bsp.c 文件实现:

/*
*********************************************************************************************************
* 函 数 名: bsp_Init
* 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{
/* 配置MPU */
MPU_Config(); /* 使能L1 Cache */
CPU_CACHE_Enable(); /*
STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟:
- 调用函数HAL_InitTick,初始化滴答时钟中断1ms。
- 设置NVIV优先级分组为4。
*/
HAL_Init(); /*
配置系统时钟到400MHz
- 切换使用HSE。
- 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。
*/
SystemClock_Config(); /*
Event Recorder:
- 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。
- 默认不开启,如果要使能此选项,务必看V7开发板用户手册第xx章
*/
#if Enable_EventRecorder == 1
/* 初始化EventRecorder并开启 */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
#endif bsp_InitKey(); /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */
bsp_InitTimer(); /* 初始化滴答定时器 */
bsp_InitUart(); /* 初始化串口 */
bsp_InitExtIO(); /* 初始化FMC总线74HC574扩展IO. 必须在 bsp_InitLed()前执行 */
bsp_InitLed(); /* 初始化LED */
}

MPU配置和Cache配置:

数据Cache和指令Cache都开启。

AXI SRAM的MPU属性:

Write back, Read allocate,Write allocate。

FMC的扩展IO的MPU属性:

必须Device或者Strongly Ordered。

D2 SRAM1,SRAM2和SRAM3的MPU属性:

Write through, read allocate,no write allocate。

D3 SRAM4的MPU属性:

Write through, read allocate,no write allocate。

/*
*********************************************************************************************************
* 函 数 名: MPU_Config
* 功能说明: 配置MPU
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void MPU_Config( void )
{
MPU_Region_InitTypeDef MPU_InitStruct; /* 禁止 MPU */
HAL_MPU_Disable(); /* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* 配置SRAM1的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_128KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* 配置SRAM2的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30020000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_128KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* 配置SRAM3的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_32KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* 配置SRAM4的属性为Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x38000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER5;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /*使能 MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
} /*
*********************************************************************************************************
* 函 数 名: CPU_CACHE_Enable
* 功能说明: 使能L1 Cache
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void CPU_CACHE_Enable(void)
{
/* 使能 I-Cache */
SCB_EnableICache(); /* 使能 D-Cache */
SCB_EnableDCache();
}

主功能:

主程序实现如下操作:

  • 启动自动重装软件定时器0,每100ms翻转一次LED2。
  • K1键按下,从DTCM依次申请280字节,64字节和6111字节。
  • K1键松开,释放从DTCM申请的空间。
  • K2键按下,从AXI SRAM依次申请160字节,32字节和2333字节。
  • K2键松开,释放从AXI SRAM申请的空间。
  • K3键按下,从D2域SRAM依次申请200字节,96字节和4111字节。
  • K3键松开,释放从D2域SRAM申请的空间。
  • 摇杆OK键按下,从D3域SRAM依次申请300字节,128字节和5111字节。
  • 摇杆OK键松开,释放从D3域SRAM申请的空间。
/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: c程序入口
* 形 参: 无
* 返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{
uint8_t ucKeyCode; /* 按键代码 */
uint32_t *DTCM_Addres0, *AXISRAM_Addres0, *SRAM1_Addres0, *SRAM4_Addres0;
uint16_t *DTCM_Addres1, *AXISRAM_Addres1, *SRAM1_Addres1, *SRAM4_Addres1;
uint8_t *DTCM_Addres2, *AXISRAM_Addres2, *SRAM1_Addres2, *SRAM4_Addres2; bsp_Init(); /* 硬件初始化 */ /* 初始化动态内存空间 */
osRtxMemoryInit(AppMallocDTCM, sizeof(AppMallocDTCM));
osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));
osRtxMemoryInit(AppMallocSRAM1, sizeof(AppMallocSRAM1));
osRtxMemoryInit(AppMallocSRAM4, sizeof(AppMallocSRAM4)); PrintfLogo(); /* 打印例程名称和版本等信息 */
PrintfHelp(); /* 打印操作提示 */ bsp_StartAutoTimer(, ); /* 启动1个100ms的自动重装的定时器 */ /* 进入主程序循环体 */
while ()
{
bsp_Idle(); /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */ /* 判断定时器超时时间 */
if (bsp_CheckTimer())
{
/* 每隔100ms 进来一次 */
bsp_LedToggle();
} /* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
if (ucKeyCode != KEY_NONE)
{
switch (ucKeyCode)
{
/* 从DTCM依次申请280字节,64字节和6111字节 */
case KEY_DOWN_K1:
/* 从DTCM申请280字节空间,使用指针变量DTCM_Addres0操作这些空间时不要超过280字节大小 */
printf("=========================================================\r\n");
DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, , );
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM总大小 = %d字节,申请大小 = 0280字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->size, DTCMUsed->used); /* 从DTCM申请64字节空间,使用指针变量DTCM_Addres1操作这些空间时不要超过64字节大小 */
DTCM_Addres1 = osRtxMemoryAlloc(AppMallocDTCM, , );
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM总大小 = %d字节,申请大小 = 0064字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->size, DTCMUsed->used); /* 从DTCM申请6111字节空间,使用指针变量DTCM_Addres2操作这些空间时不要超过6111字节大小 */
DTCM_Addres2 = osRtxMemoryAlloc(AppMallocDTCM, , );
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM总大小 = %d字节,申请大小 = 6111字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->size, DTCMUsed->used);
break; /* 释放从DTCM申请的空间 */
case KEY_UP_K1:
/* 释放从DTCM申请的280字节空间 */
osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("释放DTCM动态内存区申请的0280字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->used); /* 释放从DTCM申请的64字节空间 */
osRtxMemoryFree(AppMallocDTCM, DTCM_Addres1);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("释放DTCM动态内存区申请的0064字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->used); /* 释放从DTCM申请的6111字节空间 */
osRtxMemoryFree(AppMallocDTCM, DTCM_Addres2);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("释放DTCM动态内存区申请的6111字节,当前共使用大小 = %d字节\r\n",
DTCMUsed->used);
break; /* 从AXI SRAM依次申请160字节,32字节和2333字节 */
case KEY_DOWN_K2:
/* 从AXI SRAM 申请160字节空间,使用指针变量AXISRAM_Addres0操作这些空间时不要超过160字节大小 */
printf("=========================================================\r\n");
AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, , );
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("AXI SRAM总大小 = %d字节,申请大小 = 0162字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->size, AXISRAMUsed->used); /* 从AXI SRAM 申请32字节空间,使用指针变量AXISRAM_Addres1操作这些空间时不要超过32字节大小 */
AXISRAM_Addres1 = osRtxMemoryAlloc(AppMallocAXISRAM, , );
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("AXI SRAM总大小 = %d字节,申请大小 = 0032字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->size, AXISRAMUsed->used); /* 从AXI SRAM 申请2333字节空间,使用指针变量AXISRAM_Addres2操作这些空间时不要超过2333字节大小 */
AXISRAM_Addres2 = osRtxMemoryAlloc(AppMallocAXISRAM, , );
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("AXI SRAM总大小 = %d字节,申请大小 = 2333字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->size, AXISRAMUsed->used);
break; /* 释放从AXI SRAM申请的空间 */
case KEY_UP_K2:
/* 释放从AXI SRAM申请的160字节空间 */
osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("释放AXI SRAM动态内存区申请的0160字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->used); /* 释放从AXI SRAM申请的32字节空间 */
osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres1);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("释放AXI SRAM动态内存区申请的0032字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->used); /* 释放从AXI SRAM申请的2333字节空间 */
osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres2);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("释放AXI SRAM动态内存区申请的2333字节,当前共使用大小 = %d字节\r\n",
AXISRAMUsed->used);
break; /* 从D2域SRAM依次申请200字节,96字节和4111字节 */
case KEY_DOWN_K3:
/* 从D2域的SRAM申请200字节空间,使用指针变量SRAM1_Addres0操作这些空间时不要超过200字节大小 */
printf("=========================================================\r\n");
SRAM1_Addres0 = osRtxMemoryAlloc(AppMallocSRAM1, , );
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("D2域SRAM总大小 = %d字节,申请大小 = 0200字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->size, SRAM1Used->used); /* 从D2域的SRAM申请96字节空间,使用指针变量SRAM1_Addres1操作这些空间时不要超过96字节大小 */
SRAM1_Addres1 = osRtxMemoryAlloc(AppMallocSRAM1, , );
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("D2域SRAM总大小 = %d字节,申请大小 = 0096字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->size, SRAM1Used->used); /* 从D2域的SRAM申请4111字节空间,使用指针变量SRAM1_Addres2操作这些空间时不要超过4111字节大小 */
SRAM1_Addres2 = osRtxMemoryAlloc(AppMallocSRAM1, , );
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("D2域SRAM总大小 = %d字节,申请大小 = 4111字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->size, SRAM1Used->used);
break; /* 释放从D2域SRAM申请的空间 */
case KEY_UP_K3:
/* 释放从D2域的SRAM申请的200字节空间 */
osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres0);
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("释放D2域SRAM动态内存区申请的0200字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->used); /* 释放从D2域的SRAM申请的96字节空间 */
osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres1);
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("释放D2域SRAM动态内存区申请的0096字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->used); /* 释放从D2域的SRAM申请的4111字节空间 */
osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres2);
SRAM1Used = MemHeadPtr(AppMallocSRAM1);
printf("释放D2域SRAM动态内存区申请的4111字节,当前共使用大小 = %d字节\r\n",
SRAM1Used->used);
break; /* 从D3域SRAM依次申请300字节,128字节和5111字节 */
case JOY_DOWN_OK:
/* 从D3域的SRAM申请300字节空间,使用指针变量SRAM4_Addres0操作这些空间时不要超过300字节大小 */
printf("=========================================================\r\n");
SRAM4_Addres0 = osRtxMemoryAlloc(AppMallocSRAM4, , );
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("D3域SRAM总大小 = %d字节,申请大小 = 0300字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->size, SRAM4Used->used); /* 从D3域的SRAM申请96字节空间,使用指针变量SRAM4_Addres1操作这些空间时不要超过96字节大小 */
SRAM4_Addres1 = osRtxMemoryAlloc(AppMallocSRAM4, , );
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("D3域SRAM总大小 = %d字节,申请大小 = 0128字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->size, SRAM4Used->used); /* 从D3域的SRAM申请5111字节空间,使用指针变量SRAM4_Addres2操作这些空间时不要超过5111字节大小 */
SRAM4_Addres2 = osRtxMemoryAlloc(AppMallocSRAM4, , );
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("D3域SRAM总大小 = %d字节,申请大小 = 5111字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->size, SRAM4Used->used);
break; /* 释放从D3域SRAM申请的空间 */
case JOY_UP_OK:
/* 释放从D3域的SRAM申请的300字节空间 */
osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres0);
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("释放D3域SRAM动态内存区申请的0300字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->used); /* 释放从D3域的SRAM申请的128字节空间 */
osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres1);
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("释放D3域SRAM动态内存区申请的0128字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->used); /* 释放从D3域的SRAM申请的5111字节空间 */
osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres2);
SRAM4Used = MemHeadPtr(AppMallocSRAM4);
printf("释放D3域SRAM动态内存区申请的5111字节,当前共使用大小 = %d字节\r\n",
SRAM4Used->used);
break; default:
/* 其它的键值不处理 */
break;
}
}
}
}

27.6 总结

本章节就为大家讲解这么多,还是比较有项目实用价值的,特别是MP3编解码,JPEG编解码,视频播放器,矢量字体等需要动态内存的场合。

最新文章

  1. Python 环境搭建,开发工具,基本语法
  2. web自动化工具-开篇
  3. Apache+Tomcat实现负载均衡
  4. LayaAir引擎——(十)
  5. git 教程(1)--安装git
  6. 【我所理解的Cocos2d-x】第六章 精灵Sprite 读书笔记
  7. 线程学习笔记(EventWaitHandler)AutoResetEvent的使用
  8. python 3 安装 scrapy 并运行成功
  9. 在数组中搜索数据用 filteredArrayUsingPredicate
  10. asp.net 下OnClientClick的妙用
  11. 4.锁定--Java的LockSupport.park()实现分析
  12. 关于FlagsAttribute
  13. 《剑指offer》从尾到头打印链表
  14. 【AtCoder】ARC071
  15. scrapy使用MongoDB简单示例
  16. Neural Networks and Deep Learning(week3)Planar data classification with one hidden layer(基于单隐藏层神经网络的平面数据分类)
  17. The last packet sent successfully to the server was 0 milliseconds ago.[nutch---mysql ]
  18. PCA图
  19. PTA (Advanced Level) 1005 Spell It Right
  20. mitmproxy

热门文章

  1. @supports特性查询
  2. springboot模板
  3. [洛谷P1169][题解][ZJOI2007]午餐
  4. qt 自定义控件窗口提升
  5. SpringBoot开发准备工作,保存备用,
  6. Python集合类型的操作与应用
  7. JavPlayer:AI破坏马赛克,大量马赛克破坏版影片流出
  8. ETCD:配置参数
  9. 使用 Docker 构建 Nebula Graph 源码
  10. Git - Git推送本地分支到远程分支报错(! [rejected] non-fast-forward)的解决办法