fdi_mpll.c
来自「FDI Intel开发的FLASH文件系统,功能很强大」· C语言 代码 · 共 1,983 行 · 第 1/5 页
C
1,983 行
{
/* determine the size of the buffer */
size_to_write = GET_MIN(size, BUFFER_SIZE / sizeof(FLASH_DATA));
buffer_size = BUFFER_SIZE_TO_WRITE(size_to_write);
/* wait until buffer is ready */
DISABLE_INTERRUPTS(key0, key1);
UNLOCK_BLOCK(flash_ptr);
do
{
*flash_ptr = FLASH_COMMAND_WRITE_BUFFER;
} while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY);
/* send size of data and fill buffer */
*flash_ptr = buffer_size;
for (i = 0; i < size_to_write; i++)
{
*flash_ptr = *ram_ptr;
flash_ptr++;
ram_ptr++;
}
/* make sure pointer is in the same block and commit buffer */
flash_ptr--;
*flash_ptr = FLASH_COMMAND_CONFIRM;
/*E.5.4.940 START*/
/*mDEBUG_RESET_WRITE();*/
/*E.5.4.940 END*/
ENABLE_INTERRUPTS(key0, key1);
/* decrement size */
size -= size_to_write;
}
/* wait until flash is done */
while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
}
/* Lock the block */
#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
DISABLE_INTERRUPTS(key0, key1);
LOCK_BLOCK(flash_ptr);
ENABLE_INTERRUPTS(key0, key1);
#endif
/* check for errors */
if (*flash_ptr & FLASH_STATUS_ERROR)
{
*flash_ptr = FLASH_COMMAND_CLEAR;
status = HW_ERR_WRITE;
break;
}
/*
* if a write is allowed to span blocks, uncomment the following
* line of code to guarantee that the data, not status, will be read
* on future reads
*/
/* *flash_ptr = FLASH_COMMAND_READ; */
/* increment flash pointer */
flash_ptr++;
}
return status;
}
#else /* BUFFER_SIZE == 0 */
/*#############################################################################
### WriteToFlash (Non-Buffered Version)
###
### DESCRIPTION:
### Writes data to flash and performs error checking before returning.
###
### PARAMETERS:
### IN: dst_ptr (FLASH_DATA_PTR) - A pointer to the data destination.
### src_ptr (FLASH_DATA_PTR) - A pointer to the data source.
### size (DWORD) - The number of FLASH_DATA units to write.
### OUT:
###
### RETURNS:
### If any portion of the data is not written successfully, the function
### returns HW_ERR_WRITE; otherwise, the function returns HW_ERR_NONE.
###
*/
/* E.5.0.652 Begin */
static HW_ERROR WriteToFlash(volatile FLASH_DATA *flash_ptr,
FLASH_DATA *ram_ptr,
DWORD size)
/* E.5.0.652 End */
{
DWORD key0, key1;
HW_ERROR status = HW_ERR_NONE;
while (size > 0)
{
/* program flash */
DISABLE_INTERRUPTS(key0, key1);
UNLOCK_BLOCK(flash_ptr);
*flash_ptr = FLASH_COMMAND_WRITE;
*flash_ptr = *ram_ptr;
/*E.5.4.940 START*/
/*mDEBUG_RESET_WRITE();*/
/*E.5.4.940 END*/
ENABLE_INTERRUPTS(key0, key1);
/* wait until flash is done */
while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
}
/* lock the block */
#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
DISABLE_INTERRUPTS(key0, key1);
LOCK_BLOCK(flash_ptr);
ENABLE_INTERRUPTS(key0, key1);
#endif
/* check for errors */
if (*flash_ptr & FLASH_STATUS_ERROR)
{
*flash_ptr = FLASH_COMMAND_CLEAR;
status = HW_ERR_WRITE;
break;
}
/*
* if a write is allowed to span blocks, uncomment the following
* line of code to guarantee that the data, not status, will be read
* on future reads
*/
/* *flash_ptr = FLASH_COMMAND_READ; */
/* update pointers */
flash_ptr++;
ram_ptr++;
size--;
}
return status;
}
#endif /* BUFFER_SIZE */
/*### Global Declarations
*######################### */
/*### Global Functions
*######################### */
#if (RELOCATE_CODE == TRUE)
/*#############################################################################
### FlashDevInit (Relocate 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)
{
#if (((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_NONFDI_BLOCKLOCKING == TRUE)) \
|| (ENABLE_PR != FDI_NONE))
BYTE_PTR dst_ptr = (BYTE_PTR) address;
BYTE_PTR src_ptr;
WORD size;
#endif /* OPTIONAL_FEATURES */
HARDWARE_INITIALIZE;
/*E5.0.733 Start */
CurrentFlashState =
SET_PARTITION_STATE(LOWLVL_DATA_START_ADDRESS, HW_STATE_READ);
/*E5.0.733 End */
/* Relocated functions based on configuration */
#if (((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_NONFDI_BLOCKLOCKING == TRUE)) \
|| (ENABLE_PR != FDI_NONE))
src_ptr = (BYTE_PTR) LowLvlReadStat;
size = (WORD) ((DWORD) LowLvlEnd - (DWORD) LowLvlReadStat);
MemoryMove(dst_ptr, src_ptr, size);
PtrLowLvlReadStat = (LLREADSTAT_FUNCPTR) (address);
#if (BLOCK_LOCK_SUPPORT == TRUE)
PtrLowLvlLock = (LLLOCK_FUNCPTR) (address +
((DWORD) LowLvlLock - (DWORD) LowLvlReadStat));
#endif /* BLOCK_LOCK_SUPPORT */
#if (ENABLE_PR != FDI_NONE)
PtrLowLvlProtectReg = (LLPR_FUNCPTR) (address +
((DWORD) LowLvlProtectReg - (DWORD) LowLvlReadStat));
#endif /* ENABLE_PR */
#elif (BLOCK_LOCK_SUPPORT == TRUE)
PtrLowLvlLock = (LLLOCK_FUNCPTR) LowLvlLock;
#endif /* OPTIONAL_FEATURES */
return HW_ERR_NONE;
}
#else /* RELOCATE_CODE != TRUE */
/*#############################################################################
### FlashDevInit (Non-Relocate 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;
/*E5.0.733 Start */
CurrentFlashState =
SET_PARTITION_STATE(LOWLVL_DATA_START_ADDRESS, HW_STATE_READ);
/*E5.0.733 End */
/* Assign based on configuration */
#if (((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_NONFDI_BLOCKLOCKING == TRUE)) \
|| (ENABLE_PR != FDI_NONE))
PtrLowLvlReadStat = (LLREADSTAT_FUNCPTR) LowLvlReadStat;
#endif /* (BLOCK_LOCK_SUPPORT && ENABLE_NONFDI_BLOCKLOCKING) || ENABLE_PR */
#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 */
return HW_ERR_NONE;
}
#endif /* DEBUG_LOWLVL */
/*#############################################################################
### 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.
### 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;
/* look for the first value that is not FLASH_STATUS_READY */
for (*flash_ptr = FLASH_COMMAND_READ; (DWORD) flash_ptr < (address + size);
flash_ptr++)
{
if (*flash_ptr != FLASH_STATUS_READY)
{
break;
}
}
/* if at or past end of window, no compatibility issue */
if ((DWORD) flash_ptr >= (address + size))
{
compat = HW_ERR_NONE;
}
/* otherwise, clear status register and check value */
else
{
*flash_ptr = FLASH_COMMAND_CLEAR;
*flash_ptr = FLASH_COMMAND_STATUS;
status_reg = *flash_ptr;
*flash_ptr = FLASH_COMMAND_READ;
if (status_reg == FLASH_STATUS_READY)
{
compat = HW_ERR_NONE;
}
else
{
compat = HW_ERR_COMPAT;
}
}
return compat;
}
/*#############################################################################
### 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;
/* E5.1.769 START */
volatile FLASH_DATA_PTR dst_data_ptr;
/* E5.1.769 END */
FLASH_DATA temp_buffer[COPY_BUFFER_SIZE / sizeof(FLASH_DATA)];
DWORD dst_offset;
DWORD byte_size, data_size;
HW_ERROR status = HW_ERR_NONE;
DWORD preempted_state;
BYTE suspended = (BYTE) FALSE;
/* 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;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?