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

📄 d_loader.c

📁 乐高机器人的源码,开发平台是IAR_for_AVR.
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Date init       14.12.2004
//
// Revision date   $Date:: 17-05-06 8:36                                     $
//
// Filename        $Workfile:: d_loader.c                                    $
//
// Version         $Revision:: 75                                            $
//
// Archive         $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_loader.c $
//
// Platform        C
//

#include  "stdconst.h"
#include  "modules.h"
#include  "m_sched.h"
#include  "d_loader.h"
#include  "d_loader.r"
#include  <string.h>
#include  <ctype.h>

#define   FILEVERSION                   (0x00000106L)

#define   MAX_FILES                     ((SECTORSIZE/4) - 1)  /* Last file entry is used for file version*/
#define   MAX_WRITE_BUFFERS             4
#define   FLASHOFFSET                   (0x100000L)

#define   IS_LOADER_ERR(LStatus)        (((LStatus) & 0xFF00) != SUCCESS)
#define   SECTORINDEXUSERFLASH          ((STARTOFUSERFLASH & ~FLASHOFFSET)/256/32)
#define   SECTORPOINTERUSERFLASH        (((STARTOFUSERFLASH & ~FLASHOFFSET) - ((SECTORINDEXUSERFLASH * 32) * 256))/256)

typedef   struct
{
  const   UBYTE  *pFlash;
  const   UWORD  *pSectorNo;
  ULONG           ReadLength;
  ULONG           DataLength;
  ULONG           FileDlPtr;
  UBYTE           SearchStr[FILENAME_SIZE];
  UWORD           FileIndex;
  UWORD           CheckSum;
  UBYTE           SearchType;
  UBYTE           Status;
  UBYTE           FileType;
  UBYTE           WriteBufNo;
}HANDLE;

typedef   struct
{
  ULONG   Buf[SECTORSIZE/4];
  UBYTE   BufIndex;
  UBYTE   Status;
}WRITEBUF;

static    HANDLE      HandleTable[MAX_HANDLES];
static    WRITEBUF    WriteBuffer[MAX_WRITE_BUFFERS];
static    ULONG       SectorTable[NOOFSECTORS>>5];
static    const       ULONG *Files;
static    FILEHEADER  Header;
static    ULONG       FreeUserFlash;
static    UWORD       FreeSectors;

void      dLoaderUpdateSectorTable(void);
UWORD     dLoaderGetFreeHandle(void);
const     UBYTE * dLoaderGetNextSectorPtr(UBYTE Handle);
ULONG     dLoaderReturnFreeFlash(void);
UWORD     dLoaderAllocateHeader(UWORD Handle, ULONG *FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize, UWORD CompleteFileSectorSize);
UWORD     dLoaderFlashFileHeader(UWORD Handle, ULONG FileStartAdr, FILEHEADER *pHeader, UWORD HeaderByteSize);
UWORD     dLoaderFindFirstSector(UBYTE Type, UWORD SectorCount, UWORD *pSector);
UWORD     dLoaderAllocateWriteBuffer(UWORD  Handle);
UWORD     dLoaderSetFilePointer(UWORD Handle, ULONG BytePtr, const UBYTE **pData);
UWORD     dLoaderGetSectorNumber(ULONG Adr);
void      dLoaderCheckVersion(void);
UWORD     dLoaderCheckHandle(UWORD Handle, UBYTE Operation);
ULONG     dLoaderCalcFreeFileSpace(UWORD NosOfFreeSectors);
UWORD     dLoaderCheckDownload(UBYTE *pName);
UWORD     dLoaderAvailFileNo(void);


void      dLoaderInit(void)
{
  UWORD   Tmp;

  LOADERInit;

  Files = (const ULONG*)STARTOFFILETABLE;

  /* Clear handle table */
  for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++)
  {
    HandleTable[Tmp].Status     = FREE;
    HandleTable[Tmp].WriteBufNo = FREEBUFNO;
  }

  /* Clear write buffers */
  for (Tmp = 0; Tmp < MAX_WRITE_BUFFERS; Tmp++)
  {
    WriteBuffer[Tmp].Status = FREE;
  }

  dLoaderCheckVersion();
  dLoaderUpdateSectorTable();
  FreeUserFlash = dLoaderReturnFreeFlash();
}

UWORD     dLoaderAvailFileNo(void)
{
  UBYTE   Tmp, Tmp2;
  UWORD   ReturnVal;
  const   ULONG* FlashPtr;

  ReturnVal = NOMOREFILES;
  Tmp2      = 0;
  FlashPtr  = Files;
  for(Tmp = 0; Tmp < MAX_HANDLES; Tmp++)
  {

    /* Check for files allready downloading except datafiles as the have entered their */
    /* filepointer in the filepointer table at begin of download                       */
    if ((DOWNLOADING == HandleTable[Tmp].Status) && (DATAFILE != HandleTable[Tmp].FileType))
    {
      Tmp2++;
    }
  }
  if ((0xFFFFFFFF == FlashPtr[(MAX_FILES - 1) - Tmp2]) || (0 == FlashPtr[(MAX_FILES - 1) - Tmp2]))
  {
    ReturnVal = SUCCESS;
  }
  return(ReturnVal);
}


UWORD     dLoaderInsertPtrTable(const UBYTE *pAdr, UWORD Handle)
{
  UWORD   TmpCnt;
  UWORD   Status;
  ULONG   SectorCopy[(SECTORSIZE/4)];
  const   ULONG* FlashPtr;

  /* It is possible to add the file as checking for number of files */
  /* is done when initiating the file download                      */
  FlashPtr = Files;
  memset(SectorCopy, 0, sizeof(SectorCopy));

  TmpCnt = MAX_FILES - 1;
  while(TmpCnt)
  {

    /* TmpCnt-- first because you want to copy from index 0 */
    TmpCnt--;
    SectorCopy[TmpCnt + 1] = FlashPtr[TmpCnt];
  }

  /* Copy the new file in position 0 */
  SectorCopy[0]         = (ULONG)pAdr;

  /* Add the File version to the top of the file list */
  SectorCopy[MAX_FILES] = FlashPtr[MAX_FILES];
  dLoaderWritePage((ULONG)Files, SECTORSIZE, SectorCopy);

  /* FileIndex in HandleTable should be incremented by one - new file index is 0 */
  for (TmpCnt = 0; TmpCnt < MAX_HANDLES; TmpCnt++)
  {
    if (HandleTable[TmpCnt].Status != FREE)
    {
      (HandleTable[TmpCnt].FileIndex)++;
    }
  }
  HandleTable[Handle].FileIndex = 0;

  Status = SUCCESS | Handle;

  return(Status);
}


UWORD     dLoaderDeleteFilePtr(UWORD Handle)
{

  UWORD   ErrorCode;
  UWORD   LongCnt;
  ULONG   SectorCopy[(SECTORSIZE>>2)];
  const   ULONG *pFlash;

  ErrorCode = SUCCESS;
  if (0xFFFFFFFF != Files[HandleTable[Handle].FileIndex])
  {
    ErrorCode = dLoaderCheckFiles(Handle);
    if (0x8000 > ErrorCode)
    {
      pFlash = Files;
      for (LongCnt = 0; LongCnt < (HandleTable[Handle].FileIndex); LongCnt++, pFlash++)
      {
        SectorCopy[LongCnt] = *pFlash;
      }

      /* Skip the file that has to be deleted  */
      pFlash++;
      for ( ; LongCnt < (MAX_FILES - 1); LongCnt++, pFlash++)
      {
        SectorCopy[LongCnt] = *pFlash;
      }

      /* The top file entry is now free */
      SectorCopy[MAX_FILES - 1] = 0xFFFFFFFF;

      /* Insert the file version         */
      SectorCopy[MAX_FILES]     = *pFlash;


      /* Write the sectortable back into flash */
      dLoaderWritePage((ULONG)Files, SECTORSIZE,(ULONG*) &SectorCopy);
      dLoaderUpdateSectorTable();
      FreeUserFlash = dLoaderReturnFreeFlash();

      /* Update the HandleTable[].FileIndex */
      for (LongCnt = 0; LongCnt < MAX_HANDLES; LongCnt++)
      {
        if ((HandleTable[Handle].FileIndex <= HandleTable[LongCnt].FileIndex) && (FREE != HandleTable[LongCnt].Status))
        {
          (HandleTable[LongCnt].FileIndex)--;
        }
      }
    }
  }
  else
  {
    ErrorCode = FILENOTFOUND;
  }
  return(ErrorCode | Handle);
}


void      dLoaderDeleteAllFiles(void)
{
  ULONG   Tmp;
  ULONG   SectorBuf[SECTORSIZE/4];

  /* Close all handles - all files is to be wiped out */
  for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++)
  {
    dLoaderCloseHandle(Tmp);
  }

  for (Tmp = ((STARTOFUSERFLASH-FLASHOFFSET)/SECTORSIZE); Tmp < (SIZEOFFLASH/SECTORSIZE); Tmp++)
  {
    dLoaderErasePage(Tmp<<SECTORSIZESHIFT);
  }

  /* Insert the file version */
  memset(SectorBuf, 0xFF, SECTORSIZE);
  SectorBuf[(SECTORSIZE/4) - 1] = FILEVERSION;
  dLoaderWritePage(STARTOFFILETABLE, SECTORSIZE, SectorBuf);

  /* Update all other parameters */
  dLoaderUpdateSectorTable();
  FreeUserFlash = dLoaderReturnFreeFlash();
}


