本帖最后由 正点原子运营 于 2024-5-14 17:36 编辑
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板
2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版
6)正点原子STM32技术交流QQ群:725095144
本章将介绍正点原子提供的内存管理库的使用,通过使用内存管理库可以提高内存的使用效率,在大型的应用开发中,是必不可少的工具。通过本章的学习,读者将学习到正点原子内存管理库的使用。 本章分为如下几个小节: 45.1 硬件设计 45.2 程序设计 45.3 下载验证
45.1 硬件设计 45.1.1 例程功能 1. 按下WKUP按键可从内存SRAM申请内存,并在LCD上显示相关信息 2. 按下KEY0按键可释放最近一次从SRAM申请到的内存 3. LED0闪烁,提示程序正在运行
45.1.2 硬件资源 1. LED LED0 - PB5 2. 正点原子2.8/3.5/4.3/7/10寸TFTLCD模块 3. 按键 WKUP - PA0 KEY0 - PE4
45.1.3 原理图 本章实验使用的内存管理库为软件库,因此没有对应的连接原理图。
45.2 程序设计 45.2.1 内存管理库的使用 正点原子提供的内存管理库包含两个文件,分别为:malloc.c和malloc.h,本章实验配套的实验例程中已经提供了这两个文件,并且已经针对正点原子M144Z-M3最小系统板STM32F103版进行了移植适配,用户在使用时,仅需将这两个文件添加到自己的工程即可,如下图所示: 内存管理库中提供了内存管理初始化、申请内存和释放内存等函数,使用非常方便。 在进行内存申请和释放之前,需要使用内存初始化函数对内存进行初始化,内存管理初始化的使用示例,如下所示: - #include "./MALLOC/malloc.h"
- void example_fun(void)
- {
- /* 初始化内部SRAM内存池 */
- my_mem_init(SRAMIN);
- }
复制代码初始化内存后,便可以在需要内存的时候申请内存,申请内存函数的使用示例,如下所示: - #include "./MALLOC/malloc.h"
- void example_fun(void)
- {
- uint8_t ptr;
-
- /* 初始化内部SRAM内存池 */
- my_mem_init(SRAMIN);
-
- /* 申请1KB内存 */
- ptr= (uint8_t *)mymalloc(SRAMIN, 1024);
-
- /* Do something. */
- }
复制代码在内存使用完毕后,需要及时释放内存,否则可能产生内存泄漏,释放内存函数的使用示例,如下所示: - #include "./MALLOC/malloc.h"
- void example_fun(void)
- {
- uint8_t ptr;
-
- /* 初始化内部SRAM内存池 */
- my_mem_init(SRAMIN);
-
- /* 申请1KB内存 */
- ptr= (uint8_t *)mymalloc(SRAMIN, 1024);
-
- /* Do something. */
-
- /* 释放无用内存 */
- myfree(SRAMIN, ptr);
- }
复制代码45.2.2 实验应用代码 本章实验的应用代码,如下所示: - int main(void)
- {
- uint8_t t = 0;
- uint8_t key;
- uint8_t *p_sramin = NULL;
- uint32_t tp_sramin = 0;
- uint8_t paddr[32];
- uint16_t memused;
-
- HAL_Init(); /* 初始化HAL库 */
- sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
- delay_init(72); /* 初始化延时 */
- usart_init(115200); /* 初始化串口 */
- led_init(); /* 初始化LED */
- key_init(); /* 初始化按键 */
- lcd_init(); /* 初始化LCD */
- my_mem_init(SRAMIN); /* 初始化内部SRAM内存池 */
-
- lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
- lcd_show_string(30, 70, 200, 16, 16, "MALLOCTEST", RED);
- lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
-
- lcd_show_string(30, 110, 200, 16, 16, "KEY0:Malloc& WR & Show", RED);
- lcd_show_string(30, 130, 200, 16, 16, "KEY_UP:Free", RED);
-
- lcd_show_string(30, 162, 200, 16, 16, "SRAMINUSED:", BLUE);
-
- while (1)
- {
- key = key_scan(0);
- if (key == WKUP_PRES)
- {
- /* 申请内存 */
- p_sramin = mymalloc(SRAMIN, 2048);
-
- /* 判断内存申请是否成功 */
- if (p_sramin != NULL)
- {
- /* 使用申请到的内存 */
- sprintf((char *)p_sramin,
- "SRAMIN: Malloc Test%03d", t + SRAMIN);
- lcd_show_string(30, 226, 239, 16, 16, (char *)p_sramin, BLUE);
- }
- else
- {
- myfree(SRAMIN, p_sramin);
- p_sramin = NULL;
- }
- }
- else if (key == KEY0_PRES)
- {
- /* 释放内存 */
- myfree(SRAMIN, p_sramin);
- p_sramin = NULL;
- }
-
- /* 显示申请到内存的首地址 */
- if (tp_sramin != (uint32_t)p_sramin)
- {
- tp_sramin = (uint32_t)p_sramin;
-
- sprintf((char *)paddr,
- "SRAMIN: Addr: 0x%08X", (uint32_t)p_sramin);
- lcd_show_string(30, 194, 239, 16, 16, (char *)paddr, BLUE);
- }
- else if (p_sramin == NULL)
- {
- lcd_fill(30, 194, 239, 319, WHITE);
- }
-
- if (++t == 20)
- {
- t = 0;
-
- /* 显示内部SRAM使用率 */
- memused = my_mem_perused(SRAMIN);
- sprintf((char *)paddr, "%d.%01d%%", memused / 10, memused % 10);
- lcd_show_string(30 + 96, 162, 200, 16, 16, (char *)paddr, BLUE);
-
- LED0_TOGGLE();
- }
-
- delay_ms(10);
- }
- }
复制代码可以看到,本实验的应用代码使用到了一个内存池,为内部SRAM,在完成内存池初始化后,便在LCD上实时刷新显示这个内存池的使用量,以及检测按键输入,若检测到WKUP按键被按下,则从这个内存池中申请一块内存,并写入测试数据,然后将申请到的这块内存的起始地址即内存中写入的测试数据在LCD上进行显示,若检测到KEY0按键被按下,则释放最近一次申请的这块内存回内存池中。
45.3 下载验证 在完成编译和烧录操作后,可以看到LCD上实时地显示了一个内存池的使用情况,此时按下WKUP按键申请内存,可以看到这个内存池的使用量增加,并且LCD上显示了申请到的一个内存的起始地址和内存中写入的测试数据,接着按下KEY0按键释放内存,可以看到,LCD上显示的内存信息消失,并且因为内存已经被释放回内存池,因此内存池的使用量较少。 |