5. 动态内存管理(基于硬件MMU)
AD23N 支持基于硬件MMU实现的动态内存管理,系统通过虚拟内存机制提供了一种更灵活、更安全的内存管理方式。
本章节主要围绕以下几点讲解:
5.1. MMU相关接口
5.1.1. 函数void mem_init(void)
该函数用于初始化MMU,SDK已在main函数调用。
5.1.2. 函数void *malloc(size_t size)
该函数用于申请一块虚拟内存。其中参数::
1、size:申请内存大小,单位为byte 2、返回值: 地址:申请内存成功。 空指针:申请内存失败。
5.1.3. 函数void *zalloc(size_t size)
该函数用于申请一块虚拟内存,并且对申请到的内存进行清0。其中参数::
1、size:申请内存大小,单位为byte 2、返回值: 地址:申请内存成功。 空指针:申请内存失败。
5.1.4. 函数void free(void *pv)
该函数用于释放申请过的内存。其中参数::
1、pv:申请过的动态内存指针,如果传入的指针已经被释放过,会出现MMU访问异常。free之后的指针还是会保留之前申请到的值,建议free之后将指针清空。
5.2. 一些旧的内存管理函数说明
5.2.1. 函数void *my_malloc(u32 size, mm_type xType)
对于支持MMU的芯片,该函数内部已拦截为使用mmu的malloc,因此可以当作void *malloc(size_t size)使用,xType参数无效。
5.2.2. void *my_free(void *pv)
对于支持MMU的芯片,函数内部已拦截为使用mmu的free,因此可以当作void free(void *pv)使用。
5.3. MMU在SDK的使用情况
AD23N SDK已经用于解码、编码、音效、文件系统、以及SARADC外设驱动。
因此,AD23N SDK和以往的玩具系列芯片相比,ld文件中overlay的绝大部分的编码、解码、音效所需要的代码段都已去掉。即算法所需要的ram都通过malloc申请。
SDK为了方便排查相关的内存泄露问题,在每个申请内存的地方都添加了申请内存的计数值(仅用于排查内存申请和释放是否成对调用),例如:
![]()
解码内存申请计数
如果一个文件中需要有多个cnt,可以按以下方式添加
![]()
文件系统内存申请计数
5.4. SDK已有的MMU_debug接口
SDK提供了一个打印函数,通过轮询的方式,讲所有内存申请的计数值打印出来,以此排查内存申请和释放是否成对调用。
如下图添加了一个cnt打印函数(用于打印调用malloc和free的cnt值)到d_malloc_cnt段,只要调用all_malloc_cnt_dump函数就能将段内所有的打印函数轮询一遍。
![]()
文件系统内存申请计数
![]()
malloc_cnt轮询打印函数
5.5. MMU使用的注意事项
1、MMU申请到的内存不建议用于硬件访问,否则可能会产生一些边界问题。
2、free之后的指针还是会保留之前申请到的值,建议free之后将指针清空。否则再次访问可能会出现异常