21.2.2 ffsystem.c文件的修改
(1)內(nèi)存分配ff_memalloc
void* ff_memalloc( UINT msize )
{
return ( void* )mymalloc( SRAMIN, msize ) ;
}
(2)內(nèi)存釋放ff_memfree
void ff_memfree( void* mblock )
{
myfree( SRAMIN, mblock ) ;
}
21.2.3 exfuns.c與exfuns.h文件的創(chuàng)建
(1)創(chuàng)建exfuns.h文件,并輸入以下代碼。
#ifndef _EXFUNS_H
#define _EXFUNS_H
#include "sys.h"
#include "ff.h"
extern FATFS *fs[ FF_VOLUMES ] ;
extern FIL *file;
extern FIL *ftemp;
extern UINT br,bw;
extern FILINFO fileinfo;
extern DIR dir;
u8 exfuns_init( void ) ; //為exfuns申請內(nèi)存
u8 exf_getfree( u8 *drv, u32 *total, u32 *free ) ; //得到磁盤總?cè)萘亢褪S嗳萘?/p>
#endif
(2)創(chuàng)建exfuns.c文件,并輸入以下代碼。
#include "exfuns.h"
#include "malloc.h"
FATFS *fs[ FF_VOLUMES ] ; //邏輯磁盤工作區(qū)
FIL *file ; //文件1
FIL *ftemp ; //文件2
UINT br, bw ; //讀寫變量
FILINFO fileinfo ; //文件信息
DIR dir ; //目錄
u8 *fatbuf ; //SD卡數(shù)據(jù)緩存區(qū)
u8 exfuns_init()
{
u8 i;
for( i=0; i
{
//為磁盤i工作區(qū)申請內(nèi)存
fs[ i ] = ( FATFS* )mymalloc( SRAMIN, sizeof( FATFS ) ) ;
if( !fs[ i ] )
break ;
}
file = ( FIL* )mymalloc( SRAMIN, sizeof( FIL ) ) ; //為file申請內(nèi)存
ftemp = ( FIL* )mymalloc( SRAMIN, sizeof( FIL ) ) ; //為ftemp申請內(nèi)存
fatbuf = ( u8* )mymalloc( SRAMIN, 512 ) ; //為fatbuf申請內(nèi)存
//申請有一個失敗,即失敗
if( ( i==FF_VOLUMES )&&file&&ftemp&&fatbuf )
return 0 ;
else
return 1 ;
}
u8 exf_getfree( u8 *drv, u32 *total, u32 *free )
{
FATFS *fs1;
u8 res;
u32 fre_clust=0, fre_sect=0, tot_sect=0;
//得到磁盤信息及空閑簇數(shù)量
res = ( u32 )f_getfree( ( const TCHAR* )drv, ( DWORD* )&fre_clust, &fs1 ) ;
if( res==0 )
{
tot_sect =( fs1->n_fatent-2 )*fs1->csize ; //得到總扇區(qū)數(shù)
fre_sect = fre_clust*fs1->csize ; //得到空閑扇區(qū)數(shù)
//扇區(qū)大小不是512字節(jié),則轉(zhuǎn)換為512字節(jié)
#if FF_MAX_SS!=512
tot_sect*=fs1->ssize/512;
fre_sect*=fs1->ssize/512;
#endif
*total=tot_sect>>1 ; //單位為KB
*free=fre_sect>>1 ; //單位為KB
}
return res;
}
注:如果SD卡文件系統(tǒng)不能正確掛載則需要修改SD卡驅(qū)動文件中的兩個參數(shù),如下圖所示。

21.3 內(nèi)存管理
21.3.1 內(nèi)存管理簡介
內(nèi)存管理,是指軟件運行時對計算機內(nèi)存資源的分配和使用的技術。其最主要的目的是如何高效,快速的分配,并且在適當?shù)臅r候釋放和回收內(nèi)存資源。內(nèi)存管理的實現(xiàn)方法有很多種,他們其實最終都是要實現(xiàn)2個函數(shù):malloc和free;malloc函數(shù)用于內(nèi)存申請,free函數(shù)用于內(nèi)存釋放。
這一部分我們使用了一種比較簡單的辦法來實現(xiàn):分塊式內(nèi)存管理。下面我們介紹一下該方法的實現(xiàn)原理,如下圖所示。

