日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32F7xx —— 内存管理

發布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32F7xx —— 内存管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? ? ? ? ? ? ? ? ? ? ? STM32F7xx —— 內存管理

?

?

目的:高效、快速的分配,并在適當的時候回收內存資源。最終就是實現malloc和free函數。(實現方法參考原子哥)

#define CONFIG_SRAM_OUT_ENABLE 0typedef enum {SRAM_TYPE_IN, // 內部內存池 #if(CONFIG_SRAM_OUT_ENABLE == 1)SRAM_YPE_OUT, // 外部內存池(SDRAM) #endifSRAM_TYPE_DTCM, // DTCM內存池(此部分SRAM僅僅CPU可以訪問!!!)SRAM_TYPE_MAX, // 最多支持的SRAM塊數. } sram_type_t;// 內部SRAM #define SRAM_IN_BLOCK_SIZE 64 // 內存塊大小為64字節 #define SRAM_IN_MAX_SIZE (160 * 1024) // 最大管理內存160K #define SRAM_IN_ALLOC_TABLE_SIZE (SRAM_IN_MAX_SIZE / SRAM_IN_BLOCK_SIZE)#if(CONFIG_SRAM_OUT_ENABLE == 1) // 外部SDRAM里面 #define SRAM_OUT_BLOCK_SIZE 64 // 內存塊大小為64字節 #define SRAM_OUT_MAX_SIZE (100 *1024) // 最大管理內存100K #define SRAM_OUT_ALLOC_TABLE_SIZE (SRAM_OUT_MAX_SIZE / SRAM_OUT_BLOCK_SIZE) #endif// CCM,用于管理DTCM(特別注意,這部分SRAM,僅CPU可以訪問!!) #define SRAM_DTCM_BLOCK_SIZE 64 //內存塊大小為64字節 #define SRAM_DTCM_MAX_SIZE (100 *1024) //最大管理內存60K #define SRAM_DTCM_ALLOC_TABLE_SIZE (SRAM_DTCM_MAX_SIZE/SRAM_DTCM_BLOCK_SIZE) //內存池(32字節對齊) __align(32) uint8_t sram_in_base[SRAM_IN_MAX_SIZE]; // 內部SRAM內存池 uint32_t sram_in_map_base[SRAM_IN_ALLOC_TABLE_SIZE];#if(CONFIG_SRAM_OUT_ENABLE == 1) __align(32) uint8_t sram_out_base[SRAM_OUT_MAX_SIZE] __attribute__((at(0xC01F4000))); // 外部SDRAM內存池 uint32_t sram_out_map_base[SRAM_OUT_ALLOC_TABLE_SIZE] __attribute__((at(0xC01F4000 + SRAM_OUT_MAX_SIZE))); // 外部SRAM內存池MAP #endif__align(32) uint8_t sram_dtcm_base[SRAM_DTCM_MAX_SIZE] __attribute__((at(0x20000000))); // 內部DTCM內存池 uint32_t sram_dtcm_map_base[SRAM_DTCM_ALLOC_TABLE_SIZE] __attribute__((at(0x20000000 + SRAM_DTCM_MAX_SIZE))); //內部DTCM內存池MAPstatic const uint32_t memtblsize[SRAM_TYPE_MAX] = {SRAM_IN_ALLOC_TABLE_SIZE, #if(CONFIG_SRAM_OUT_ENABLE == 1)SRAM_OUT_ALLOC_TABLE_SIZE, #endifSRAM_DTCM_ALLOC_TABLE_SIZE}; //內存表大小static const uint32_t memblksize[SRAM_TYPE_MAX] = {SRAM_IN_BLOCK_SIZE, #if(CONFIG_SRAM_OUT_ENABLE == 1)SRAM_OUT_BLOCK_SIZE, #endifSRAM_DTCM_BLOCK_SIZE}; //內存分塊大小static const uint32_t memsize[SRAM_TYPE_MAX] = {SRAM_IN_MAX_SIZE, #if(CONFIG_SRAM_OUT_ENABLE == 1)SRAM_OUT_MAX_SIZE, #endifSRAM_DTCM_MAX_SIZE}; //內存總大小void mymem_init(uint8_t type); uint16_t mymem_perused(uint8_t type);typedef struct {void (* init)(uint8_t );uint16_t (* perused)(uint8_t); // 內存使用率uint8_t *membase[SRAM_TYPE_MAX]; // 內存池 管理SRAMBANK個區域的內存uint32_t *memmap[SRAM_TYPE_MAX]; // 內存管理狀態表uint8_t memrdy[SRAM_TYPE_MAX]; // 內存管理是否就緒 } sram_dev_t;//內存管理控制器 static sram_dev_t sram_dev = {mymem_init, // 內存初始化mymem_perused, // 內存使用率sram_in_base,#if(CONFIG_SRAM_OUT_ENABLE == 1)sram_out_base, #endifsram_dtcm_base, // 內存池sram_in_map_base, #if(CONFIG_SRAM_OUT_ENABLE == 1)sram_out_map_base, #endifsram_dtcm_map_base,0, #if(CONFIG_SRAM_OUT_ENABLE == 1)0, #endif0, };// 內存管理初始化 static void mymem_init(uint8_t memx) {memset(sram_dev.memmap[memx], 0, memtblsize[memx] * 4); // 內存狀態表數據清零sram_dev.memrdy[memx] = 1; // 內存管理初始化OK }// 獲取內存使用率 // type:所屬內存塊 // 返回值:使用率(擴大了10倍,0~1000,代表0.0%~100.0%) static uint16_t mymem_perused(uint8_t type) {uint32_t used = 0;uint32_t i;for(i = 0; i < memtblsize[type]; ++i){if(sram_dev.memmap[type][i]){used++;}}return (used * 1000) / (memtblsize[type]); }// 內存分配(內部調用) // type:所屬內存塊 // size:要分配的內存大小(字節) // 返回值:0XFFFFFFFF,代表錯誤;其他,內存偏移地址 static uint32_t mymem_malloc(uint8_t type, uint32_t size) {signed long offset = 0;uint32_t nmemb; // 需要的內存塊數uint32_t cmemb = 0; // 連續空內存塊數uint32_t i;if(!sram_dev.memrdy[type]){sram_dev.init(type); // 未初始化,先執行初始化}if(size == 0){return 0xFFFFFFFF; // 不需要分配}nmemb = size / memblksize[type]; // 獲取需要分配的連續內存塊數if(size % memblksize[type]){nmemb++;}for(offset = memtblsize[type] - 1; offset >= 0; offset--) // 搜索整個內存控制區{if(!sram_dev.memmap[type][offset]){cmemb++; // 連續空內存塊數增加}else{cmemb = 0; // 連續內存塊清零}if(cmemb == nmemb) // 找到了連續nmemb個空內存塊{for(i = 0; i < nmemb; i++) // 標注內存塊非空{sram_dev.memmap[type][offset + i] = nmemb;}return (offset * memblksize[type]); // 返回偏移地址}}return 0xFFFFFFFF; // 未找到符合分配條件的內存塊 }// 釋放內存(內部調用) // type:所屬內存塊 // offset:內存地址偏移 // 返回值:0,釋放成功;1,釋放失敗; static uint8_t mymem_free(uint8_t type, uint32_t offset) {int i;if(!sram_dev.memrdy[type])// 未初始化,先執行初始化{sram_dev.init(type);return 1;// 未初始化}if(offset < memsize[type]) // 偏移在內存池內.{int index = offset / memblksize[type]; // 偏移所在內存塊號碼int nmemb = sram_dev.memmap[type][index]; // 內存塊數量for(i = 0; i < nmemb; i++) // 內存塊清零{sram_dev.memmap[type][index + i] = 0;}return 0;}else{return 2; // 偏移超區了.} }void MemInit(uint8_t type) {memset(sram_dev.memmap[type], 0, memtblsize[type] * 4); // 內存狀態表數據清零sram_dev.memrdy[type] = 1; // 內存管理初始化OK }// 釋放內存(外部調用) // type:所屬內存塊 // ptr:內存首地址 void MemFree(uint8_t type, void *ptr) {uint32_t offset;if(ptr == NULL){return; // 地址為0.}offset = (uint32_t)ptr - (uint32_t)sram_dev.membase[type];mymem_free(type, offset); // 釋放內存 }// 分配內存 void *MemAlloc(uint8_t type, uint32_t size) {uint32_t offset;offset = mymem_malloc(type, size);if(offset == 0XFFFFFFFF){return NULL;}else{return (void*)((uint32_t)sram_dev.membase[type] + offset);} }// 重新分配內存 void *MemRealloc(uint8_t type, void *ptr, uint32_t size) {uint32_t offset;offset = mymem_malloc(type, size);if(offset == 0xFFFFFFFF){return NULL;}else{memcpy((void*)((uint32_t)sram_dev.membase[type] + offset), ptr, size); // 拷貝舊內存內容到新內存MemFree(type, ptr); // 釋放舊內存return (void*)((uint32_t)sram_dev.membase[type] + offset); // 返回新內存首地址} }

?

?

?

?

?

?

總結

以上是生活随笔為你收集整理的STM32F7xx —— 内存管理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。