發布地址: 山東
? ? 本代碼適用于無操作系統的STM32單片機開發,功能強大。
? ? 可申請到地址空間連續的不同大小的內存空間,且用戶接口簡單,使用方便。
? ? 直接復制粘貼如下代碼即可:
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:
#include?"memory.h"?#define?DMEM_BLOCK_SIZE ? ? ? ? 256 ? ? ?//內存塊大小為128字節#define?DMEM_BLOCK_NUM ? ? ? ? ?20 ? ? ??//內存塊個數為40個#define?DMEM_TOTAL_SIZE ? ? ? ? (DMEM_BLOCK_SIZE*DMEM_BLOCK_NUM) ? ?//內存總大小?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;?static?uint8_t?DMEMORY[DMEM_TOTAL_SIZE];static?DMEM_STATE DMEMS = {0};
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;}?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;}
?原文地址
http://blog.csdn.net/u011833609/article/details/46834203
關注微信公眾號
免費查看免費推送