⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 s3c6400 ADS下官方测试程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		*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 + -