【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,返回偏移地址 */
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 命令大全完整版(14)

5. 文件管理命令 chgrp(change group) 功能说明&#xff1a;变更文件或目录的所属群组。语  法&#xff1a;chgrp [-cfhRv][–help][–version][所属群组][文件或目录…] 或 chgrp [-cfhRv][–help][–version][–reference<参考文件或目录>][文件或目录…]补充说明&…

[数据结构]顺序表详解

目录 一.线性表 二.顺序表 2.1概念及结构 1. 静态顺序表&#xff1a;使用定长数组存储元素。 2. 动态顺序表&#xff1a;使用动态开辟的数组存储。 2.1按需申请 2.2 接口实现&#xff1a;增删查改 SeqList.h: SeqList.c: test.c 一.线性表 线性表 &#xff08; line…

綫性與非綫性泛函分析與應用_2.賦范向量空間-母本

第2章 賦范向量空間 1.向量空間;哈默爾基;向量空間的維數 - 定義與性質 - 向量空間的定義:設\mathbb{K}為數域,集合X是\mathbb{K}上的向量空間,若在X上定義了加法(x,y)\in X\times X\to x + y\in X和數乘(\alpha,x)\in\mathbb{K}\times X\to\alpha x\in X兩種運算,且滿足…

2025年- G17-Lc91-409.最长回文-java版

1.题目描述 2.思路 思路1: 判断一个字符串中的字母个数是否是偶数个。 遍历字符串&#xff0c;检查每个字符是否是字母&#xff08;可以通过 Character.isLetter() 来判断&#xff09;。 累加字母的个数。 最后判断字母的个数是否是偶数。 思路2: 这段 Java 代码的作用是 统…

SpringBoot+Mybatis-Plus实现动态数据源

目录 一、前言二、代码实现1&#xff09;工程结构2&#xff09;相关依赖3&#xff09;数据源拦截切面4&#xff09;动态数据源切换5&#xff09;核心配置类6&#xff09;使用 三、原理分析1&#xff09;mapper接口注入流程2&#xff09;动态数据源切换执行流程 四、声明式事务导…

玩转 Java 与 Python 交互,JEP 库来助力

文章目录 玩转 Java 与 Python 交互&#xff0c;JEP 库来助力一、背景介绍二、JEP 库是什么&#xff1f;三、如何安装 JEP 库&#xff1f;四、JEP 库的简单使用方法五、JEP 库的实际应用场景场景 1&#xff1a;数据处理场景 2&#xff1a;机器学习场景 3&#xff1a;科学计算场…

Qt常用控件之日历QCalendarWidget

日历QCalendarWidget QCalendarWidget 是一个日历控件。 QCalendarWidget属性 属性说明selectDate当前选中日期。minimumDate最小日期。maximumDate最大日期。firstDayOfWeek设置每周的第一天是周几&#xff08;影响日历的第一列是周几&#xff09;。gridVisible是否显示日历…

三数之和:经典问题的多种优化策略

三数之和&#xff1a;经典问题的多种优化策略 大家好&#xff0c;我是Echo_Wish。今天我们来聊一个经典的算法问题——三数之和&#xff08;3Sum&#xff09;。它是许多面试和算法竞赛中常见的问题之一&#xff0c;也常常考察我们对算法优化的理解和技巧。我们不仅要解决问题&…

Go 语言中的协程

概念 Go语言中的协程&#xff08;Goroutine&#xff09;是一种由Go运行时管理的轻量级线程。它是Go语言并发模型的核心&#xff0c;旨在通过简单、易用的方式支持高并发的程序设计。 创建协程 协程的创建非常简单&#xff0c;只需要使用go关键字&#xff0c;后面跟着一个函数…

JAVA最新版本详细安装教程(附安装包)

目录 文章自述 一、JAVA下载 二、JAVA安装 1.首先在D盘创建【java/jdk-23】文件夹 2.把下载的压缩包移动到【jdk-23】文件夹内&#xff0c;右键点击【解压到当前文件夹】 3.如图解压会有【jdk-23.0.1】文件 4.右键桌面此电脑&#xff0c;点击【属性】 5.下滑滚动条&…

基于javaweb的SpringBoot个人博客系统设计和实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…

三、linux字符驱动详解

在上一节完成NFS开发环境的搭建后&#xff0c;本节将探讨Linux字符设备驱动的开发。字符设备驱动作为Linux内核的重要组成部分&#xff0c;主要负责管理与字符设备&#xff08;如串口、键盘等&#xff09;的交互&#xff0c;并为用户空间程序提供统一的读写操作接口。 驱动代码…

Python爬虫处理网页中的动态内容

文章目录 前言一、Python环境搭建1.Python安装2.选择Python开发环境 二、Python爬虫处理网页中的动态内容1. 使用 Selenium 库2. 使用 Pyppeteer 库3. 分析 API 请求 前言 在网页中&#xff0c;动态内容通常是指那些通过 JavaScript 在页面加载后动态生成或更新的内容&#xf…

重学SpringBoot3-Spring Retry实践

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞??收藏评论 重学SpringBoot3-Spring Retry实践 1. 简介2. 环境准备3. 使用方式 3.1 注解方式 基础使用自定义重试策略失败恢复机制重试和失败恢复效果注意事项 3.2 编程式使用3.3 监听重试过程 监…

vue3中解决组件间 css 层级问题最佳实践(Teleport的使用)

定义&#xff1a; <Teleport> 是 Vue 3 中引入的一个内置组件&#xff0c;用于将组件的内容渲染到 DOM 中的指定位置&#xff0c;而不受组件层级结构的限制。这在处理模态框、通知、下拉菜单等需要脱离当前组件层级的情况下非常有用。 通俗来说&#xff0c;Teleport的功…

密度提升30%!Intel 18A工艺正式开放代工

快科技2月23日消息&#xff0c;Intel官方网站悄然更新了对于18A(1.8nm级)工艺节点的描述&#xff0c;称已经做好了迎接客户项目的准备&#xff0c;将在今年上半年开始流片&#xff0c;有需求的客户可以随时联系。 Intel宣称&#xff0c;这是在北美地区率先量产的2nm以下工艺节…

docker中常用的命令

一、服务命令 systemctl start docker.service 启动docker服务 systemctl stop docker.service 关闭docker服务 systemctl enable docker.service 设置docker服务开机启动 systemctl disable docker.service .禁止docker服务开机自启动 二、镜像命令 d…

架构师论文《智慧医疗系统中的数据集成与共享》

智慧医疗系统中的数据集成与共享 摘要 随着医疗信息化的发展&#xff0c;如何实现跨系统、跨机构的数据集成与共享成为智慧医疗建设的核心问题。2019年&#xff0c;我所在的医疗科技公司承接了某省卫生健康委员会主导的“区域医疗信息化平台”项目。该平台旨在整合区域内三甲医…

请求go构建缓存,go clean -cache

go clean -cache go 构建时会产生很多缓存&#xff0c; 一般是目录&#xff1a;/Users/xxx/Library/Caches/go-build 此目录README&#xff1a; This directory holds cached build artifacts from the Go build system. Run "go clean -cache" if the directory …

mybatis从接口直接跳到xml的插件

在使用 MyBatis(包括 MyBatis-Plus)时,如果你希望从接口方法直接跳转到对应的 XML 映射文件中的 SQL 语句定义,可以借助一些开发工具或插件来实现这一功能。以下是几种常见的方法和插件推荐: 方法一:使用 IDE 内置功能 IntelliJ IDEA IntelliJ IDEA 提供了对 MyBatis …