📄 d_loader.c
字号:
dLoaderWritePage(((ULONG)HandleTable[Handle].pFlash & ~(SECTORSIZE - 1)), WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf);
WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = 0;
}
}
}
else
{
*pLen = 0;
}
if (DLERROR == WriteBuffer[HandleTable[Handle].WriteBufNo].Status)
{
/* DLERROR set due to over flow a file - EOFEXSPECTED should be set */
/* for repeated overflow requests */
Handle |= EOFEXSPECTED;
}
return(Handle);
}
UWORD dLoaderGetFreeHandle(void)
{
UBYTE Tmp;
UWORD Handle;
Handle = NOMOREHANDLES;
for(Tmp = 0; Tmp < MAX_HANDLES; Tmp++)
{
if (FREE == HandleTable[Tmp].Status)
{
HandleTable[Tmp].Status = BUSY;
Handle = 0; /* Clear NOMOREHANDLES */
Handle = Tmp;
Tmp = MAX_HANDLES;
}
}
return(Handle);
}
const UBYTE * dLoaderGetNextSectorPtr(UBYTE Handle)
{
const UBYTE *pAdr;
/* Check for the last entry in a sector - if so, */
/* then this is the sector number on the next sector table */
if (!((ULONG)(HandleTable[Handle].pSectorNo + 1) & (SECTORSIZE-1)))
{
HandleTable[Handle].pSectorNo = (const UWORD *)(((ULONG)(*(HandleTable[Handle].pSectorNo)) << SECTORSIZESHIFT) | FLASHOFFSET);
}
/* If pointing at an illegal adr then set it to NULL */
if (SIZEOFFLASH < (ULONG)((ULONG)(HandleTable[Handle].pSectorNo) & ~FLASHOFFSET))
{
pAdr = NULL;
}
else
{
pAdr = (const UBYTE *)(((ULONG)(*(HandleTable[Handle].pSectorNo)) << SECTORSIZESHIFT) | FLASHOFFSET);
}
(HandleTable[Handle].pSectorNo)++;
return(pAdr);
}
UWORD dLoaderCloseHandle(UWORD Handle)
{
UWORD RtnStatus;
FILEHEADER *TmpFileHeader;
RtnStatus = Handle;
/* if it is a normal handle or handle closed due to an error then error must be different */
/* from the no more handles available error (else you would delete a used handle) */
if (((0x8000 > Handle) || (NOMOREHANDLES != (Handle & 0xFF00))) && ((UBYTE)Handle < MAX_HANDLES))
{
Handle &= 0x00FF;
if (FREE == HandleTable[Handle].Status)
{
RtnStatus |= HANDLEALREADYCLOSED;
}
else
{
/* Handle was NOT free - now close it */
if (DOWNLOADING == HandleTable[Handle].Status)
{
if (DATAFILE & HandleTable[Handle].FileType)
{
/* This is a Datafile that should be closed and this is a legal action */
/* 1. Write the data from the writebuffer into flash */
/* 2. Update the Datalength in the file header */
/* This takes minimum 8 mS (2 page writes into flash) */
if (WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex)
{
/* There are databytes in the writebuffer write them into flash */
dLoaderWritePage(((ULONG)HandleTable[Handle].pFlash & ~(SECTORSIZE - 1)), WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf);
}
/* Now the databuffer is free now use if for a buffer for the fileheader*/
memcpy(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, (void const*)HandleTable[Handle].FileDlPtr, SECTORSIZE);
TmpFileHeader = (FILEHEADER *) WriteBuffer[HandleTable[Handle].WriteBufNo].Buf;
TmpFileHeader->DataSize = TmpFileHeader->FileSize - HandleTable[Handle].DataLength;
dLoaderWritePage(((ULONG)HandleTable[Handle].FileDlPtr & ~(SECTORSIZE - 1)), SECTORSIZE, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf);
}
else
{
/* This is a system file being closed now update the file pointer table if no error and complete file written */
if ((DLERROR != WriteBuffer[HandleTable[Handle].WriteBufNo].Status) && (0 == HandleTable[Handle].DataLength))
{
/* no error durig download - add the file pointer to the file pointer table */
Handle = dLoaderInsertPtrTable((const UBYTE *) HandleTable[Handle].FileDlPtr, Handle);
}
else
{
/* an error has occured during download - now clean up the mess... */
dLoaderUpdateSectorTable();
FreeUserFlash = dLoaderReturnFreeFlash();
}
}
}
if (HandleTable[Handle].WriteBufNo != FREEBUFNO)
{
WriteBuffer[HandleTable[Handle].WriteBufNo].Status = FREE;
HandleTable[Handle].WriteBufNo = FREEBUFNO;
}
HandleTable[Handle].Status = FREE;
}
}
return(RtnStatus);
}
UWORD dLoaderOpenRead(UBYTE *pFileName, ULONG *pLength)
{
UWORD Handle;
UBYTE Name[FILENAME_LENGTH + 1];
const FILEHEADER *TmpHeader;
ULONG FileLength;
ULONG DataLength;
Handle = dLoaderFind(pFileName, Name, &FileLength, &DataLength, (UBYTE)BUSY);
if (0x8000 > Handle)
{
if (FileLength)
{
TmpHeader = (FILEHEADER const *)(Files[HandleTable[Handle].FileIndex]);
HandleTable[Handle].pFlash = (const UBYTE *)TmpHeader->FileStartAdr;
HandleTable[Handle].pSectorNo = TmpHeader->FileSectorTable;
HandleTable[Handle].DataLength = TmpHeader->DataSize;
HandleTable[Handle].ReadLength = 0;
*pLength = TmpHeader->DataSize;
}
else
{
Handle = FILENOTFOUND;
}
}
return(Handle);
}
UWORD dLoaderRead(UBYTE Handle, UBYTE *pBuffer, ULONG *pLength)
{
UWORD ByteCnt, Status;
Status = dLoaderCheckHandle(Handle, BUSY);
if (0x8000 > Status)
{
Status = Handle;
ByteCnt = 0;
while (ByteCnt < *pLength)
{
if (HandleTable[Handle].DataLength <= HandleTable[Handle].ReadLength)
{
*pLength = ByteCnt;
Status |= ENDOFFILE;
}
else
{
*pBuffer = *(HandleTable[Handle].pFlash);
pBuffer++;
ByteCnt++;
HandleTable[Handle].pFlash++;
HandleTable[Handle].ReadLength++;
if (!((ULONG)(HandleTable[Handle].pFlash) & (SECTORSIZE-1)))
{
HandleTable[Handle].pFlash = dLoaderGetNextSectorPtr(Handle);
}
}
}
}
return(Status);
}
UWORD dLoaderDelete(UBYTE *pFile)
{
UWORD LStatus;
ULONG FileLength;
ULONG DataLength;
UBYTE Name[FILENAME_LENGTH + 1];
LStatus = dLoaderFind(pFile, Name, &FileLength, &DataLength, (UBYTE)BUSY);
if (!IS_LOADER_ERR(LStatus))
{
LStatus = dLoaderDeleteFilePtr((UBYTE)LStatus);
}
dLoaderCloseHandle(LStatus);
return(LStatus);
}
UWORD dLoaderFind(UBYTE *pFind, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength, UBYTE Session)
{
UWORD Handle;
Handle = dLoaderGetFreeHandle();
if (Handle < 0x8000)
{
if (FILENAME_LENGTH < strlen((const char*)pFind))
{
Handle |= ILLEGALFILENAME;
}
else
{
HandleTable[Handle].FileIndex = 0xFFFF;
HandleTable[Handle].Status = Session;
dLoaderInsertSearchStr((HandleTable[Handle].SearchStr), pFind, &(HandleTable[Handle].SearchType));
Handle = dLoaderFindNext(Handle, pFound, pFileLength, pDataLength);
}
}
return(Handle);
}
UWORD dLoaderFindNext(UWORD Handle, UBYTE *pFound, ULONG *pFileLength, ULONG *pDataLength)
{
UBYTE Tmp;
UWORD ReturnVal;
FILEHEADER *pHeader;
*pFileLength = 0;
ReturnVal = Handle | FILENOTFOUND;
for (Tmp = ((HandleTable[Handle].FileIndex) + 1); Tmp < MAX_FILES; Tmp++)
{
if (0xFFFFFFFF != Files[Tmp])
{
if (SUCCESS == dLoaderCheckName((UBYTE*)Files[Tmp], HandleTable[Handle].SearchStr, HandleTable[Handle].SearchType))
{
HandleTable[Handle].FileIndex = Tmp;
Tmp = MAX_FILES;
ReturnVal = Handle;
}
}
}
if (0x8000 > ReturnVal)
{
pHeader = (FILEHEADER *)Files[HandleTable[Handle].FileIndex];
if (NULL != pFileLength)
{
*pFileLength = pHeader->FileSize;
}
if (NULL != pDataLength)
{
*pDataLength = pHeader->DataSize;
}
if (NULL != pFound)
{
dLoaderCopyFileName(pFound, (UBYTE *)pHeader->FileName);
}
}
return(ReturnVal);
}
ULONG dLoaderReturnFreeFlash(void)
{
ULONG SectorCnt, IndexPtr;
UWORD Sectors;
Sectors = 0;
IndexPtr = (ULONG)0x01 << SECTORPOINTERUSERFLASH; /* Offset in first index can be different from 0 */
for(SectorCnt = SECTORINDEXUSERFLASH; SectorCnt <= ((NOOFSECTORS>>5)-1); SectorCnt++)
{
for( ; IndexPtr > 0; IndexPtr<<=1)
{
if (!(SectorTable[SectorCnt] & IndexPtr))
{
Sectors++;
}
}
IndexPtr = 0x00000001;
}
FreeSectors = Sectors;
return(dLoaderCalcFreeFileSpace(Sectors));
}
ULONG dLoaderCalcFreeFileSpace(UWORD NosOfFreeSectors)
{
UWORD SectorCnt;
ULONG Space;
ULONG HeaderSpace;
/* Calculate only if any sectors available */
if (NosOfFreeSectors)
{
Space = (ULONG)NosOfFreeSectors << SECTORSIZESHIFT;
/* (FreeSectors - 1) is beacuse the the first sector of a file do not */
/* require an entry in the sector table - it is pointed to by the filepointer */
/* in the file pointer table*/
SectorCnt = NosOfFreeSectors - 1;
/* If more that one sector is used for the header the first filebody sector do not */
/* require an entry in the sectortable - it is pointed to by the file startpointer */
/* in the file header */
if ((((SectorCnt<<1) + HEADERFIXEDSIZE) & (SECTORSIZE - 1)) < 4)
{
SectorCnt--;
}
HeaderSpace = (HEADERFIXEDSIZE + (SectorCnt << 1));
if (HeaderSpace & 0x0003)
{
/* Header size is not a multiplum of 4 - now make it a mul 4 */
HeaderSpace += (0x0004 - (HeaderSpace & 0x0003));
}
Space -= HeaderSpace;
}
return(Space);
}
UWORD dLoaderGetFilePtr(UBYTE *pFileName, UBYTE *pPtrToFile, ULONG *pFileLength)
{
UWORD RtnVal;
UBYTE FoundFile[FILENAME_LENGTH + 1];
FILEHEADER *File;
ULONG DataLength;
RtnVal = dLoaderFind(pFileName, FoundFile, pFileLength, &DataLength, (UBYTE)BUSY);
if (0x8000 > RtnVal)
{
File = (FILEHEADER*) Files[HandleTable[RtnVal].FileIndex];
if (LINEAR & File->FileType)
{
*((ULONG*)pPtrToFile) = File->FileStartAdr;
}
else
{
RtnVal |= NOTLINEARFILE;
}
}
return(RtnVal);
}
UWORD dLoaderAllocateHeader(UWORD Handle, ULONG *FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize, UWORD CompleteFileSectorSize)
{
UWORD Tmp;
UWORD SectorTableIndex;
ULONG SectorIndex;
UWORD HeaderSectorSize;
UBYTE EvenHeader;
UWORD FileBodySectorSize;
UWORD ErrorCode;
HeaderSectorSize = ((HeaderByteSize - 1) >> SECTORSIZESHIFT) + 1;
FileBodySectorSize = (((pHeader->FileSize - (SECTORSIZE - (HeaderByteSize & (SECTORSIZE - 1)))) - 1) >> SECTORSIZESHIFT) + 1;
/* First allocate the file file header - this means the file name, */
/* the file start adress, and the sector table */
/* SectorTableIndex indicates in the last word of a sector in which */
/* sector the sectortable continues */
SectorTableIndex = ((SECTORSIZE - HEADERFIXEDSIZE)>>1) - 1;
/* Find first free sector - here there is a differende between linear or not*/
ErrorCode = dLoaderFindFirstSector(pHeader->FileType, CompleteFileSectorSize, &Tmp);
if (SUCCESS == ErrorCode)
{
*FileStartAdr = (ULONG)((ULONG)Tmp << SECTORSIZESHIFT) | FLASHOFFSET;
HandleTable[Handle].FileDlPtr = *FileStartAdr;
SectorIndex = (Tmp >> 5);
Tmp &= 0x1F;
SectorTable[SectorIndex]|= (0x01<<Tmp);
/* Advance to next sector */
Tmp++;
/* if only one sector used for for file header */
pHeader->FileStartAdr = (ULONG)(*FileStartAdr) + HeaderByteSize;
/* if there is a sectortable it always starts right after the fixed header (Name + start + size)*/
HandleTable[Handle].pSectorNo = (const UWORD *)(*FileStartAdr + HEADERFIXEDSIZE);
/* First header has been allocated by find first function */
HeaderSectorSize--;
UWORD TmpHSS = HeaderSectorSize;
/* Next part is only executed when more than one sector is used */
if (HeaderSectorSize)
{
UBYTE ExitCode = FALSE;
while ((FALSE == ExitCode) && (SectorIndex < (NOOFSECTORS/32)))
{
for(; ((Tmp < 32) && (ExitCode == FALSE)); Tmp++)
{
if (!(SectorTable[SectorIndex] & (0x01<<Tmp)))
{
/* Sector is free you can have this one */
SectorTable[SectorIndex] |= (0x01<<Tmp);
pHeader->FileSectorTable[SectorTableIndex] = (SectorIndex << 5) + Tmp;
SectorTableIndex += (SECTORSIZE/2);
HeaderSectorSize--;
if (0 == HeaderSectorSize)
{
pHeader->FileStartAdr = (((SectorIndex << 5) + Tmp) << SECTORSIZESHIFT) + (HeaderByteSize - (TmpHSS<<SECTORSIZESHIFT)) | FLASHOFFSET;
ExitCode = TRUE;
}
}
}
if (FALSE == ExitCode)
{
SectorIndex++;
Tmp = 0;
}
}
}
EvenHeader = FALSE;
if (((HeaderByteSize & (SECTORSIZE - 1)) >= (SECTORSIZE - 2)) || (0 == (HeaderByteSize & (SECTORSIZE - 1))))
{
/* The header uses exact one or several sectors */
/* meaning that the next sector do not go into */
/* the sectortable as it is pointed to by the */
/* FileStart pointer */
EvenHeader = TRUE;
}
/* Now allocated the file body */
SectorTableIndex = 0;
while ((FileBodySectorSize > 0) && (SectorIndex < (NOOFSECTORS/32)))
{
for(; Tmp < 32; Tmp++)
{
if (!(SectorTable[SectorIndex] & (0x01<<Tmp)))
{
if (TRUE == EvenHeader)
{
/* This sector do not go into the sectortable */
/* it is pointed to by the filestart pointer */
SectorTable[SectorIndex] |= (0x01<<Tmp);
pHeader->FileStartAdr = (((SectorIndex << 5) + Tmp) << SECTORSIZESHIFT) | FLASHOFFSET;
EvenHeader = FALSE;
}
else
{
/* Sector is free you can have this one */
SectorTable[SectorIndex] |= (0x01<<Tmp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -