現在非常多的的MCU性能都還不錯,同時用戶也會去擴展一些外部RAM,這樣如果高效便捷的管理這些內存是一個重要話題。
今天給大家分享一份源碼:基于無操作系統的STM32單片機開發,功能強大,可申請到地址空間連續的不同大小的內存空間,且用戶接口簡單,使用方便。
源碼說明
源碼包含memory.h 和 memory.c 兩個文件(嵌入式C/C++代碼的“標配”),其源碼中包含重要的注釋。 頭文件memory.h :包含結構體等定義,函數API申明等; 源文件memory.c :是實現內存管理相關API函數的原型。
頭文件memory.h
頭文件是相關的定義和申請:
#ifndef __MEMORY_H__
#define __MEMORY_H__
#include "stdio.h"
#include "string.h"
#include "includes.h"
//用戶使用
typedef struct
{
void *addr; //申請到的內存的起始地址
uint32_t size; //申請到的內存的大小,按照塊大小分配,大于等于申請大小
uint16_t tb; //申請表序號,申請內存時分配,釋放內存時使用,用戶不使用
}DMEM;
//若返回空,則申請失敗
DMEM *DynMemGet(uint32_t size);
void DynMemPut(DMEM *pDmem);
#endif //__MEMORY_H__
這里的代碼比較簡單,也是常規的寫法,重點是要理解結構體成員的含義。
源文件memory.c
源文件主要就是實現內存管理的函數,源碼比較多,這里才分為三部分。 1、相關的定義
#include "memory.h" #define DMEM_BLOCK_SIZE 256 //內存塊大小為128字節 #define DMEM_BLOCK_NUM 20 //內存塊個數為40個 #defineDMEM_TOTAL_SIZE(DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM) //內存總大小 static uint8_t DMEMORY[DMEM_TOTAL_SIZE]; static DMEM_STATE DMEMS = {0}; typedef enum { DMEM_FREE = 0, DMEM_USED = 1, }DMEM_USED_ITEM; typedef struct { DMEM_USED_ITEM used; //使用狀態 uint16_t blk_s; //起始塊序號 uint16_t blk_num; //塊個數 }DMEM_APPLY; typedef struct { DMEM_USED_ITEM tb_blk[DMEM_BLOCK_NUM]; DMEM tb_user[DMEM_BLOCK_NUM]; //用戶申請內存信息 DMEM_APPLY tb_apply[DMEM_BLOCK_NUM]; //系統分配內存信息 uint16_t apply_num; //內存申請表占用數目 uint16_t blk_num; //內存塊占用數目 }DMEM_STATE;
2、內存分配函數DynMemGet
DMEM *DynMemGet(uint32_t size)
{
uint16_t loop = 0;
uint16_t find = 0;
uint16_t blk_num_want = 0;
DMEM * user = NULL;
DMEM_APPLY *apply = NULL;
//申請內存大小不能為0
if(size == 0) { return NULL; }
//申請內存不可超過總內存大小
if(size > DMEM_TOTAL_SIZE) { return NULL; }
//申請內存不可超過剩余內存大小
if(size > (DMEM_BLOCK_NUM - DMEMS.blk_num) * DMEM_BLOCK_SIZE) { return NULL; }
//申請表必須有空余
if(DMEMS.apply_num >= DMEM_BLOCK_NUM) { return NULL; }
//計算所需連續塊的個數
blk_num_want = (size + DMEM_BLOCK_SIZE - 1) / DMEM_BLOCK_SIZE;
//尋找申請表
for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
{
if(DMEMS.tb_apply[loop].used == DMEM_FREE)
{
apply = &DMEMS.tb_apply[loop]; //申請表已找到
user = &DMEMS.tb_user[loop]; //用戶表對應找到
user->tb = loop; //申請表編號記錄
user->size = blk_num_want * DMEM_BLOCK_SIZE; //分配大小計算
break;
}
}
//沒有找到可用申請表,理論上是不會出現此現象的,申請表剩余已在上面校驗
if(loop == DMEM_BLOCK_NUM) { return NULL; }
//尋找連續內存塊
for(loop = 0; loop < DMEM_BLOCK_NUM; loop++)
{
if(DMEMS.tb_blk[loop] == DMEM_FREE)
{//找到第一個空閑內存塊
for(find = 1; (find < blk_num_want) && (loop + find < DMEM_BLOCK_NUM); find ++)
{//找到下一個空閑內存塊
if(DMEMS.tb_blk[loop + find] != DMEM_FREE)
{//發現已使用內存塊
break;
}
}
if(find >= blk_num_want)
{//尋找到的空閑內存塊數目已經夠用
user->addr = DMEMORY + loop * DMEM_BLOCK_SIZE; //計算申請到的內存的地址
apply->blk_s = loop; //記錄申請到的內存塊首序號
apply->blk_num = blk_num_want; //記錄申請到的內存塊數目
for(find = 0 ; find < apply->blk_num; find++)
{
DMEMS.tb_blk[loop + find] = DMEM_USED;
}
apply->used = DMEM_USED; //標記申請表已使用
DMEMS.apply_num += 1;
DMEMS.blk_num += blk_num_want;
return user;
}
else
{//尋找到的空閑內存塊不夠用,從下一個開始找
loop += find;
}
}
}
//搜索整個內存塊,未找到大小適合的空間
return NULL;
}
3、內存釋放函數DynMemPut
void DynMemPut(DMEM *user)
{
uint16_t loop = 0;
//若參數為空,直接返回
if(NULL == user) { return; }
//釋放內存空間
for(loop = DMEMS.tb_apply[user->tb].blk_s; loop < DMEMS.tb_apply[user->tb].blk_s + DMEMS.tb_apply[user->tb].blk_num; loop++)
{
DMEMS.tb_blk[loop] = DMEM_FREE;
DMEMS.blk_num -= 1;
}
//釋放申請表
DMEMS.tb_apply[user->tb].used = DMEM_FREE;
DMEMS.apply_num -= 1;
}
代碼中包含注釋,注釋描述的比較清楚,也比較容易理解。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
單片機
+關注
關注
6076文章
45495瀏覽量
670442 -
內存
+關注
關注
9文章
3210瀏覽量
76377 -
STM32
+關注
關注
2309文章
11162瀏覽量
373475
原文標題:基于無操作系統的STM32內存管理模塊,附源碼
文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
熱點推薦
單片機編程和操作系統綜述
本文分為兩部分——“單片機編程篇”和“操作系統篇”。單片機編程篇主要介紹單片機的各種編程結構,及其實現方法。是在假設已經可以驅動單片機和各個
發表于 05-08 11:12
?40次下載
華大單片機移植RTThread操作系統
華大單片機移植RTThread-國產操作系統文章目錄華大單片機移植RTThread-國產操作系統1.華大單片機型號選擇2.RTThread
發表于 11-17 17:21
?53次下載
單片機操作系統有哪些
單片機操作系統(RTOS)是一種專門設計用于單片機的操作系統,它可以提供任務調度、內存管理、設備驅動等功能,幫助程序員更高效地開發嵌入式
基于無操作系統的STM32單片機開發附源碼
評論