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

📄 d_loader.c

📁 乐高机器人的源码,开发平台是IAR_for_AVR.
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -