【STM32】内存管理

【STM32】内存管理

文章目录

  • 【STM32】内存管理
    • 1、内存管理简介
    • 疑问:为啥不用标准的 C 库自带的内存管理算法?
    • 2、分块式内存管理(掌握)
      • 分配方向
      • 分配原理
      • 释放原理
      • 分块内存管理 管理内存情况
    • 3、内存管理使用(掌握)
      • 操作步骤
      • 内存池
      • 内存管理表

1、内存管理简介

如何在LCD 上面实现SD卡文件浏览?

需要读取所有文件名到内存,然后显示到LCD。一般的方法,是定义一个数组来存储所有文件名

1,需要知道最大文件名的长度。255字节。

2,需要知道文件个数。 100?1000?10000 ?

如果没有内存管理:则要定义一个:uint8_t filenametbl[10000][255]; 的数组!(占用2550K字>节内存

内存管理,是指软件运行时对MCU内存资源的分配和使用的技术。(内存的大管家)

其最主要目的是:如何高效,快速的分配,并且在适当的时候释放和回收内存资源。(防止内存泄露、内存碎片)

内存使用三部曲:1. 内存申请(分配) 2. 内存使用 3.内存释放

内存管理的实现方法有很多种,最终都是实现2个函数:malloc和free;

malloc内存申请
free内存释放

标准的 C 库也提供了函数 malloc()和函数 free()来实现动态地申请和释放内存 。

疑问:为啥不用标准的 C 库自带的内存管理算法?

因为标准 C 库的动态内存管理方法有如下几个缺点:

  • 占用大量的代码空间 不适合用在资源紧缺的嵌入式系统中
  • 没有线程安全的相关机制
  • 运行有不确定性,每次调用这些函数时花费的时间可能都不相同
  • 内存碎片化
  • ………

2、分块式内存管理(掌握)

分块式内存管理由内存池和内存管理表两部分组成。内存池被等分为n块,对应的内存管理表,大小也为n,内存管理表的每一个项对应内存池的一块内存。

内存管理表的项值代表的意义:当该项值为0时,代表对应的内存块未被占用;当该项值非零时,代表该项对应的内存块已经被占用,其数值则代表被连续占用的内存块数。

当内存管理刚初始化的时候,内存管理表全部清零,表示没有任何内存块被占用。

分配方向

分配原理

当指针p调用malloc申请内存时,

① 先判断p要分配的内存块数(m)

② 从第n项开始,向下查找,直到找到m块连续的空内存块(即对应内存管理表项为0)

③ 将这m个内存管理表项的值都设置为m(标记被占用)

④ 把最后的这个空内存块的地址返回指针p,完成一次分配

注意:如果当内存不够时(找到最后也没有找到连续m块空闲内存),则返回NULL给p,表示分配失败。

释放原理

当指针p申请的内存用完,需要释放的时候,调用free函数实现。

free函数实现:

① 先判断p指向的内存地址所对应的内存块

② 找到对应的内存管理表项目,得到p所占用的内存块数目m

③ 将这m个内存管理表项目的值都清零,标记释放,完成一次内存释放

分块内存管理 管理内存情况

3、内存管理使用(掌握)

操作步骤

1、初始化内存

内存管理控制器 struct _m_malloc_dev
外扩SRAM 需初始化(内部SRAM不需要)
内存管理表 清零	void my_mem_init(uint8_t memx)

2、申请内存

void *mymalloc(uint8_t memx, uint32_t size)

3、操作内存

sprintf((char *)p, “Memory Malloc Test%03d”, i);

4、释放内存(用完,一定要释放)

void myfree(uint8_t memx, void *ptr)
/* 内存管理控制器 */
#define SRAMBANK 2 	/* 定义管理的内存片数*/
struct _m_mallco_dev
{
    void 		(*init)(uint8_t);			/* 函数指针,指向内存初始化函数,用于初始化内存管理 */
    uint8_t	(*perused)(uint8_t);		/* 函数指针,指向内存使用率函数,用于获取内存使用率 */
 	uint8_t 	*membase[SRAMBANK]; 	/* 内存池指针,指向内存池 */
 	uint16_t 	*memmap[SRAMBANK];  	/* 内存管理表指针,指向内存管理表 */
 	uint8_t  	memrdy[SRAMBANK]; 		/* 内存管理表就绪标志,用于表示内存管理表是否已初始化 */
};
struct _m_mallco_dev mallco_dev
{
    my_mem_init,	
    my_mem_perused, 		
    mem1base, mem2base,		
    mem1mapbase, mem2mapbase,	
    0, 0,	
};

MEMx_MAX_SIZE 		内存池中内存块大小
MEMx_ALLOC_TABLE_SIZE 	内存管理表中项数
/* 内存池 */
static __align(64) uint8_t mem1base[MEM1_MAX_SIZE];
static __align(64) uint8_t mem2base[MEM2_MAX_SIZE];
/* 内存管理表 */
static uint16_t mem1mapbase[MEM1_ALLOC_TABLE_SIZE];
static uint16_t mem2mapbase[MEM2_ALLOC_TABLE_SIZE];

内存池

uint8_t mem1base[MEM1_MAX_SIZE]
MEM1_ALLOC_TABLE_SIZE个内存块

内存管理表

uint16_t mem1mapbase[MEM1_ALLOC_TABLE_SIZE]
MEM1_ALLOC_TABLE_SIZE个项
项的大小为2字节

void my_mem_init(uint8_t memx)
{
    uint8_t mttsize = sizeof(MT_TYPE); 	/* 获取memmap数组的类型长度(uint16_t /uint32_t)*/
    my_mem_set(mallco_dev.memmap[memx], 0, memtblsize[memx] * mttsize);	/* 内存管理表数据清零 */
    mallco_dev.memrdy[memx] = 1;        	/* 内存管理初始化OK */
}
uint16_t my_mem_perused(uint8_t memx)
{
    uint32_t i, used = 0;

    for (i = 0; i < memtblsize[memx]; i++)
        if (mallco_dev.memmap[memx][i])used++;

    return (used * 1000) / (memtblsize[memx]);
}
void my_mem_set(void *s, uint8_t c, uint32_t count)
{
    uint8_t *xs = s;
    while (count--) *xs++ = c;
}

void *mymalloc(uint8_t memx, uint32_t size)
{
	uint32_t offset; 	
    	offset = my_mem_malloc(memx, size);

 	if (offset == 0xFFFFFFFF) return NULL;	/* 申请出错 */
	else return (void *)((uint32_t)mallco_dev.membase[memx] + offset);	/* 申请没问题,返回首地址 */
}
uint32_t my_mem_malloc(uint8_t memx, uint32_t size)
{
	/* 1、判断内存块memx是否已经初始化 */
	/* 2、通过size获取需要分配的连续内存块数x */
	/* 3、搜索符合 要求内存块数x 的内存块 */
	/* 4、找到符合要求内存块数区域,对其管理表写入内存块数的值x,返回偏移地址 */
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/975754.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DeepSeek 助力 Vue 开发:打造丝滑的二维码生成(QR Code)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

认知重构 | 自我分化 | 苏格拉底式提问

注&#xff1a;本文为 “认知重构 | 自我分化” 相关文章合辑。 心理学上有一个词叫&#xff1a;认知重构&#xff08;改变 “非黑即白&#xff0c;一分为二” 的思维方式&#xff09; 原创 心理师威叔 心理自救 2024 年 10 月 26 日 19:08 广东 你有没有过这样的时候&#x…

YARN的工作机制及特性总结

YARN hadoop的资源管理调度平台&#xff08;集群&#xff09;——为用户程序提供运算资源的管理和调度 用户程序&#xff1a;如用户开发的一个MR程序 YARN有两类节点&#xff08;服务进程&#xff09;&#xff1a; 1. resourcemanager 主节点master ----只需要1个来工作 2. nod…

LLM2CLIP论文学习笔记:强大的语言模型解锁更丰富的视觉表征

1. 写在前面 今天分享的一篇论文《LLM2CLIP: P OWERFUL L ANGUAGE M ODEL U NLOCKS R ICHER V ISUAL R EPRESENTATION》&#xff0c; 2024年9月微软和同济大学的一篇paper&#xff0c; 是多模态领域的一篇工作&#xff0c;主要探索了如何将大模型融合到Clip模型里面来进一步提…

Win11更新系统c盘爆满处理

1.打开磁盘管理 2.右击c盘选择属性&#xff0c;进行磁盘管理&#xff0c;选择详细信息。 3.选择以前安装的文件删除即可释放c盘空间。

Spring面试题2

1、compareable和compactor区别 定义与包位置:Comparable是一个接口&#xff0c;位于java.lang包,需要类去实现接口&#xff1b;而Compactor是一个外部比较器&#xff0c;位于java.util包 用法&#xff1a;Comparable只需要实现int compareTo(T o) 方法&#xff0c;比较当前对…

2025年02月21日Github流行趋势

项目名称&#xff1a;source-sdk-2013 项目地址url&#xff1a;https://github.com/ValveSoftware/source-sdk-2013项目语言&#xff1a;C历史star数&#xff1a;7343今日star数&#xff1a;929项目维护者&#xff1a;JoeLudwig, jorgenpt, narendraumate, sortie, alanedwarde…

Django check_password原理

check_password 是 Django 提供的一个用于密码校验的函数&#xff0c;它的工作原理是基于密码哈希算法的特性。 Django 的 make_password 函数在生成密码哈希时&#xff0c;会使用一个随机的 salt&#xff08;盐值&#xff09;。这个 salt 会与密码一起进行哈希运算&#xff0…

如何在 SpringBoot 项目创建并使用 Redis 的详细介绍

本文是博主整理项目时整理出来的&#xff0c;项目使用 SpringBoot 框架&#xff0c;使用 Redis 作为缓存组件&#xff0c;用于缓存部分热点接口数据。 文章目录 一、Redis 的前置配置1、引入依赖2、单机配置3、集群配置4、两种配置路径解读 二、创建 Redis 配置类1、简易版 Red…

快速入门——第三方组件element-ui

学习自哔哩哔哩上的“刘老师教编程”&#xff0c;具体学习的网站为&#xff1a;10.第三方组件element-ui_哔哩哔哩_bilibili&#xff0c;以下是看课后做的笔记&#xff0c;仅供参考。 第一节 组件间的传值 组件可以有内部Data提供数据&#xff0c;也可由父组件通过prop方式传…

使用 Grafana 监控 Spring Boot 应用

随着软件开发领域的不断发展&#xff0c;监控和可观测性已成为确保系统可靠性和性能的关键实践。Grafana 是一个功能强大的开源工具&#xff0c;能够为来自各种来源的监控数据提供丰富的可视化功能。在本篇博客中&#xff0c;我们将探讨如何将 Grafana 与 Spring Boot 应用程序…

《深度学习》——RNN网络简单介绍

文章目录 RNN网络简介工作原理网络结构训练方法应用领域 RNN网络简介 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一种专门用于处理序列数据的神经网络&#xff0c;在自然语言处理、语音识别、时间序列预测等领域有广泛应用。 RNN 是一种…

深入解析JVM垃圾回收机制

1 引言 本节常见面试题 如何判断对象是否死亡&#xff08;两种方法&#xff09;。简单的介绍一下强引用、软引用、弱引用、虚引用&#xff08;虚引用与软引用和弱引用的区别、使用软引用能带来的好处&#xff09;。如何判断一个常量是废弃常量如何判断一个类是无用的类垃圾收…

python网络安全怎么学 python做网络安全

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 众所周知&#xff0c;python是近几年比较火的语言之一&#xff0c;它具有简单易懂、免费开源、可移植、可扩展、丰富的第三方库函数等特点&#xff0c;Java需要大…

使用excel中的VBA合并多个excel文件

需求是这样的&#xff1a; 在Windows下&#xff0c;用excel文件让多个小组填写了统计信息&#xff0c;现在我需要把收集的多个文件汇总到一个文件中&#xff0c;前三行为标题可以忽略&#xff0c;第四行为收集信息的列名&#xff0c;处理每一行数据的时候&#xff0c;发现某一行…

【算法】2022年第十三届蓝桥杯大赛软件类省赛Java大学C组真题

个人主页&#xff1a;NiKo 算法专栏&#xff1a;算法设计与分析 目录 题目 2680:纸张尺寸 题目 2664:求和 题目 2681: 矩形拼接 题目 2665: 选数异或 题目 2682: GCD 题目 2667: 青蛙过河 题目 2683: 因数平方和 题目 2668: 最长不下降子序列 题目 2680:纸张尺寸 题目…

2025雅森北京展今天开幕,全景展现新能源汽车时代

推动汽车后市场全产业链向新向优转型升级 在2月21日举行的第36届中国国际汽车服务用品及设备展览会&#xff0c;中国国际新能源汽车技术、零部件及服务展览会&#xff08;雅森北京展CIAACE&#xff09;上&#xff0c;雅森国际总裁谢宇表示&#xff0c;当前正处在汽车行业新旧动…

PHP.INI的作用以及如何设置

php.ini是网站服务器上的一个重要配置文件&#xff0c;它包含了决定PHP运行环境特性的关键设置&#xff0c;直接关系到网站能否顺畅运行。每次 PHP 启动时&#xff0c;系统都会读取这个文件&#xff0c;加载相应的配置并将其应用到网站的脚本上。 尽管服务器通常预装了一些默认…

新版IDEA配置 Tomcat

配置tomcat 先检查自己的tomcat是否已经安装完成以及是否有其他问题&#xff0c;这里不对Tomcat方面的问题进行讲解。 新版IDEA需要在已有项目中添加Web部分的项目结构。 安装完成之后&#xff0c;打开要创建Web项目的项目(这里演示使用新建项目) 第一步&#xff0c;先给项…

整理好的java面试八大常用算法

原创不易&#xff0c;如果有转载需要的话&#xff0c;请在首行附上本文地址&#xff0c;谢谢。 文中整理了八大常见的排序算法&#xff0c;冒泡排序、选择排序、快速排序、插入排序、堆排序、希尔排序、归并排序和基数排序的简单思想&#xff0c;每种算法配有动图分析和相应的…