從上圖可以看出,分塊式內(nèi)存管理由內(nèi)存池和內(nèi)存管理表兩部分組成。內(nèi)存池被等分為n塊,對應的內(nèi)存管理表,大小也為n,內(nèi)存管理表的每一個項對應內(nèi)存池的一塊內(nèi)存。內(nèi)存管理表的項值代表的意義為:當該項值為0的時候,代表對應的內(nèi)存塊未被占用,當該項值非零的時候,代表該項對應的內(nèi)存塊已經(jīng)被占用,其數(shù)值則代表被連續(xù)占用的內(nèi)存塊數(shù)。比如某項值為10,那么說明包括本項對應的內(nèi)存塊在內(nèi),總共分配了10個內(nèi)存塊給外部的某個指針。
內(nèi)存分配方向如圖所示,是從頂?shù)降椎姆峙浞较?。即首先從最末端開始找空內(nèi)存。當內(nèi)存管理剛初始化的時候,內(nèi)存表全部清零,表示沒有任何內(nèi)存塊被占用。
21.3.2 分配原理
當指針p調(diào)用malloc申請內(nèi)存的時候,先判斷p要分配的內(nèi)存塊數(shù)m,然后從第n項開始,向下查找,直到找到m塊連續(xù)的空內(nèi)存塊(即對應內(nèi)存管理表項為0),然后將這m個內(nèi)存管理表項的值都設置為m(標記被占用),最后,把最后的這個空內(nèi)存塊的地址返回指針p,完成一次分配。注意,如果當內(nèi)存不夠的時候(找到最后也沒找到連續(xù)的m塊空閑內(nèi)存),則返回NULL給p,表示分配失敗。
21.3.3 釋放原理
當p申請的內(nèi)存用完,需要釋放的時候,調(diào)用free函數(shù)實現(xiàn)。free函數(shù)先判斷p指向的內(nèi)存地址所對應的內(nèi)存塊,然后找到對應的內(nèi)存管理表項目,得到p所占用的內(nèi)存塊數(shù)目m(內(nèi)存管理表項目的值就是所分配內(nèi)存塊的數(shù)目),將這m個內(nèi)存管理表項目的值都清零,標記釋放,完成一次內(nèi)存釋放。
21.3.4 源代碼實現(xiàn)
(1)創(chuàng)建malloc.h文件,并輸入以下代碼。
/*********************************************************************************************************
內(nèi) 存 管 理 文 件
*********************************************************************************************************/
#ifndef _MALLOC_H_
#define _MALLOC_H_
#include "sys.h"
/*********************************************************************************************************
數(shù) 據(jù) 結(jié) 構(gòu) 定 義
*********************************************************************************************************/
//定義兩個內(nèi)存池
#define SRAMIN 0 //內(nèi)部內(nèi)存池
#define SRAMBANK 1 //定義支持的SRAM塊數(shù)
//mem1內(nèi)存參數(shù)設定
#define MEM1_BLOCK_SIZE 32 //內(nèi)存塊大小為32字節(jié)
#define MEM1_MAX_SIZE 40*1024 //最大管理內(nèi)存40K
#define MEM1_ALLOC_TABLE_SIZE MEM1_MAX_SIZE/MEM1_BLOCK_SIZE //內(nèi)存表大小
//內(nèi)存管理控制器
struct _m_mallco_dev
{
void ( *init )( u8 ) ; //初始化
u8 ( *perused )( u8 ) ; //內(nèi)存使用率
u8 *membase[ SRAMBANK ] ; //內(nèi)存池 管理SRAMBANK個區(qū)域的內(nèi)存
u16 *memmap[ SRAMBANK ] ; //內(nèi)存管理狀態(tài)表
u8 memrdy[ SRAMBANK ] ; //內(nèi)存管理是否就緒
};
extern struct _m_mallco_dev mallco_dev; //在mallco.c里面定義
/*********************************************************************************************************
函 數(shù) 列 表
*********************************************************************************************************/
void my_mem_init( u8 memx ) ; //內(nèi)存管理初始化函數(shù)
u8 my_mem_perused( u8 memx ) ; //獲得內(nèi)存使用率
void myfree( u8 memx, void *ptr ) ; //內(nèi)存釋放
void *mymalloc( u8 memx, u32 size ) ; //內(nèi)存分配
void *myrealloc( u8 memx, void *ptr, u32 size ) ; //重新分配內(nèi)存
#endif
-
單片機
+關注
關注
6078文章
45565瀏覽量
673182 -
嵌入式系統(tǒng)
+關注
關注
41文章
3817瀏覽量
133851 -
FATFS
+關注
關注
0文章
46瀏覽量
19597
發(fā)布評論請先 登錄
基于STM32完成FATFS文件系統(tǒng)移植與運用
FatFS文件系統(tǒng)在STM32F4上的移植和應用
STM32CubeMx入門教程(10):Fatfs文件系統(tǒng)的應用
FATFS文件系統(tǒng)移植
STM32的FATFS文件系統(tǒng)移植筆記
FatFs文件系統(tǒng)的原理是什么?如何對FATFS進行移植?
MSP430、STM32、8051單片機fatfs 文件系統(tǒng)移植 W25Q128
Fatfs(文件系統(tǒng)的移植)
【文件系統(tǒng)】FatFs文件系統(tǒng)在嵌入式芯片LPC18XX上的移植
手把手教你在flash上移植fatfs文件系統(tǒng)(含實時操作系統(tǒng))
STM32入門學習筆記之文件系統(tǒng)FatFs的移植1
STM32入門學習筆記之文件系統(tǒng)FatFs的移植2
STM32入門學習筆記之文件系統(tǒng)FatFs的移植4
文件系統(tǒng)FatFs的移植
STM32入門學習筆記之文件系統(tǒng)FatFs的移植3
評論