fdi_spll.c
来自「Flash file system」· C语言 代码 · 共 1,894 行 · 第 1/5 页
C
1,894 行
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 */
mDEBUG_PLR_SIMULATION(size);
/* 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; */ /* commented by jjs - replaced with the following two IFs*/
if(dst_offset != 0) /* added by jjs */
{
MemoryMove((BYTE_PTR)(&temp_data), (BYTE_PTR)dst_data_ptr, dst_offset);
}
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++;
}
if(dst_offset < sizeof(FLASH_DATA)) /* added by jjs */
{
MemoryMove((BYTE_PTR)dst_byte_ptr,
((BYTE_PTR)dst_data_ptr) + dst_offset,
sizeof(FLASH_DATA) - 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; */ /* commented by jjs */
MemoryMove((BYTE_PTR)dst_byte_ptr + size,
((BYTE_PTR)dst_data_ptr) + size,
sizeof(FLASH_DATA) - size); /* added by jjs */
/* 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.
### OUT: buffer_ptr - Contains the contents read.
###
### RETURNS:
### If the entire source buffer does not lie within the data managed area
### (or code managed area if DAV is enabled), the function returns
### HW_ERR_PARAM. Otherwise, the function returns HW_ERR_NONE.
###
*/
HW_ERROR FlashDevRead(BYTE_PTR buffer_ptr, DWORD address, DWORD size)
{
BYTE_PTR src_byte_ptr, dst_byte_ptr;
FLASH_DATA_PTR src_data_ptr, dst_data_ptr;
DWORD src_offset, dst_offset;
/* validate address */
address += LOWLVL_FLASH_START_ADDRESS;
VALIDATE_ADDRESS(address, size);
/* return if nothing to read */
if (size == 0)
{
return HW_ERR_NONE;
}
/* determine address offsets */
src_offset = UNALIGNED_BYTES(address);
dst_offset = UNALIGNED_BYTES((DWORD) buffer_ptr);
src_byte_ptr = (BYTE_PTR) address;
dst_byte_ptr = buffer_ptr;
/*
* determine if source and destination addresses allow the reading on
* aligned addresses
*/
if ((src_offset == dst_offset) && (size > sizeof(FLASH_DATA)))
{
/* read initial unaligned bytes */
if (src_offset != 0)
{
while (src_offset < sizeof(FLASH_DATA))
{
*dst_byte_ptr = *src_byte_ptr;
dst_byte_ptr++;
src_byte_ptr++;
size--;
src_offset++;
}
}
/* read aligned data */
dst_data_ptr = (FLASH_DATA_PTR) dst_byte_ptr;
src_data_ptr = (FLASH_DATA_PTR) src_byte_ptr;
while (size >= sizeof(FLASH_DATA))
{
*dst_data_ptr = *src_data_ptr;
dst_data_ptr++;
src_data_ptr++;
size -= sizeof(FLASH_DATA);
}
/* read remaining unaligned bytes */
if (size > 0)
{
dst_byte_ptr = (BYTE_PTR) dst_data_ptr;
src_byte_ptr = (BYTE_PTR) src_data_ptr;
while (size > 0)
{
*dst_byte_ptr = *src_byte_ptr;
dst_byte_ptr++;
src_byte_ptr++;
size--;
}
}
}
/*
* source and destination addresses do not allow the reading on aligned
* addresses; therefore, a byte-by-byte copy needs to be done
*/
else
{
while (size > 0)
{
*dst_byte_ptr = *src_byte_ptr;
dst_byte_ptr++;
src_byte_ptr++;
size--;
}
}
return HW_ERR_NONE;
}
#if (CONSISTENT_ACCESS_TIME == TRUE)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?