📄 _fs_flashio.c
字号:
/*----------------------------------------------------------------------------
* R T L - F l a s h F i l e S y s t e m
*----------------------------------------------------------------------------
* Name: _FS_FLASHIO.C
* Purpose: Common low level Flash File Routines
* Rev.: V3.22
*----------------------------------------------------------------------------
* This code is part of the RealView Run-Time Library.
* Copyright (c) 2004-2008 KEIL - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/
#include "File_Config.h"
/*----------------------------------------------------------------------------
* Search for free/unused File Identification Number.
* Parameter: maxID: max ID found in Allocation Table
* Return Value: fileID
*---------------------------------------------------------------------------*/
U16 fs_get_freeID (U32 maxID, IOB *fcb) {
FALLOC fa;
U32 bl,fid,adr;
maxID |= 0x8000;
for (fid = 0x8001; fid < maxID; ) {
for (bl = 0; bl < fcb->NumSect; bl++) {
adr = fs_adr_sig (bl, fcb) - 8;
for (;;) {
adr = fs_rd_alloc (adr, &fa);
/* If this fileID is used, go and check next one */
if (fa.fileID == fid) goto nextfid;
if (fa.end == fcb->InitVal) break;
}
}
return (fid & 0x7FFF);
nextfid:
fid++;
}
return ((maxID + 1) & 0x7FFF);
} /* end of fs_get_freeID */
/*----------------------------------------------------------------------------
* Get remaining free space in Flash Block.
* Parameter: block: block index
* Return Value: free space in bytes
*---------------------------------------------------------------------------*/
U32 fs_get_freeMem (U32 block, IOB *fcb) {
FALLOC fa;
U32 size,adr,prev;
adr = fs_adr_sig (block, fcb) - 8;
for (prev = 0; ; prev = fa.end) {
adr = fs_rd_alloc (adr, &fa);
if (fa.end == fcb->InitVal) break;
}
size = (adr & ~1) + 8 - ((DEVCONF *)fcb->DevCfg)[block].bStart - prev;
if (size < 256) {
/* This block is considered to be full. */
return (0);
}
return (size);
} /* end of fs_get_freeMem */
/*----------------------------------------------------------------------------
* Check if there exist a file opened for writing in this Flash Block
* Parameter: block: block index
* fcb : file control block
* Return Value: __TRUE - block is busy
* __FALSE - block is free
*---------------------------------------------------------------------------*/
BOOL fs_check_fwopen (U32 block, IOB *fcb) {
U32 i;
for (i = 0; i < _NFILE; i++) {
if (&_iob[i] == fcb) {
continue;
}
if ((_iob[i].flags & _IOWRT) && (_iob[i]._fblock == block)) {
/* Another File is already opened for writing in this Flash Block */
return (__TRUE);
}
}
return (__FALSE);
} /* end of fs_check_fwopen */
/*----------------------------------------------------------------------------
* Set the 'fcb' top and bottom addresses of free memory in a Flash Block
* Parameter: fcb: file control block
*---------------------------------------------------------------------------*/
void fs_mark_freeMem (IOB *fcb) {
FALLOC fa;
U32 adr,prev;
adr = fs_adr_sig (fcb->_fblock, fcb) - 8;
for (prev = 0; ; prev = fa.end) {
adr = fs_rd_alloc (adr, &fa);
if (fa.end == fcb->InitVal) break;
}
/* All file blocks are 4-byte aligned. */
fcb->_fbot = (prev + 3) & ~3;
fcb->_ftop = (adr & ~1) + 8 - ((DEVCONF *)fcb->DevCfg)[fcb->_fblock].bStart;
} /* end of fs_mark_freeMem */
/*----------------------------------------------------------------------------
* Set the 'fcb' bottom, top address and Flash Block index of opened file
* Parameter: fcb: file control block with valid parameters
* 'fcb->fileID' - file identification number
* 'fcb->_fblock' - start scanning Flash Block
* 'fcb->_fidx' - file block sequence index
* Return Value: __TRUE - parameters set OK
* __FALSE - error, empty/invalid file found or End Of File
*---------------------------------------------------------------------------*/
BOOL fs_mark_fileMem (IOB *fcb) {
FALLOC fa;
U32 i,adr,bl,prev;
bl = fcb->_fblock;
for (i = 0; i < fcb->NumSect; i++) {
/* Search for file blocks identified with identification 'fileID' */
adr = fs_adr_sig (bl, fcb);
adr = fs_rd_sig (adr, &fa.end);
if (fa.end != fcb->InitVal) {
for (prev = 0; ; prev = fa.end) {
adr = fs_rd_alloc (adr, &fa);
if (fa.fileID == fcb->fileID && fa.index == fcb->_fidx) {
/* Set Current File Block parameters */
fcb->_fblock = bl;
fcb->_fbot = (prev + 3) & ~3;
fcb->_ftop = fa.end;
fcb->_fidx++;
return (__TRUE);
}
if (fa.end == fcb->InitVal) break;
}
}
if (++bl == fcb->NumSect) {
bl = 0;
}
}
return (__FALSE);
} /* end of fs_mark_fileMem */
/*----------------------------------------------------------------------------
* Low level File Find.
* Parameter: fname: name of the file to search for
* fcb : file control block
* Return Value: 0 - file found, fcb-updated accordingly
* maxID - max fileID found in File Allocation Table when
* the file was not found
*---------------------------------------------------------------------------*/
U32 fs_Find_File (const S8 *fname, IOB *fcb) {
FALLOC fa;
U8 buf[32];
U32 bl,adr,prev,name;
U32 fid = 0x8000;
for (bl = 0; bl < fcb->NumSect; bl++) {
/* Search all allocated File Blocks for a given 'fname */
adr = fs_adr_sig (bl, fcb);
adr = fs_rd_sig (adr, &fa.end);
if (fa.end != fcb->InitVal) {
for (prev = 0; ; prev = fa.end) {
adr = fs_rd_alloc (adr, &fa);
if (fa.fileID > 0x8000 && fa.fileID < 0xFFFF) {
/* Filename is 4-byte aligned. */
name = ((DEVCONF *)fcb->DevCfg)[bl].bStart + prev;
name = (name + 3) & ~3;
if (adr & 0x01) {
/* Copy name for SPI Flash Drive. */
fs_spi_ReadData (name, sizeof (buf), (U8 *)&buf);
}
else {
fs_ReadData (name, sizeof (buf), (U8 *)&buf);
}
buf[31] = 0;
if (fn_cmp (fname, (S8 *)&buf) == __TRUE) {
/* File with 'fname' has been found */
fcb->fileID = fa.fileID & 0x7FFF;
fcb->_fblock = bl;
return (0);
}
/* Search for the max fileID in use */
if (fa.fileID > fid) {
fid = fa.fileID;
}
}
if (fa.end == fcb->InitVal) break;
}
}
}
/* 'fid' is a nonzero value here */
return (fid);
}
/*----------------------------------------------------------------------------
* Check if Block Full, write File Allocation Info when it is full
* Parameter: fcb: file control block
* Return Value: __FALSE - enough free space
* __TRUE - full, FAT written
*---------------------------------------------------------------------------*/
BOOL fs_BlockFull (IOB *fcb) {
FALLOC alloc;
if ((fcb->_ftop - sizeof (FALLOC)) > fcb->_fbot) {
/* Enough space in current Flash Block */
return (__FALSE);
}
/* No more free space, write File Allocation Information */
alloc.end = fcb->_fbot;
alloc.fileID = fcb->fileID;
alloc.index = fcb->_fidx++;
fs_WriteBlock (((DEVCONF *)fcb->DevCfg)[fcb->_fblock].bStart + fcb->_ftop,
&alloc, sizeof (FALLOC), fcb);
/* Mark this Flash Block as full */
alloc.end = fcb->InitVal ^ BlockFULL;
fs_WriteBlock (((DEVCONF *)fcb->DevCfg)[fcb->_fblock].bEnd, &alloc, 4, fcb);
return (__TRUE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -