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 + -
显示快捷键?