본문 바로가기
임베디드 개발/펌웨어

FatFs, f_getfree(), f_readdir() 드라이브 여유 공간/사용 공간 확인

by eteo 2023. 3. 31.

 

 

The f_getfree function gets number of the free clusters on the volume.

FRESULT f_getfree (
  const TCHAR* path,  /* [IN] Logical drive number */
  DWORD* nclst,       /* [OUT] Number of free clusters */
  FATFS** fatfs       /* [OUT] Corresponding filesystem object */
);

 

Parameters 

  • path : Pointer to the null-terminated string that specifies the logical drive. A null-string means the default drive.
  • nclst : Pointer to the DWORD variable to store number of free clusters.
  • fatfs : Pointer to pointer that to store a pointer to the corresponding filesystem object.

 

 

사용예시

FATFS *pFatFs;
unsigned long ui32TotalSize;

if(f_getfree("/", &ui32TotalSize, &pFatFs) == FR_OK)
{
	// 섹터사이즈가 512byte라고 가정
    printf(", %10uK bytes free\n", ui32TotalSize * pFatFs->sects_clust / 2);
}

 

 

FATFS 구조체를 보면 free_clust라는 멤버 변수가 있는데 f_getfree() 함수를 호출하지 않으면 여기엔 유효하지 않은 값이 들어있다. 포맷이 FAT이면 0xFFFF, FAT32면 0xFFFFFFFF인 상태고, f_getfree()함수를 호출해줘야 유효한 값으로 갱신이 된다.

FAT32인 경우 시간이 좀 걸린다. 그리고 함수에 out 파라미터가 있는데 해당 드라이브 번호로 마운트된 파일시스템 변수가 업데이트 되어있으니 직접 접근해 확인해봐도 된다.

free_clust를 알고, sectors per cluster(csize)를 알고, 섹터사이즈를 알면 나머진 계산하면 된다.

 

 

 

혹은 f_readdir() 함수를 사용해 디렉터리내 파일을 순회하며 사용용량을 확인할 수 있다.

f_readdir() 함수는 디렉터리 내의 파일 및 서브 디렉터리 목록을 순회하며 읽어오는 함수로 파일을 읽은경우 fno.fsize 멤버로 byte 단위의 사이즈를 알 수 있고, 하위 디렉터리를 읽은 경우(fno.fattrib & AM_DIR) 사이즈는 0이다. 그리고 순회하다 디렉터리의 끝에 도달하면 FILINFO변수의 fname 멤버는 null문자가 저장이 된다.

FRESULT res;
FILINFO fno;
DWORD dir_size = 0;
DIR dir;

res = f_opendir(&dir, "/");

while(1)
{
    res = f_readdir(&dir, &fno);

    if(res != FR_OK || fno.fname[0] == 0) break;

    dir_size += fno.fsize;
}

printf("Directory Size : %lu bytes", dir_size);

http://elm-chan.org/fsw/ff/doc/readdir.html

 

 

 

 

 

 

 

FATFS 구조체 정의

typedef struct {
    BYTE    fs_type;      /* FAT type (0, FS_FAT12, FS_FAT16, FS_FAT32 or FS_EXFAT) */
    BYTE    pdrv;         /* Hosting physical drive of this volume */
    BYTE    n_fats;       /* Number of FAT copies (1,2) */
    BYTE    wflag;        /* win[] flag (b0:win[] is dirty) */
    BYTE    fsi_flag;     /* FSINFO flags (b7:Disabled, b0:Dirty) */
    WORD    id;           /* Volume mount ID */
    WORD    n_rootdir;    /* Number of root directory entries (FAT12/16) */
    WORD    csize;        /* Sectors per cluster */
#if FF_MAX_SS != FF_MIN_SS
    WORD    ssize;        /* Sector size (512,1024,2048 or 4096) */
#endif
#if FF_FS_EXFAT
    BYTE*   dirbuf;       /* Directory entry block scratchpad buffer */
#endif
#if FF_FS_REENTRANT
    FF_SYNC_t sobj;       /* Identifier of sync object */
#endif
#if !FF_FS_READONLY
    DWORD   last_clust;   /* FSINFO: Last allocated cluster (0xFFFFFFFF if invalid) */
    DWORD   free_clust;   /* FSINFO: Number of free clusters (0xFFFFFFFF if invalid) */
#endif
#if FF_FS_RPATH
    DWORD   cdir;         /* Cluster number of current directory (0:root) */
#if FF_FS_EXFAT
    DWORD   cdc_scl;      /* Containing directory start cluster (invalid when cdir is 0) */
    DWORD   cdc_size;     /* b31-b8:Size of containing directory, b7-b0: Chain status */
    DWORD   cdc_ofs;      /* Offset in the containing directory (invalid when cdir is 0) */
#endif
#endif
    DWORD   n_fatent;     /* Number of FAT entries (Number of clusters + 2) */
    DWORD   fsize;        /* Sectors per FAT */
    LBA_t   volbase;      /* Volume base LBA */
    LBA_t   fatbase;      /* FAT base LBA */
    LBA_t   dirbase;      /* Root directory base (LBA|Cluster) */
    LBA_t   database;     /* Data base LBA */
    LBA_t   winsect;      /* Sector LBA appearing in the win[] */
    BYTE    win[FF_MAX_SS]; /* Disk access window for directory, FAT (and file data at tiny cfg) */
} FATFS;

 

 

 

Reference : http://elm-chan.org/fsw/ff/doc/sfatfs.html