【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.pswp.cn/web/70504.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70504.shtml
英文地址,請注明出處:http://en.pswp.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 …