⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mappednandflash.c

📁 at91sam9263操作NAND FLASH代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -