Пример #1
0
//------------------------------------------------------------------------------
/// Copies the data from a whole block to another block on a nandflash. Both
/// blocks must be LIVE.
/// Returns 0 if successful; otherwise returns NandCommon_ERROR_WRONGSTATUS if
/// at least one of the blocks is not free, or a NandCommon_ERROR_xxx code.
/// \param managed  Pointer to a ManagedNandFlash instance.
/// \param sourceBlock  Source block number.
/// \param destBlock  Destination block number.
//------------------------------------------------------------------------------
unsigned char ManagedNandFlash_CopyBlock(
    const struct ManagedNandFlash *managed,
    unsigned short sourceBlock,
    unsigned short destBlock)
{
    unsigned short numPages = NandFlashModel_GetBlockSizeInPages(MODEL(managed));
    unsigned char error;
    unsigned short page;

    ASSERT(sourceBlock != destBlock,
           "ManagedNandFlash_CopyBlock: Source block must be different from dest. block\n\r");

    TRACE_INFO("ManagedNandFlash_CopyBlock(B#%d->B#%d)\n\r",
              sourceBlock, destBlock);

    // Copy all pages
    for (page=0; page < numPages; page++) {

        error = ManagedNandFlash_CopyPage(managed,
                                          sourceBlock,
                                          page,
                                          destBlock,
                                          page);
        if (error) {

            TRACE_ERROR("ManagedNandFlash_CopyPage: Failed to copy page %d\n\r", page);
            return error;
        }
    }

    return 0;
}
/**
 * \brief  Terminates the current write operation by copying all the missing pages from
 * the previous physical block.
 *
 * \param translated  Pointer to a TranslatedNandFlash instance.
 * \return 0 if successful; otherwise returns error code
 */
unsigned char TranslatedNandFlash_Flush(struct TranslatedNandFlash *translated)
{
    unsigned int i;
    unsigned char error;
    unsigned int currentPhysicalBlock;

    /* Check if there is a current block and a previous block*/
    if ((translated->currentLogicalBlock == -1)
        || (translated->previousPhysicalBlock == -1))
    {
        return 0;
    }

    TRACE_INFO("TranslatedNandFlash_Flush(PB#%d -> LB#%d)\n\r",
              translated->previousPhysicalBlock, translated->currentLogicalBlock);

    /* Copy missing pages in the current block*/
    currentPhysicalBlock = MappedNandFlash_LogicalToPhysical(
                                MAPPED(translated),
                                translated->currentLogicalBlock);

    for (i=0; i < NandFlashModel_GetBlockSizeInPages(MODEL(translated)); i++)
    {
        if (PageIsClean(translated, i))
        {
            TRACE_DEBUG("Copying back page #%d of block #%d\n\r", i, translated->previousPhysicalBlock);

            /* Copy page*/
            error = ManagedNandFlash_CopyPage(MANAGED(translated),
                                              translated->previousPhysicalBlock,
                                              i,
                                              currentPhysicalBlock,
                                              i);
            if (error)
            {
                TRACE_ERROR("FinishCurrentWrite: copy page #%d\n\r", i);
                return error;
            }
        }
    }

    translated->currentLogicalBlock = -1;
    translated->previousPhysicalBlock = -1;
    return 0;
}