void      dLoaderUpdateSectorTable(void)
{
  UWORD   Tmp;
  UWORD   SectorNo;
  const   FILEHEADER *pFile;
  ULONG   FileStart;

  Tmp = 0;

  memset(SectorTable, 0, sizeof(SectorTable));

  /* All file pointer are occupied as default */
  while (Tmp < MAX_FILES)
  {
    SectorNo = dLoaderGetSectorNumber((ULONG)&Files[Tmp]);
    SectorTable[SectorNo>>5] |= (0x1 << (SectorNo - ((SectorNo>>5)<<5)));
    Tmp += (SECTORSIZE >> 2);
  }

  for (Tmp = 0; Tmp < MAX_FILES; Tmp++)
  {
    if ((0xFFFFFFFF != Files[Tmp]) && (0x00000000 != Files[Tmp]))
    {
      pFile       = (const FILEHEADER *) Files[Tmp];
      FileStart   = pFile->FileStartAdr;

      /* This is necessary if the start address is at the first address in an sector */
      SectorNo    = dLoaderGetSectorNumber((ULONG)pFile->FileStartAdr);
      SectorTable[SectorNo>>5] |= (0x1 << (SectorNo - ((SectorNo>>5)<<5)));

      /* This is necessary as the first sector (where the fileheader is) is not */
      /* included in the sector table                                           */
      SectorNo    = dLoaderGetSectorNumber((ULONG)Files[Tmp]);
      SectorTable[SectorNo>>5] |= (0x1 << (SectorNo - ((SectorNo>>5)<<5)));

      SectorNo = 0;
      while(FileStart > ((ULONG)(&(pFile->FileSectorTable[SectorNo]))) && (NOOFSECTORS > pFile->FileSectorTable[SectorNo]))
      {
        SectorTable[(pFile->FileSectorTable[SectorNo])>>5] |= (0x1 << ((pFile->FileSectorTable[SectorNo]) - (((pFile->FileSectorTable[SectorNo])>>5)<<5)));
        if (0 == ((ULONG)(&(pFile->FileSectorTable[SectorNo+1])) & (SECTORSIZE-1)))
        {
          SectorNo += (((pFile->FileSectorTable[SectorNo]) << SECTORSIZESHIFT) - ((ULONG)&(pFile->FileSectorTable[SectorNo]) & ~FLASHOFFSET)>>1);
        }
        else
        {
          SectorNo++;
        }
      }
    }
  }
}


UWORD     dLoaderCreateFileHeader(ULONG FileSize, UBYTE *pName, UBYTE LinearState, UBYTE FileType)
{
  UWORD       HeaderByteSize;
  ULONG       FileStartAdr;
  ULONG       CompleteFileByteSize;
  UWORD       Handle;
  UBYTE       Name[FILENAME_SIZE];
  ULONG       FileLength;
  ULONG       DataLength;
  UWORD       ErrorCode;
  UWORD       CompleteSectorNo;
  UWORD       Tmp;

  memset(&(Header.FileName), 0, sizeof(Header.FileName));
  memset(&(Header.FileSectorTable), 0xFF, sizeof(Header.FileSectorTable));

  ErrorCode = dLoaderFind(pName, Name, &FileLength, &DataLength, (UBYTE)BUSY);
  Handle =  ErrorCode & 0x00FF;
  if (SUCCESS == (ErrorCode & 0xFF00))
  {
    ErrorCode |= FILEEXISTS;
  }
  if (FILENOTFOUND == (ErrorCode & 0xFF00))
  {
    /* Here check for the download buffers for a matching download */
    /* in progress                                                 */
    ErrorCode &= 0x00FF;
    ErrorCode = dLoaderCheckDownload(pName);

    if (0x8000 > ErrorCode)
    {

      /* Check for file overflow */
      ErrorCode = dLoaderAvailFileNo();
      if (0x8000 > ErrorCode)
      {

        ErrorCode = dLoaderAllocateWriteBuffer(Handle);
        if (0x8000 > ErrorCode)
        {

          dLoaderCopyFileName((Header.FileName), pName);
          HandleTable[Handle].pSectorNo  = 0;
          HandleTable[Handle].DataLength = FileSize; /* used for end of file detection            */
          Header.FileSize                = FileSize; /* used to program into flash                */
          if (DATAFILE == FileType)
          {
            Header.DataSize = 0;
          }
          else
          {
            Header.DataSize = FileSize;
          }
          HandleTable[Handle].FileType   = FileType | LinearState; /* if it is a datafile it can be stopped     */
          Header.FileType                = FileType | LinearState; /* FileType included for future appending    */

          /* File body size calculation*/
          CompleteFileByteSize = FileSize;

          /* Add the the fixed header to the fixed size    */
          CompleteFileByteSize  += HEADERFIXEDSIZE;

          /* Find the number of sectors used by the fixed file size  */
          CompleteSectorNo       = (CompleteFileByteSize - 1) >> SECTORSIZESHIFT;

          /* Add the size taken by the sectortable               */
          CompleteFileByteSize  += (CompleteSectorNo << 1);

          /* Recalc the number of sectors - to see wether the sectortable has caused */
          /* the sectornumber to encrease                                            */
          Tmp = ((CompleteFileByteSize - 1) >> SECTORSIZESHIFT);

          /* Substract from the original sectors used - Tmp holds the encreased number*/
          Tmp -= CompleteSectorNo;
          if (Tmp)
          {
            /* The sectortable takes up more than one sector */
            CompleteFileByteSize += Tmp << 1;
            CompleteSectorNo     += Tmp;
          }

          HeaderByteSize         = CompleteFileByteSize - FileSize;

          if (HeaderByteSize & 0x0003)
          {
            /* Header size is not a multiplum of 4 - now make it a mul 4 */
            HeaderByteSize  += (0x0004 - (HeaderByteSize & 0x0003));
          }

          if (FileSize <= FreeUserFlash)
          {


            /* Allocate file header   */
            Tmp = (((CompleteFileByteSize - 1) >> SECTORSIZESHIFT) + 1);
            Handle = dLoaderAllocateHeader(Handle, &FileStartAdr, &Header, HeaderByteSize, Tmp);
            if (Handle < 0x8000)
            {
              dLoaderFlashFileHeader(Handle, FileStartAdr, &Header, HeaderByteSize);

              /* If this is a datafile then add the filepointer to the filepointer table */
              /* now as the datafile do not need to have a special size to be valid      */
              if (DATAFILE & HandleTable[Handle].FileType)
              {
                ErrorCode = dLoaderInsertPtrTable((const UBYTE *)HandleTable[Handle].FileDlPtr, Handle);
              }
              FreeSectors -= Tmp;
              FreeUserFlash = dLoaderCalcFreeFileSpace(FreeSectors);
              HandleTable[Handle].Status = DOWNLOADING;
            }
          }
          else
          {
            ErrorCode = NOSPACE;
          }
        }
      }
    }
  }

  return(ErrorCode | Handle);
}


UWORD     dLoaderWriteData(UWORD Handle, UBYTE *pBuf, UWORD *pLen)
{
  UWORD   Tmp;
  UBYTE   *pSectorBuf;

  Handle =  dLoaderCheckHandle(Handle, DOWNLOADING);
  if (0x8000 > Handle)
  {

    if (*pLen > HandleTable[Handle].DataLength)
    {

      /* Write request exceeds filesize - only flash up to filesize*/
      *pLen   = HandleTable[Handle].DataLength;
      WriteBuffer[HandleTable[Handle].WriteBufNo].Status = DLERROR;  /* save error untill close handle */
    }

    pSectorBuf = (UBYTE *)WriteBuffer[HandleTable[Handle].WriteBufNo].Buf;
    for(Tmp = 0; Tmp < *pLen; Tmp++)
    {
      pSectorBuf[WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex] = pBuf[Tmp];
      if ((WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex) >= (SECTORSIZE-1))
      {
        dLoaderWritePage(((ULONG)HandleTable[Handle].pFlash & ~(SECTORSIZE - 1)), SECTORSIZE, WriteBuffer[HandleTable[Handle].WriteBufNo].Buf);
        WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = 0;
        HandleTable[Handle].pFlash = dLoaderGetNextSectorPtr(Handle);
        memset(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, 0xFF, sizeof(WriteBuffer[0].Buf));
      }
      else
      {
        (WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex)++;
      }
    }
    HandleTable[Handle].DataLength -= *pLen;

    /* Check for correct end of file */
    if (0 == HandleTable[Handle].DataLength)
    {
      if ((WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex) != 0)
      {

        /* write the last data into the file */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -