📄 mappednandflash.c
字号:
return error;
}
return 0;
}
//------------------------------------------------------------------------------
/// Reads the data and/or spare area of a page in a mapped logical block.
/// Returns 0 if successful; otherwise, returns NandCommon_ERROR_BLOCKNOTMAPPED
/// if the block is not mapped, or a NandCommon_ERROR_xxx code.
/// \param mapped Pointer to a MappedNandFlash instance.
/// \param block Number of logical block to read page from.
/// \param page Number of page to read inside given block.
/// \param data Data area buffer, can be 0.
/// \param spare Spare area buffer, can be 0.
//------------------------------------------------------------------------------
unsigned char MappedNandFlash_ReadPage(
const struct MappedNandFlash *mapped,
unsigned short block,
unsigned short page,
void *data,
void *spare)
{
signed short physicalBlock;
trace_LOG(INFO, "MappedNandFlash_ReadPage(LB#%d:P#%d)\n\r", block, page);
// Check if block is mapped
physicalBlock = mapped->logicalMapping[block];
if (physicalBlock == -1) {
trace_LOG(trace_WARNING, "MappedNandFlash_ReadPage: Block must be mapped\n\r");
return NandCommon_ERROR_BLOCKNOTMAPPED;
}
// Read page from corresponding physical block
return ManagedNandFlash_ReadPage(MANAGED(mapped),
physicalBlock,
page,
data,
spare);
}
//------------------------------------------------------------------------------
/// Writes the data and/or spare area of a page in the given mapped logical
/// block.
/// Returns 0 if successful; otherwise, returns NandCommon_ERROR_BLOCKNOTMAPPED
/// (indicating the block is not logically mapped) or another NandCommon_ERROR
/// code.
/// \param mapped Pointer to a MappedNandFlash instance.
/// \param block Number of logical block to write on.
/// \param page Number of page to write inside given block.
/// \param data Data area buffer, can be 0.
/// \param spare Spare area buffer, can be 0.
//------------------------------------------------------------------------------
unsigned char MappedNandFlash_WritePage(
const struct MappedNandFlash *mapped,
unsigned short block,
unsigned short page,
void *data,
void *spare)
{
signed short physicalBlock;
trace_LOG(INFO, "MappedNandFlash_WritePage(LB#%d:P#%d)\n\r", block, page);
// Check if block is mapped
physicalBlock = mapped->logicalMapping[block];
if (physicalBlock == -1) {
trace_LOG(trace_ERROR, "MappedNandFlash_WritePage: Block must be mapped\n\r");
return NandCommon_ERROR_BLOCKNOTMAPPED;
}
// Write page on physical block
return ManagedNandFlash_WritePage(MANAGED(mapped),
physicalBlock,
page,
data,
spare);
}
//------------------------------------------------------------------------------
/// Maps a logical block number to an actual physical block. This allocates
/// the physical block (meaning it must be FREE), and releases the previous
/// block being replaced (if any).
/// Returns 0 if successful; otherwise returns a NandCommon_ERROR_xxx code.
/// \param mapped Pointer to a MappedNandFlash instance.
/// \param logicalBlock Logical block number to map.
/// \param physicalBlock Physical block to map to the logical one.
//------------------------------------------------------------------------------
unsigned char MappedNandFlash_Map(
struct MappedNandFlash *mapped,
unsigned short logicalBlock,
unsigned short physicalBlock)
{
unsigned char error;
signed short oldPhysicalBlock;
trace_LOG(INFO, "MappedNandFlash_Map(LB#%d -> PB#%d)\n\r",
logicalBlock, physicalBlock);
ASSERT(logicalBlock < NandFlashModel_GetDeviceSizeInBlocks(MODEL(mapped)),
"MappedNandFlash_Map: logicalBlock out-of-range\n\r");
ASSERT(physicalBlock < NandFlashModel_GetDeviceSizeInBlocks(MODEL(mapped)),
"MappedNandFlash_Map: physicalBlock out-of-range\n\r");
// Allocate physical block
error = ManagedNandFlash_AllocateBlock(MANAGED(mapped), physicalBlock);
if (error) {
return error;
}
// Release currently mapped block (if any)
oldPhysicalBlock = mapped->logicalMapping[logicalBlock];
if (oldPhysicalBlock != -1) {
error = ManagedNandFlash_ReleaseBlock(MANAGED(mapped), oldPhysicalBlock);
if (error) {
return error;
}
}
// Set mapping
mapped->logicalMapping[logicalBlock] = physicalBlock;
mapped->mappingModified = 1;
return 0;
}
//------------------------------------------------------------------------------
/// Unmaps a logical block by releasing the corresponding physical block (if
/// any).
/// Returns 0 if successful; otherwise returns a NandCommon_ERROR code.
/// \param mapped Pointer to a MappedNandFlash instance.
/// \param logicalBlock Number of logical block to unmap.
//------------------------------------------------------------------------------
unsigned char MappedNandFlash_Unmap(
struct MappedNandFlash *mapped,
unsigned short logicalBlock)
{
signed short physicalBlock = mapped->logicalMapping[logicalBlock];
unsigned char error;
trace_LOG(IMPORTANT, "MappedNandFlash_Unmap(LB#%d)\n\r", logicalBlock);
ASSERT(logicalBlock < NandFlashModel_GetDeviceSizeInBlocks(MODEL(mapped)),
"MappedNandFlash_Unmap: logicalBlock out-of-range\n\r");
if (physicalBlock != -1) {
error = ManagedNandFlash_ReleaseBlock(MANAGED(mapped), physicalBlock);
if (error) {
return error;
}
}
mapped->logicalMapping[logicalBlock] = -1;
mapped->mappingModified = 1;
return 0;
}
//------------------------------------------------------------------------------
/// Returns the physical block mapped with the given logical block, or -1 if it
/// is not mapped.
/// \param mapped Pointer to a MappedNandFlash instance.
/// \param logicalBlock Logical block number.
//------------------------------------------------------------------------------
signed short MappedNandFlash_LogicalToPhysical(
const struct MappedNandFlash *mapped,
unsigned short logicalBlock)
{
ASSERT(logicalBlock < NandFlashModel_GetDeviceSizeInBlocks(MODEL(mapped)),
"MappedNandFlash_LogicalToPhysical: logicalBlock out-of-range\n\r");
return mapped->logicalMapping[logicalBlock];
}
//------------------------------------------------------------------------------
/// Returns the logical block which is mapped to given physical block, or -1 if
/// the latter is not mapped.
/// \param mapped Pointer to a MappedNandFlash instance.
/// \param physicalBlock Physical block number.
//------------------------------------------------------------------------------
signed short MappedNandFlash_PhysicalToLogical(
const struct MappedNandFlash *mapped,
unsigned short physicalBlock)
{
unsigned short numBlocks = NandFlashModel_GetDeviceSizeInBlocks(MODEL(mapped));
signed short logicalBlock;
ASSERT(physicalBlock < NandFlashModel_GetDeviceSizeInBlocks(MODEL(mapped)),
"MappedNandFlash_PhysicalToLogical: physicalBlock out-of-range\n\r");
// Search the mapping for the desired physical block
for (logicalBlock=0; logicalBlock < numBlocks; logicalBlock++) {
if (mapped->logicalMapping[logicalBlock] == physicalBlock) {
return logicalBlock;
}
}
return -1;
}
//------------------------------------------------------------------------------
/// Saves the logical mapping on a FREE, unmapped physical block. Allocates the
/// new block, releases the previous one (if any) and save the mapping.
/// Returns 0 if successful; otherwise, returns NandCommon_ERROR_WRONGSTATUS
/// if the block is not LIVE, or a NandCommon_ERROR code.
/// \param mapped Pointer to a MappedNandFlash instance.
/// \param physicalBlock Physical block number.
//------------------------------------------------------------------------------
unsigned char MappedNandFlash_SaveLogicalMapping(
struct MappedNandFlash *mapped,
unsigned short physicalBlock)
{
unsigned char error;
unsigned char data[NandCommon_MAXPAGEDATASIZE];
unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(mapped));
unsigned short numBlocks = NandFlashModel_GetDeviceSizeInBlocks(MODEL(mapped));
unsigned int i;
unsigned int remainingSize;
unsigned char *currentBuffer;
unsigned short currentPage;
unsigned int writeSize;
signed short previousPhysicalBlock;
trace_LOG(INFO, "MappedNandFlash_SaveLogicalMapping(B#%d)\n\r", physicalBlock);
// If mapping has not been modified, do nothing
if (!mapped->mappingModified) {
return 0;
}
// Allocate new block
error = ManagedNandFlash_AllocateBlock(MANAGED(mapped), physicalBlock);
if (error) {
return error;
}
// Save mapping
previousPhysicalBlock = mapped->logicalMappingBlock;
mapped->logicalMappingBlock = physicalBlock;
// Save actual mapping in pages #1-#XXX
currentBuffer = (unsigned char *) mapped->logicalMapping;
remainingSize = sizeof(mapped->logicalMapping);
currentPage = 1;
while (remainingSize > 0) {
writeSize = min(remainingSize, pageDataSize);
memset(data, 0xFF, pageDataSize);
memcpy(data, currentBuffer, writeSize);
error = ManagedNandFlash_WritePage(MANAGED(mapped),
physicalBlock,
currentPage,
data,
0);
if (error) {
trace_LOG(trace_ERROR,
"MappedNandFlash_SaveLogicalMapping: Failed to write mapping\n\r");
return error;
}
currentBuffer += writeSize;
remainingSize -= writeSize;
currentPage++;
}
// Mark page #0 of block with a distinguishible pattern, so the mapping can
// be retrieved at startup
for (i=0; i < pageDataSize; i++) {
data[i] = PATTERN(i);
}
error = ManagedNandFlash_WritePage(MANAGED(mapped), physicalBlock, 0, data, 0);
if (error) {
trace_LOG(trace_ERROR,
"MappedNandFlash_SaveLogicalMapping: Failed to write pattern\n\r");
return error;
}
// Mapping is not modified anymore
mapped->mappingModified = 0;
// Release previous block (if any)
if (previousPhysicalBlock != -1) {
trace_LOG(DEBUG, "Previous physical block was #%d\n\r", previousPhysicalBlock);
error = ManagedNandFlash_ReleaseBlock(MANAGED(mapped),
previousPhysicalBlock);
if (error) {
return error;
}
}
trace_LOG(IMPORTANT, "Mapping saved on block #%d\n\r", physicalBlock);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -