📄 fat.c
字号:
*clus = cluster;
} // end of while (!LAST_CLUSTER(cluster))
if (termination)
{
FAT_CopyEntry(buff_end-DIR_ENTRY_SIZE, TERM_ENTRY_TAG, sCh);
FAT_WriteSector(buff_start, start_sector, 1, sCh);
}
*sector= *offset = 0;
*nSpecFile = 0;
}
/********************************************************************/
/* create a empty file with specified size on hd, lfname in unicode */
/********************************************************************/
// return value: nHeadCluster <-- HD_allo_cchain(, ,) is right??
void FAT_CreateFile(int location, const char *cFname, u8 ucAttr, int nLength, int* nEmpFile, SDHC* sCh)
{
u8 p[SECBUFFSIZE*MAXSEC_PER_CLUSTER]; //LYS 040525
int entries, numberofcluster;//nPosi,
u32 uHeadCluster;
int nSector, nOffset, nDirCluster;
int nLen = strlen(cFname);
int nFileEnt, m;
char cSfname[11];
// u32 i;
int nEntOffset;
int nNextCluster;
int uAlloCluster;
short* spLFUnicodeName;
int nLossFlag;
int nDirecEntry;
const char* cTempSfname;
int nCurrDirNum, nNextDirNum;
u32 uDIR_FstClus, uDIR_FileSize;
u8* pLastEntryAddr;
Assert(nLen>0);
if(FAT_FindDirEntryOffsetFromName(cFname, &nEntOffset, sCh))
{ // file or directory exist, verify ok
Disp("The same name file already exist: file No. %d\n", nEntOffset);
*nEmpFile = -3;
return;
}
if ((ucAttr&ATTR_DIRECTORY) == ATTR_DIRECTORY) {
numberofcluster = 1;
}
else {
numberofcluster = (nLength+oFat.m_nBytesPerCluster-1)/oFat.m_nBytesPerCluster;
}
// sunny 060818
if (nLen<=SF_NAME_LENGTH)
entries = 1; // short file name directory entry
else
entries = (nLen+12)/13 + 1; // long file name directory entry
FAT_FindFreeEntry(entries, &nDirCluster, &nOffset, sCh); // find the free file entry for the current file
printf("offset: %d, cluster: %d\n", nOffset, nDirCluster);
FAT_FromClusterToLba(nDirCluster, &nSector, sCh);
FAT_ReadSector(p, nSector, oFat.m_ucBpbSecPerClus, sCh);
//Need to store the entry in the second root cluster, then need to update the FAT to fix the second root cluster
if (entries!=1 &&(oFat.m_uDirEntryPerCulster-nOffset)<entries)
{
pLastEntryAddr = (p + DIR_ENTRY_SIZE*(nOffset-1));
FAT_GetEntryCluster(pLastEntryAddr, &uDIR_FstClus, sCh);
uDIR_FileSize = LSB_GET_4BYTES(pLastEntryAddr + 28);
// Get the next cluster which store the remainder file info.
nNextCluster = uDIR_FstClus + (uDIR_FileSize+oFat.m_nBytesPerCluster-1)/oFat.m_nBytesPerCluster;
FAT_UpdateRootCluInFat(nNextCluster, sCh);
}
FAT_UpdateFileDataCluInFat(numberofcluster, &uAlloCluster, sCh);
if ((uHeadCluster=uAlloCluster)==0)
{
*nEmpFile = -4; /* no disc free space */
return;
}
if (entries==1) // short file entry
{
//SetDateTime(0x309B, 0x762D); // LYS 040426 LYS 040427
FAT_WriteFileHead(cFname, ucAttr, nLength, uHeadCluster, &nFileEnt, sCh); //it makes fill oFat.m_ucFileEntryHead content(32bytes)
FAT_CopyAblockOfMem(p+nOffset*32, oFat.m_ucFileEntryHead, DIR_ENTRY_SIZE, sCh);
FAT_WriteSector(p, nSector, oFat.m_ucBpbSecPerClus, sCh);
*nEmpFile = uHeadCluster;
}
else // Long file entry
{
FAT_ConvChNameToUniName((char*)cFname,&spLFUnicodeName, sCh);
FAT_GenerateSNameFromLName(oFat.m_sUdLFname, cSfname, &nLossFlag, sCh);
cTempSfname = cSfname;
if ((oFat.m_uDirEntryPerCulster-nOffset)>=entries) // the current cluster can hold all the long file dir entries
{
for (m=0; m<entries; m++)
{
if (m<(entries-1))
FAT_PassoutLFileName(oFat.m_sUdLFname, (u8*)cSfname, entries-m-1, &nDirecEntry, sCh);
else
FAT_WriteSFFileHead(cTempSfname, ucAttr, nLength, uHeadCluster, &nFileEnt, sCh);
FAT_CopyAblockOfMem(p+nOffset*32, oFat.m_ucFileEntryHead, DIR_ENTRY_SIZE, sCh);
nOffset ++;
}
FAT_WriteSector(p, nSector, oFat.m_ucBpbSecPerClus, sCh);
*nEmpFile = uHeadCluster;
}
else
{
nCurrDirNum = oFat.m_uDirEntryPerCulster-nOffset;
nNextDirNum = entries-nCurrDirNum;
for (m=0; m<nCurrDirNum; m++)
{
FAT_PassoutLFileName(oFat.m_sUdLFname, (u8*)cSfname, entries-m-1, &nDirecEntry, sCh);
FAT_CopyAblockOfMem(p+nOffset*32, oFat.m_ucFileEntryHead, DIR_ENTRY_SIZE, sCh);
nOffset ++;
}
FAT_WriteSector(p, nSector, oFat.m_ucBpbSecPerClus, sCh);
FAT_FromClusterToLba(nNextCluster, &nSector, sCh);
FAT_ReadSector(p, nSector, oFat.m_ucBpbSecPerClus, sCh);
for(m=0; m<nNextDirNum; m++)
{
if (m!=(nNextDirNum-1))
FAT_PassoutLFileName(oFat.m_sUdLFname, (u8*)cSfname, nNextDirNum-m-1, &nDirecEntry, sCh);
else
FAT_WriteFileHead(cTempSfname, ucAttr, nLength, uHeadCluster, &nFileEnt, sCh);
FAT_CopyAblockOfMem(p+m*32, oFat.m_ucFileEntryHead, DIR_ENTRY_SIZE, sCh);
}
FAT_WriteSector(p, nSector, oFat.m_ucBpbSecPerClus, sCh);
*nEmpFile = uHeadCluster;
}
}
}
/*****************************************************************************
* Fat has two part: one is to link the file data, another is to link the root(store the file dir entry)
*****************************************************************************/
void FAT_UpdateFileDataCluInFat(int numberofcluster, int* uAlloCluster, SDHC* sCh)
{
int i, start_sector=0, offset=0;
int nCluster=2;
int clucount=oFat.m_nBpbCountOfClusters+2;
int curhead, curlength=0;
int nNextClu;
int nPreOffset; //the offset of the previous cluster
int nPreSector;
u8 ucFatBuff[512];
bool bCrossSectorFlag=false;
bool bFreeClustExist=false;
int res;
int sTmp;
if (numberofcluster<=0) {
*uAlloCluster = 0;
return;
}
while (nCluster<clucount)
{
FAT_ClusterFatAddr(nCluster, &start_sector, &offset, sCh); // offset: in bytes
FAT_GetFat(start_sector, offset, &sTmp, &res, sCh);
Assert(res>0);
if ((sTmp&oFat.m_nMaskCluster) == FAT_FREE_CLUSTER)
{
bFreeClustExist = true;
if (!curlength) // the headcluster and the coresponding offset
{
nPreOffset =offset;
curhead = nCluster;
}
else
nNextClu = nCluster;
curlength++;
if (curlength>1 && bCrossSectorFlag==false)
FAT_SetFat(nPreOffset, nNextClu, oFat.m_pFatBuffStart, sCh);
if (bCrossSectorFlag) {
FAT_SetFat(nPreOffset, nNextClu, ucFatBuff, sCh);
bCrossSectorFlag = false;
FAT_WriteSector(ucFatBuff, nPreSector+oFat.m_uBpbHiddSec+oFat.m_nPosFat+SDCARD_OFFSET_SECTOR, 1, sCh);// sunny modify
}
nPreOffset =offset;
if (curlength>=numberofcluster) {
FAT_SetFat(nPreOffset, oFat.m_nEOC, oFat.m_pFatBuffStart, sCh);
FAT_WriteSector(oFat.m_pFatBuffStart, start_sector+oFat.m_uBpbHiddSec+oFat.m_nPosFat+SDCARD_OFFSET_SECTOR, 1, sCh);// sunny modify
break;
}
}
if (offset==508)
//Disp("just for debug\n");
Putc('.');
if (offset==508 && bFreeClustExist==true) //the end of one sector
{
bFreeClustExist = false;
nPreSector = start_sector;
bCrossSectorFlag = true;
for(i=0; i<512; i++)
ucFatBuff[i] =*(oFat.m_pFatBuffStart++);
}
nCluster++;
}
*uAlloCluster = curhead;
}
void FAT_UpdateRootCluInFat(int nNextClu, SDHC* sCh)
{
int nStartClu = 2;
int sTmp;//res,
int start_sector, offset;
u8* pFatTempBuff = oFat.m_pFatBuffStart;
while(1)
{
FAT_ClusterFatAddr(nStartClu, &start_sector, &offset, sCh);
FAT_ReadSector(pFatTempBuff, start_sector+oFat.m_nPosFat+oFat.m_uBpbHiddSec+SDCARD_OFFSET_SECTOR, 1, sCh);
sTmp = (LSB_GET_4BYTES(pFatTempBuff+offset))&oFat.m_nMaskCluster;
if((sTmp&oFat.m_nMaskCluster) == oFat.m_nEOC)
break;
else
nStartClu = sTmp;
}
FAT_SetFat(offset, nNextClu, pFatTempBuff, sCh);
FAT_WriteSector(pFatTempBuff, start_sector+oFat.m_uBpbHiddSec+oFat.m_nPosFat+SDCARD_OFFSET_SECTOR, 1, sCh);
FAT_ClusterFatAddr(nNextClu, &start_sector, &offset, sCh); // offset: in bytes
FAT_ReadSector(pFatTempBuff, start_sector+oFat.m_nPosFat+oFat.m_uBpbHiddSec+SDCARD_OFFSET_SECTOR, 1, sCh);
FAT_SetFat(offset, oFat.m_nEOC, pFatTempBuff, sCh);
FAT_WriteSector(pFatTempBuff, start_sector+oFat.m_uBpbHiddSec+oFat.m_nPosFat+SDCARD_OFFSET_SECTOR, 1, sCh);
}
/******************************************************************
scan a continuous cluster block with specified size
if success return the specified nLength
if failed return the maximum nLength of continuous cluster block
nLength - specified nLength
nPosi - nHead cluster
******************************************************************/
void FAT_ScanCluster(int frag, int nLength, int *nPosi, int rstart, int rend, u32* uCluBlk, SDHC* sCh) // LYS 040424 big question
{
int start_sector, offset;
int cluster=2;
int clucount=oFat.m_nBpbCountOfClusters+2;
int curhead, curlength=0;
int prehead, prelength=0;
while (cluster<clucount)
{
int res, sTmp; // uint? or int?
if (rstart)
{
if (cluster>=rstart&&cluster<rend)
{
Assert(rend>rstart);
cluster=rend;
if (cluster>=clucount)
break;
}
}
FAT_ClusterFatAddr(cluster, &start_sector, &offset, sCh); //
//printf("start_sector: %d, offset: %d\n", start_sector, offset); // LYS 040424
FAT_GetFat(start_sector, offset, &sTmp, &res, sCh);
if (res<=0)
Assert(0);
if ((sTmp&oFat.m_nMaskCluster) == FAT_FREE_CLUSTER) // 0
{
if (!curlength)
curhead = cluster;
if (++curlength>=nLength)
break;
}
else if (!frag) {
if (prelength<curlength) {
prehead = curhead;
prelength = curlength;
}
curlength = 0;
}
cluster++;
///VCX_service(); //HW dependent routine
} // end of while
if (prelength>curlength)
{
curhead = prehead;
curlength = prelength;
}
*nPosi = curhead;
*uCluBlk = curlength;
}
/*******************************************************/
/* create a (small) file with the whole data in oFat.m_ucBuffer */
/*******************************************************/
void FAT_CreateSFile(int location, const char *lfname, u8 ucAttr, int nLength, u8 *data, int* nSFile, SDHC* sCh)
{
int headcluster;
int numberofsector;
int remains; // LYS 040426
int i; // LYS 040426
int nLba;
int nLen;
FAT_CreateFile(location, lfname, ucAttr, nLength, &headcluster, sCh);
if (headcluster < 2)
{
*nSFile = -1;
return;
}
numberofsector = (nLength+oFat.m_usBpbBytsPerSec-1) / oFat.m_usBpbBytsPerSec;
#if 1 // LYS 040426 fill the zero for the padding.. LYS 040617
remains = nLength % oFat.m_usBpbBytsPerSec;
for(i=0;i<SECBUFFSIZE-remains;i++)
{
*((volatile u8*)(data+nLength+i)) = 0;
}
#endif
FAT_FromClusterToLba(headcluster, &nLba, sCh);
FAT_WriteSector(data, nLba, numberofsector, sCh);
nLen = strlen(lfname);
for (i=0; i<nLen; i++)
oFat.m_pDDE[oFat.m_nFileIndex].filename[i] = *(lfname+i);
oFat.m_pDDE[oFat.m_nFileIndex].dirflag = ucAttr;
oFat.m_pDDE[oFat.m_nFileIndex].location = headcluster;
oFat.m_pDDE[oFat.m_nFileIndex].nFileSz = nLength;
oFat.m_nFileIndex++;
*nSFile = headcluster;
}
void FAT_WriteSFile(char *fileName, int nLength, u8* srcAddr, int* nWrFile, SDHC* sCh)
{
int nSFile;
FAT_CreateSFile(FIRST_DATA_CLUSTER, fileName, ATTR_ARCHIVE, nLength, srcAddr, &nSFile, sCh);
if(nSFile>=0) {
FAT_SetFSInfo(sCh);
FAT_CopyFatTableToBackup(sCh);
*nWrFile = 1;
}
else {
*nWrFile = 0;
}
}
/********************************************************/
/* create a file as directory */
/********************************************************/
// headsector: the cluster to write '.', '..'
// return value: headsector
void FAT_CreateDirectory(int location, char *dirname, int* nCrFile, SDHC* sCh)
{
//uchar *hp = oFat.m_ucDirBuffStart;
u8* hp;
int headsector, headcluster;
u8* ucSpecEnt1;
u8* ucSpecEnt2;
FAT_InitBuffDirMem(&hp, sCh); // Caution: CreateFile() uses oFat.m_pBufferFileMem[]...
FAT_CreateFile(location, dirname, ATTR_DIRECTORY, 0, &headcluster, sCh);
printf("dir create: headcluster: %d\n", headcluster);
if (headcluster<2)
*nCrFile = -1;
FAT_FromClusterToLba(headcluster, &headsector, sCh);
printf("dir create: headsector: %d, oFat.m_nPosRoot: %d\n", headsector, oFat.m_nPosRoot); //2022
if (headsector != oFat.m_nPosRoot)
{
FAT_ReadSector(hp, headsector, 1, sCh);
FAT_GenerateDirEntry(DOT_ENTRY_TAG, headcluster, &ucSpecEnt1, sCh);
FAT_CopyAblockOfMem(hp, ucSpecEnt1, DIR_ENTRY_SIZE, sCh);
//hp += DIR_ENTRY_SIZE;
//CopyAblockOfMem(hp, GenerateDirEntry(DOTDOT_ENTRY_TAG, nPwd), DIR_ENTRY_SIZE);
FAT_GenerateDirEntry(DOTDOT_ENTRY_TAG, oFat.m_nPwd, &ucSpecEnt2, sCh);
FAT_CopyAblockOfMem(hp+DIR_ENTRY_SIZE, ucSpecEnt2, DIR_ENTRY_SIZE, sCh);
//hp += DIR_ENTRY_SIZE;
FAT_CopyEntry(hp+2*DIR_ENTRY_SIZE, TERM_ENTRY_TAG, sCh);
FAT_WriteSector(hp, headsector, 1, sCh); // directory create
}
*nCrFile = headcluster;
}
/********************************************************/
/* delete file from hd with unicode long file name */
/********************************************************/
void FAT_DeleteFile(char *cSfname, u8 ucAttr, int* nDelFile, SDHC* sCh) //ucAttr not used...
{
u8 p[SECBUFFSIZE*MAXSEC_PER_CLUSTER];
int sector, offset;//, cluster;
// int index=-1;
int clusterLength; //LYS 040510
u32 nHeadCluster; //kst 060308
int nRelCluster;
#if 1 // LYS 040114
//cluster = FindClusterFromName(cSfname);
int nEntOffset;
FAT_FindDirEntryOffsetFromName(cSfname, &nEntOffset, sCh);
if((of
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -