📄 fdi_spll.c
字号:
### LowLvlEraseBlock() via its function pointer. Upon completion of the
### erase, the function releases the flash erase semaphore and returns
### the appropriate value.
###
### PARAMETERS:
### IN: address (DWORD) - The starting address of the block within
### flash to be erased.
### OUT:
###
### RETURNS:
### If the address being specified 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 erasing the block,
### the function returns HW_ERR_ERASE. Finally, if all parameters are
### within the appropriate ranges and the block was successfully erased,
### the function returns HW_ERR_NONE.
###
*/
HW_ERROR FlashDevEraseBlock(DWORD address)
{
FLASH_DATA_PTR flash_ptr;
DWORD key0, key1;
HW_ERROR status;
/* power loss simulation for testing purposes */
#if ( (TEST_PLR == BKGD_MLC) || (TEST_PLR == DAV_MLC) )
#else
mDEBUG_PLR_SIMULATION(0);
#endif /* TEST_PLR == BKGD_MLC or DAV_MLC */
/* Validate and align address */
address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(address, 0);
flash_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(address);
/* E5.3.875 START */
/*#if (DIRECT_ACCESS_VOLUME == TRUE)*/
/* take flash erase mutex */
SEM_MTX_WAIT(SEM_FlashErase);
/*#endif /DIRECT_ACCESS_VOLUME */
/* E5.3.875 END */
/* perform erase */
HARDWARE_PRECONDITION;
do
{
#if (TIME_MONITOR_ENABLED == TRUE)
TIME_MONITOR(key0, key1);
#else
DISABLE_INTERRUPTS(key0, key1);
#endif
status = PtrLowLvlEraseBlock(flash_ptr);
ENABLE_INTERRUPTS(key0, key1);
} while (status == HW_ERR_SUSPEND);
HARDWARE_POSTCONDITION;
/* E5.3.875 START */
/*#if (DIRECT_ACCESS_VOLUME == TRUE)*/
/* post flash erase mutex */
SEM_MTX_POST(SEM_FlashErase);
/*#endif DIRECT_ACCESS_VOLUME */
/* E5.3.875 END */
return status;
}
/* E5.0.480 START */
#if (BUFFER_SIZE > 0)
/*#############################################################################
### FlashDevCopy
###
### DESCRIPTION:
### This function is used to copy valid data during reclaim and during
### updates to copy data that is not changing. The Background Manager,
### Reclaim Task, and Code Manager determine the relative address by
### using the FDI mapping structures. This function reads and writes
### data by calling FlashDevRead() and FlashDevWrite().
###
### PARAMETERS:
### IN: dst_address (DWORD) - The starting address within flash to copy
### data to.
### src_address (DWORD) - The starting address within flash to read
### the data from.
### size (DWORD) - The amount of data, in bytes, to copy.
###
### RETURNS:
### If the source and destination buffers do not lie entirely within the
### data managed area (or code managed area if DAV is enabled), the
### function returns HW_ERR_PARAM. If an error occurred while writing
### to the flash hardware, the function returns HW_ERR_WRITE. Finally,
### if all parameters are within the appropriate ranges and the buffer
### was successfully copied, the funciton returns HW_ERR_NONE.
###
*/
HW_ERROR FlashDevCopy(DWORD dst_address, DWORD src_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 */
#if ( (TEST_PLR == BKGD_MLC) || (TEST_PLR == DAV_MLC) )
#else
mDEBUG_PLR_SIMULATION(size);
#endif /* TEST_PLR == BKGD_MLC or DAV_MLC */
/* address validation */
dst_address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(dst_address, size);
src_address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(src_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(dst_address);
dst_offset = UNALIGNED_BYTES(dst_address);
dst_byte_ptr = (BYTE_PTR) temp_buffer + dst_offset;
data_size = BUFFER_SIZE - dst_offset;
src_byte_ptr = (BYTE_PTR) src_address;
/* 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)
{
/*temp_buffer[0] = ALL_F;*/
/*temp_buffer[data_size] = ALL_F;*/
MemorySet((BYTE_PTR) temp_buffer, 0xff, BUFFER_SIZE);
}
MemoryMove(dst_byte_ptr, src_byte_ptr, (WORD) byte_size);
/* data_size = (byte_size + dst_offset + sizeof(FLASH_DATA) - 1) /
sizeof(FLASH_DATA); */
/* write buffer */
do
{
#if (TIME_MONITOR_ENABLED == TRUE)
TIME_MONITOR(key0, key1);
#else
DISABLE_INTERRUPTS(key0, key1);
#endif
status = PtrLowLvlWrite(dst_data_ptr, temp_buffer, data_size);
ENABLE_INTERRUPTS(key0, key1);
} while ((status == HW_ERR_SUSPEND) || (status == HW_ERR_ABORT));
/* update pointers/variables */
dst_data_ptr += data_size;
dst_byte_ptr = (BYTE_PTR) temp_buffer;
src_byte_ptr += byte_size;
size -= byte_size;
data_size = BUFFER_SIZE;
dst_offset = 0;
}
/* perform hardware postcondition, post flash write mutex, and return */
HARDWARE_POSTCONDITION;
SEM_MTX_POST(SEM_FlashWrite);
return status;
}
#else /* BUFFER_SIZE == 0 */
/*#############################################################################
### FlashDevCopy
###
### DESCRIPTION:
### This function is used to copy valid data during reclaim and during
### updates to copy data that is not changing. The Background Manager,
### Reclaim Task, and Code Manager determine the relative address by
### using the FDI mapping structures. This function reads and writes
### data by calling FlashDevRead() and FlashDevWrite().
###
### PARAMETERS:
### IN: dst_address (DWORD) - The starting address within flash to copy
### data to.
### src_address (DWORD) - The starting address within flash to read
### the data from.
### size (DWORD) - The amount of data, in bytes, to copy.
###
### RETURNS:
### If the source and destination buffers do not lie entirely within the
### data managed area (or code managed area if DAV is enabled), the
### function returns HW_ERR_PARAM. If an error occurred while writing
### to the flash hardware, the function returns HW_ERR_WRITE. Finally,
### if all parameters are within the appropriate ranges and the buffer
### was successfully copied, the funciton returns HW_ERR_NONE.
###
*/
HW_ERROR FlashDevCopy(DWORD dst_address, DWORD src_address, DWORD size)
{
FLASH_DATA_PTR src_data_ptr, dst_data_ptr;
BYTE_PTR src_byte_ptr, dst_byte_ptr;
DWORD src_offset, dst_offset;
DWORD init_unaligned_bytes;
DWORD key0, key1;
FLASH_DATA temp_data;
HW_ERROR status = HW_ERR_NONE;
/* power loss simulation for testing purposes */
#if ( (TEST_PLR == BKGD_MLC) || (TEST_PLR == DAV_MLC) )
#else
mDEBUG_PLR_SIMULATION(size);
#endif /* TEST_PLR == BKGD_MLC or DAV_MLC */
/* address validation */
dst_address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(dst_address, size);
src_address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(src_address, size);
/* return if nothing to write */
if (size == 0)
{
return HW_ERR_NONE;
}
/* align addresses & determine address offset */
dst_data_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(dst_address);
src_offset = UNALIGNED_BYTES(src_address);
dst_offset = UNALIGNED_BYTES(dst_address);
dst_byte_ptr = (BYTE_PTR) &temp_data + dst_offset;
/* calculate the number of initial unaligned bytes */
if (src_offset == dst_offset)
{
if (dst_offset == 0)
{
init_unaligned_bytes = 0;
}
else
{
init_unaligned_bytes = GET_MIN(size, sizeof(FLASH_DATA) - dst_offset);
}
}
else
{
init_unaligned_bytes = size;
}
size -= init_unaligned_bytes;
/* take flash write mutex and perform hardware precondition */
SEM_MTX_WAIT(SEM_FlashWrite);
HARDWARE_PRECONDITION;
/*
* write initial unaligned data, or all data if source and destination
* addresses do not have the same offset
*/
src_byte_ptr = (BYTE_PTR) src_address;
while ((init_unaligned_bytes > 0) && (status == HW_ERR_NONE))
{
/* fill temp buffer with data */
temp_data = ALL_F;
while ((dst_offset < sizeof(FLASH_DATA)) && (init_unaligned_bytes > 0))
{
*dst_byte_ptr = *src_byte_ptr;
dst_byte_ptr++;
src_byte_ptr++;
init_unaligned_bytes--;
dst_offset++;
}
/* write to flash */
do
{
#if (TIME_MONITOR_ENABLED == TRUE)
TIME_MONITOR(key0, key1);
#else
DISABLE_INTERRUPTS(key0, key1);
#endif
status = PtrLowLvlWrite(dst_data_ptr, &temp_data);
ENABLE_INTERRUPTS(key0, key1);
} while (status == HW_ERR_SUSPEND);
/* update pointers */
dst_data_ptr++;
dst_offset = 0;
dst_byte_ptr = (BYTE_PTR) &temp_data;
}
/* write aligned data */
src_data_ptr = (FLASH_DATA_PTR) src_byte_ptr;
while ((size >= sizeof(FLASH_DATA)) && (status == HW_ERR_NONE))
{
/* write to flash */
do
{
temp_data = *src_data_ptr;
#if (TIME_MONITOR_ENABLED == TRUE)
TIME_MONITOR(key0, key1);
#else
DISABLE_INTERRUPTS(key0, key1);
#endif
status = PtrLowLvlWrite(dst_data_ptr, &temp_data);
ENABLE_INTERRUPTS(key0, key1);
} while (status == HW_ERR_SUSPEND);
/* update pointers */
dst_data_ptr++;
src_data_ptr++;
size -= sizeof(FLASH_DATA);
}
/* write remaining unaligned bytes */
if ((size > 0) && (status == HW_ERR_NONE))
{
src_byte_ptr = (BYTE_PTR) src_data_ptr;
dst_byte_ptr = (BYTE_PTR) &temp_data;
temp_data = ALL_F;
/* fill temp buffer with data */
while (size > 0)
{
*dst_byte_ptr = *src_byte_ptr;
dst_byte_ptr++;
src_byte_ptr++;
size--;
}
/* write to flash */
do
{
#if (TIME_MONITOR_ENABLED == TRUE)
TIME_MONITOR(key0, key1);
#else
DISABLE_INTERRUPTS(key0, key1);
#endif
status = PtrLowLvlWrite(dst_data_ptr, &temp_data);
ENABLE_INTERRUPTS(key0, key1);
} while (status == HW_ERR_SUSPEND);
}
/* perform hardware postcondition, post flash write mutex, and return */
HARDWARE_POSTCONDITION;
SEM_MTX_POST(SEM_FlashWrite);
return status;
}
#endif /* BUFFER_SIZE */
/* E5.0.480 END */
/*#############################################################################
### FlashDevRead
###
### DESCRIPTION:
### Fills the specified buffer with the number of bytes defined by 'size'
### from the device's absolute physical address. The Background Manager,
### Reclaim Task, and Foreground Manager determine the relative address
### by using the FDI mapping structure. The FlashDevRead() function
### translates the relative address into a physical system address and
### verifies the address range. The function reads the data into the
### buffer and returns the appropriate value.
###
### PARAMETERS:
### IN: buffer_ptr (BYTE_PTR) - The buffer to use while reading data.
### address (DWORD) - The starting address within flash to read from.
### size (DWORD) - The amount of data, in bytes, to read.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -