fdi_spll.c

来自「Flash file system」· C语言 代码 · 共 1,894 行 · 第 1/5 页

C
1,894
字号

#define GET_PR_LOCK_REG(reg)  ((reg) ? FLASH_PR_LOCK_REG1 : FLASH_PR_LOCK_REG0)
#endif /* ENABLE_PR */



/*#############################################################################
 *# Function Pointers
 *###########################################################################*/

/* LowLvlWrite Function Pointer */
#if (BUFFER_SIZE > 0)
typedef HW_ERROR (*LLWRITE_FUNCPTR)(volatile FLASH_DATA *, const FLASH_DATA *,
                                    DWORD);
extern HW_ERROR LowLvlWrite(volatile FLASH_DATA *, const FLASH_DATA *, DWORD);
#else
typedef HW_ERROR (*LLWRITE_FUNCPTR)(volatile FLASH_DATA *, const FLASH_DATA *);
extern HW_ERROR LowLvlWrite(volatile FLASH_DATA *, const FLASH_DATA *);
#endif
static LLWRITE_FUNCPTR PtrLowLvlWrite;

/* LowLvlEraseBlock Function Pointer */
typedef HW_ERROR (*LLERASE_FUNCPTR)(volatile FLASH_DATA_PTR);
extern HW_ERROR LowLvlEraseBlock(volatile FLASH_DATA_PTR);
static LLERASE_FUNCPTR PtrLowLvlEraseBlock;

/* LowLvlReadStat Function Pointer */
typedef FLASH_DATA (*LLREADSTAT_FUNCPTR)(volatile FLASH_DATA_PTR);
extern FLASH_DATA LowLvlReadStat(volatile FLASH_DATA_PTR);
static LLREADSTAT_FUNCPTR PtrLowLvlReadStat;

/* LowLvlClearStat Function Pointer */
typedef void (*LLCLEARSTAT_FUNCPTR)(volatile FLASH_DATA_PTR);
extern void LowLvlClearStat(volatile FLASH_DATA_PTR);
static LLCLEARSTAT_FUNCPTR PtrLowLvlClearStat;

/* LowLvlLock Function Pointer */
#if (BLOCK_LOCK_SUPPORT == TRUE)
typedef HW_ERROR (*LLLOCK_FUNCPTR)(volatile FLASH_DATA_PTR, FLASH_DATA_PTR,
                                   HW_CMD);
extern HW_ERROR LowLvlLock(volatile FLASH_DATA_PTR, FLASH_DATA_PTR, HW_CMD);
static LLLOCK_FUNCPTR PtrLowLvlLock;
#endif

/* LowLvlProtectReg Function Pointer */
#if (ENABLE_PR != FDI_NONE)
typedef HW_ERROR (*LLPR_FUNCPTR)(volatile FLASH_DATA_PTR, FLASH_DATA_PTR,
                                 HW_CMD);
extern HW_ERROR LowLvlProtectReg(volatile FLASH_DATA_PTR, FLASH_DATA_PTR,
                                 HW_CMD);
static LLPR_FUNCPTR PtrLowLvlProtectReg;
#endif

/* LowLvlWritePacket Function Pointer */
#if ((PACKET_DATA == TRUE) && (BUFFER_SIZE == 0))
typedef HW_ERROR (*LLWRITEPACKET_FUNCPTR)(DWORD_PTR, DWORD_PTR, DWORD_PTR);
extern HW_ERROR LowLvlWritePacket(DWORD_PTR, DWORD_PTR, DWORD_PTR);
static LLWRITEPACKET_FUNCPTR PtrLowLvlWritePacket;
#endif /* BUFFER_SIZE */

#if (RELOCATE_CODE == TRUE)
extern void LowLvlEnd(void);
#endif


#if (CONSISTENT_ACCESS_TIME == TRUE)
extern DATA_LOOKUP_PTR FDI_DataLookupPtrTable[];
#endif /* CONSISTENT_ACCESS_TIME */
/*extern SEM_MTX_ID  SEM_LookupTable;*/
extern LOGICAL_BLOCK FDI_LogicalBlockTable[];
extern SEM_MTX_ID  SEM_BlockTable;

/*
 *### Local Functions
 *#########################
 */



/*
 *### Global Declarations
 *#########################
 */

#if (TIME_MONITOR_ENABLED == TRUE)
const DWORD LowLvlTimeNeeded = GET_MINIMUM_TICKS;
#endif /* TIME_MONITOR_ENABLED */


/* Flash Device Semaphores */
extern SEM_MTX_ID SEM_FlashWrite;
extern SEM_MTX_ID SEM_FlashErase;

/*
 *### Global Functions
 *#########################
 */

#if (RELOCATE_CODE == TRUE)
/*#############################################################################
  ### FlashDevInit (Relocatable Code Version)
  ###
  ### DESCRIPTION:
  ###   Initializes the pointers used by the flash device functions.  Though
  ###   the flash device functions do not check, this function must be
  ###   called before any of the flash device functions can be called.
  ###
  ### PARAMETERS:
  ###    IN:  address (DWORD) - The physical address to where the low-level
  ###          functions will be relocated.
  ###    OUT:
  ###
  ### RETURNS:
  ###   HW_ERR_NONE.
  ###
 */

HW_ERROR FlashDevInit(DWORD address)
{
   BYTE_PTR dst_ptr = (BYTE_PTR) address;
   BYTE_PTR src_ptr = (BYTE_PTR) LowLvlWrite;
   WORD size = (WORD) ((DWORD) LowLvlEnd - (DWORD) LowLvlWrite);

   /* 
    * the following codes are needed when the target cpu is ARM
	* which will interworking ARM & THUMB instruction.
	*
    * this code section to modify the bit0 of the function pointer.
    */
   /*------------------------begin--------------------------------*/
   DWORD TargetState = 0;

   TargetState = (((DWORD)src_ptr) & 0x01);
   address |=  TargetState;
   src_ptr = (BYTE_PTR)(((DWORD)src_ptr) & (~0x01));
   /*-------------------------end---------------------------------*/

   HARDWARE_INITIALIZE;
   MemoryMove(dst_ptr, src_ptr, size);

   /* Functions that must be relocated */
   PtrLowLvlWrite = (LLWRITE_FUNCPTR) address;
   PtrLowLvlEraseBlock = (LLERASE_FUNCPTR) (address +
                         ((DWORD) LowLvlEraseBlock - (DWORD) LowLvlWrite));
   PtrLowLvlReadStat = (LLREADSTAT_FUNCPTR) (address +
                       ((DWORD) LowLvlReadStat - (DWORD) LowLvlWrite));
   PtrLowLvlClearStat = (LLCLEARSTAT_FUNCPTR) (address +
                        ((DWORD) LowLvlClearStat - (DWORD) LowLvlWrite));

   /* Relocated functions based on configuration */
#if (BLOCK_LOCK_SUPPORT == TRUE)
   PtrLowLvlLock = (LLLOCK_FUNCPTR) (address + ((DWORD) LowLvlLock -
                   (DWORD) LowLvlWrite));
#endif /* BLOCK_LOCK_SUPPORT */

#if (ENABLE_PR != FDI_NONE)
   PtrLowLvlProtectReg = (LLPR_FUNCPTR) (address + ((DWORD) LowLvlProtectReg -
                         (DWORD) LowLvlWrite));
#endif /* ENABLE_PR */

#if ((PACKET_DATA == TRUE) && (BUFFER_SIZE == 0))
   PtrLowLvlWritePacket = (LLWRITEPACKET_FUNCPTR) (address +
                          ((DWORD) LowLvlWritePacket - (DWORD) LowLvlWrite));
#endif /* (PACKET_DATA == TRUE) && (BUFFER_SIZE == 0) */

   return HW_ERR_NONE;
}



#else /* RELOCATE_CODE != TRUE */
/*#############################################################################
  ### FlashDevInit (Non-Relocatable Code Version)
  ###
  ### DESCRIPTION:
  ###   Initializes the pointers used by the flash device functions.  Though
  ###   the flash device functions do not check, this function must be
  ###   called before any of the flash device functions can be called.
  ###
  ### PARAMETERS:
  ###    IN:  address (DWORD) - The physical address to where the low-level
  ###          functions will be relocated.  For debugging purposes, it is
  ###          ignored.
  ###    OUT:
  ###
  ### RETURNS:
  ###   HW_ERR_NONE.
  ###
 */

HW_ERROR FlashDevInit()
{
   HARDWARE_INITIALIZE;

   /* Required funtions */
   PtrLowLvlWrite       = (LLWRITE_FUNCPTR) LowLvlWrite;
   PtrLowLvlEraseBlock  = (LLERASE_FUNCPTR) LowLvlEraseBlock;
   PtrLowLvlReadStat    = (LLREADSTAT_FUNCPTR) LowLvlReadStat;
   PtrLowLvlClearStat   = (LLCLEARSTAT_FUNCPTR) LowLvlClearStat;

   /* Assign based on configuration */
#if (BLOCK_LOCK_SUPPORT == TRUE)
   PtrLowLvlLock        = (LLLOCK_FUNCPTR) LowLvlLock;
#endif /* BLOCK_LOCK_SUPPORT */

#if (ENABLE_PR != FDI_NONE)
   PtrLowLvlProtectReg  = (LLPR_FUNCPTR) LowLvlProtectReg;
#endif /* ENABLE_PR */

#if ((PACKET_DATA == TRUE) && (BUFFER_SIZE == 0))
   PtrLowLvlWritePacket = (LLWRITEPACKET_FUNCPTR) LowLvlWritePacket;
#endif /* (PACKET_DATA == TRUE) && (BUFFER_SIZE == 0) */

   return HW_ERR_NONE;
}
#endif /* RELOCATE_CODE */



/*#############################################################################
  ### FlashDevCompatCheck
  ###
  ### DESCRIPTION:
  ###   Verifies compatibility with flash support by the user application.
  ###   If the function determines that the component is incompatible, it
  ###   returns an error.
  ###
  ### PARAMETERS:
  ###    IN:  address (DWORD) - The absolute address of the window in flash
  ###          to scan.
  ###         size (DWORD) - The size of the window in flash to scan.
  ###    OUT:
  ###
  ### RETURNS:
  ###   If the flash type is supported, the function returns HW_ERR_NONE.  If
  ###   the flash type is not supported or if there was an error clearing
  ###   the status register, the function returns HW_ERR_COMPAT.
  ###
 */

HW_ERROR FlashDevCompatCheck(DWORD address, DWORD size)
{
   volatile FLASH_DATA_PTR flash_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(address);
   FLASH_DATA  status_reg;
   HW_ERROR    compat;
   DWORD       key0, key1;


   /*
    * Since a status command will be issued to the flash, find a location
    * where the ready bit(s) is (are) not set.
    */
   for (*flash_ptr = FLASH_COMMAND_READ; (DWORD) flash_ptr < (address + size);
         flash_ptr++)
   {
      if (*flash_ptr != FLASH_STATUS_READY)
      {
         break;
      }
   }

   /*
    * If our search took us to the end of the window, exit
    * with success.  This window will be checked in a future init,
    * when the flash has been formatted.
    */
   if ((DWORD) flash_ptr >= (address + size))
   {
      compat = HW_ERR_NONE;
   }

   /*
    * Clear the status and obtain it.  If not ready, a
    * major problem happened.  Exit with a failure.
    */
   else
   {
      DISABLE_INTERRUPTS(key0, key1);
      PtrLowLvlClearStat(flash_ptr);
      status_reg = PtrLowLvlReadStat(flash_ptr);
      ENABLE_INTERRUPTS(key0, key1);

      if (status_reg == FLASH_STATUS_READY)
      {
         compat = HW_ERR_NONE;
      }
      else
      {
         compat = HW_ERR_COMPAT;
      }
   }

   return compat;
}



#if (BUFFER_SIZE > 0)
/*#############################################################################
  ### FlashDevWrite
  ###
  ### DESCRIPTION:
  ###   This function writes 'size' bytes of data from a specified buffer to
  ###   the destination addresss within the device(s).  The Background Manager,
  ###   Reclaim Task, and Code Manager determine the relative address by
  ###   using the FDI mapping structures.  This function translates the
  ###   relative address into a physical system addres and verifies the
  ###   address range.  After aligning the source and destination buffers,
  ###   the function takes the flash write semaphore and calls the low-level
  ###   function LowLvlWrite() via its function pointer.  Upon completion
  ###   of the write, the function releases the flash write semaphore and
  ###   returns the appropriate value.
  ###
  ### PARAMETERS:
  ###    IN:  buffer_ptr (BYTE_PTR) - A pointer to the start address of the
  ###          data to be written.
  ###         address (DWORD) - The destination address within the flash
  ###          device(s).
  ###         size (DWORD) - The amount of data, in bytes, to write.
  ###
  ### RETURNS:
  ###   If any portion of the data being written does not fall within the
  ###   data managed area (or the code managed area if DAV is enabled), the
  ###   function returns HW_ERR_PARAM.  If an error occurred while writing
  ###   the data to flash, HW_ERR_WRITE is returned.  Finally, if all the
  ###   parameters are within the appropriate ranges and the data was
  ###   written successfully, the function returns HW_ERR_NONE.
  ###
 */

HW_ERROR FlashDevWrite(BYTE_PTR buffer_ptr, DWORD address, DWORD size)
{
   BYTE_PTR       dst_byte_ptr, src_byte_ptr;
   FLASH_DATA_PTR dst_data_ptr;
   FLASH_DATA     temp_buffer[BUFFER_SIZE / sizeof(FLASH_DATA)];

   DWORD dst_offset;
   DWORD byte_size, data_size;
   DWORD key0, key1;
   HW_ERROR status = HW_ERR_NONE;


   /* power loss simulation for testing purposes */
   mDEBUG_PLR_SIMULATION(size);

   /* address validation */
   address += LOWLVL_FLASH_START_ADDRESS;
   VALIDATE_ADDRESS(address, size);


   /* if size is 0, return */
   if (size == 0)
   {
      return HW_ERR_NONE;
   }


   /* align addresses & determine buffer offset */
   dst_data_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(address);
   dst_offset   = UNALIGNED_BYTES(address);
   dst_byte_ptr = (BYTE_PTR) temp_buffer + dst_offset;
   data_size    = BUFFER_SIZE - dst_offset;
   src_byte_ptr = buffer_ptr;


   /* take flash write mutex and perform hardware precondition */
   SEM_MTX_WAIT(SEM_FlashWrite);  
   HARDWARE_PRECONDITION;

   while ((size > 0) && (status == HW_ERR_NONE))
   {
      /**/
      byte_size = GET_MIN(data_size, size);
      data_size = (byte_size + dst_offset + sizeof(FLASH_DATA) - 1) /
                  sizeof(FLASH_DATA);

      /**/
      if (byte_size != BUFFER_SIZE)
      {

⌨️ 快捷键说明

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