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

📄 zlg_ffs.c

📁 zlg nand flash 写平衡 在LINUX XIA
💻 C
📖 第 1 页 / 共 3 页
字号:
                if (BufA[4] != 'Z')
                {
                    goto err1;
                }
                if (BufA[5] == 0)
                {
                    goto err1;
                }
                BufA[0] = C[0];
                BufA[1] = C[1];
                BufA[2] = C[2];
                BufA[3] = C[3];
                BufA[5] = 0;
                if (Drive->ExSectorWrite(Drive->Index, BufA, temp2) != TRUE)
                {
                    FFSSetBadBlock(Index, temp);
                    goto err;
                }

                if (Drive->ExSectorCheck(Drive->Index, BufA, temp2) != TRUE)
                {
                    FFSSetBadBlock(Index, temp);
                    goto err;
                }

                //if (Drive->SecCopy(Drive->Index, temp1, temp2) != TRUE)
                //{
                //    FFSSetBadBlock(Index, temp);
                //    goto err;
                //}
                Drive->SectorRead(Drive->Index, BufA, temp1);
                if (Drive->SectorWrite(Drive->Index, BufA, temp2) != TRUE)
                {
                    FFSSetBadBlock(Index, temp);
                    goto err;
                }
                if (Drive->SectorCheck(Drive->Index, BufA, temp2) != TRUE)
                {
                    FFSSetBadBlock(Index, temp);
                    goto err;
                }
            }
            temp1++;
            temp2++;
        } while (--k != 0);

        k = C[2] | (C[3] << 8);
        k = k  << 16;
        k |= (C[0] | (C[1] << 8));
            
        Index->VBlockInfo[k - 1] = temp;
        Index->BlockState[temp] = USR_BLOCK;
        Index->BlockEaseSum[temp] += USR_BLOCK_ADD;
                    
        /* 块擦除 */
        if (FFSBlockErase(Index, BlockIndex) != TRUE)
        {
            FFSSetBadBlock(Index, BlockIndex);
            goto err;
        }
    }
    return BlockIndex;
err1:
    if (FFSBlockErase(Index, BlockIndex) != TRUE)
    {
        FFSSetBadBlock(Index, BlockIndex);
    }
err:
    return 0;
}        

/*********************************************************************************************************
        写扇区
*********************************************************************************************************/
        static uint16 FFSDiskWrite(FFSDisk *Index, uint8 *Buf, uint32 SecIndex)
{
    uint32 BlockIndex, VBlockIndex;
    const FlashDriver *Drive;
    uint32 temp, temp1, temp2;
    unsigned int j, k, SecsPreBlock;
    uint8 *BufA;
    
    Drive = Index->Drive;
    
    VBlockIndex = SecIndex / Drive->SecsPreBlock;
    if (Index != NULL)
    if (Drive != NULL)
    if (VBlockIndex < Index->BlockSum)
    {
        BlockIndex = Index->VBlockInfo[VBlockIndex];                    /* 获得物理块号     */
        if (BlockIndex == 0)
        {
            BlockIndex = AddVBlock(Index);
            Index->BlockEaseSum[BlockIndex] += USR_BLOCK_ADD;
        }
        if (BlockIndex != 0 && BlockIndex < Drive->BlockPreDisk)
        {
            temp1 = SecIndex % Drive->SecsPreBlock;                 /* 获得块内偏移     */
            temp1 = temp1 + BlockIndex * Drive->SecsPreBlock;       /* 获得物理扇区号   */
            BufA = Drive->BufA;
            Drive->ExSectorRead(Drive->Index, BufA, temp1);
            if (BufA[0] == 0xff &&                                  /* 如果可写,则直接写  */
                BufA[1] == 0xff &&
                BufA[2] == 0xff &&
                BufA[3] == 0xff &&
                BufA[4] == 'Z'  &&
                BufA[5] != 0x00 )
            {
                VBlockIndex++;
                BufA[0] = VBlockIndex & 0xff;
                BufA[1] = (VBlockIndex >> 8) & 0xff;
                BufA[2] = (VBlockIndex >> 16) & 0xff;
                BufA[3] = (VBlockIndex >> 24) & 0xff;
                BufA[5] = 0;
                if (Drive->ExSectorWrite(Drive->Index, BufA, temp1) != TRUE)
                {
                    FFSSetBadBlock(Index, BlockIndex);
                    goto err;
                }
                if (Drive->ExSectorCheck(Drive->Index, BufA, temp1) != TRUE)
                {
                    FFSSetBadBlock(Index, BlockIndex);
                    goto err;
                }
                if (Drive->SectorWrite(Drive->Index, Buf, temp1) != TRUE)
                {
                    FFSSetBadBlock(Index, BlockIndex);
                    goto err;
                }
                if (Drive->SectorCheck(Drive->Index, Buf, temp1) != TRUE)
                {
                    FFSSetBadBlock(Index, BlockIndex);
                    goto err;
                }
                Index->VBlockInfo[VBlockIndex - 1] = BlockIndex;
                Index->BlockState[BlockIndex] = USR_BLOCK;
            }
            else
            {
                /* 获取新块 */
                temp = AddVBlock(Index);
                if (temp == 0)
                {
                    goto err;
                }
                
                /* 块拷贝 */
                SecsPreBlock = Drive->SecsPreBlock;
                temp1 = BlockIndex * SecsPreBlock;
                temp2 = temp * SecsPreBlock;
                j = SecIndex % SecsPreBlock;                    /* 获得块内偏移     */
                VBlockIndex++;
                for (k = 0; k < SecsPreBlock; k++)
                {
                    if (k == j)
                    {
                        temp1++;
                        temp2++;
                        continue;
                    }
                    Drive->ExSectorRead(Drive->Index, BufA, temp1);
                    if (BufA[5] == 0)
                    {
                        Drive->ExSectorRead(Drive->Index, BufA, temp2);
                        if (BufA[0] != 0xff)
                        {
                            goto err1;
                        }
                        if (BufA[1] != 0xff)
                        {
                            goto err1;
                        }
                        if (BufA[2] != 0xff)
                        {
                            goto err1;
                        }
                        if (BufA[3] != 0xff)
                        {
                            goto err1;
                        }
                        if (BufA[4] != 'Z')
                        {
                            goto err1;
                        }
                        if (BufA[5] == 0)
                        {
                            goto err1;
                        }
                        BufA[0] = VBlockIndex & 0xff;
                        BufA[1] = (VBlockIndex >> 8) & 0xff;
                        BufA[2] = (VBlockIndex >> 16) & 0xff;
                        BufA[3] = (VBlockIndex >> 24) & 0xff;
                        BufA[5] = 0;
                        if (Drive->ExSectorWrite(Drive->Index, BufA, temp2) != TRUE)
                        {
                            FFSSetBadBlock(Index, temp);
                            goto err;
                        }

                        if (Drive->ExSectorCheck(Drive->Index, BufA, temp2) != TRUE)
                        {
                            FFSSetBadBlock(Index, temp);
                            goto err;
                        }
                    
                        //if (Drive->SecCopy(Drive->Index, temp1, temp2) != TRUE)
                        //{
                        //    FFSSetBadBlock(Index, temp);
                        //    goto err;
                        //}
                        Drive->SectorRead(Drive->Index, BufA, temp1);
                        if (Drive->SectorWrite(Drive->Index, BufA, temp2) != TRUE)
                        {
                            FFSSetBadBlock(Index, temp);
                            goto err;
                        }
                        if (Drive->SectorCheck(Drive->Index, BufA, temp2) != TRUE)
                        {
                            FFSSetBadBlock(Index, temp);
                            goto err;
                        }
                    }
                    temp1++;
                    temp2++;
                }

                /* 写新块 */
                temp1 = j + temp * SecsPreBlock;             /* 获得物理扇区号   */
                BufA = Drive->BufA;
                Drive->ExSectorRead(Drive->Index, BufA, temp1);
                if (BufA[0] != 0xff)
                {
                    goto err1;
                }
                if (BufA[1] != 0xff)
                {
                    goto err1;
                }
                if (BufA[2] != 0xff)
                {
                    goto err1;
                }
                if (BufA[3] != 0xff)
                {
                    goto err1;
                }
                if (BufA[4] != 'Z')
                {
                    goto err1;
                }
                if (BufA[5] == 0)
                {
                    goto err1;
                }
                BufA[0] = VBlockIndex & 0xff;
                BufA[1] = (VBlockIndex >> 8) & 0xff;
                BufA[2] = (VBlockIndex >> 16) & 0xff;
                BufA[3] = (VBlockIndex >> 24) & 0xff;
                BufA[5] = 0;
                if (Drive->ExSectorWrite(Drive->Index, BufA, temp1) != TRUE)
                {
                    FFSSetBadBlock(Index, temp);
                    goto err;
                }
                if (Drive->ExSectorCheck(Drive->Index, BufA, temp1) != TRUE)
                {
                    FFSSetBadBlock(Index, temp);
                    goto err;
                }

                if (Drive->SectorWrite(Drive->Index, Buf, temp1) != TRUE)
                {
                    FFSSetBadBlock(Index, temp);
                    goto err;
                }
                if (Drive->SectorCheck(Drive->Index, Buf, temp1) != TRUE)
                {
                    FFSSetBadBlock(Index, temp);
                    goto err;
                }

                Index->VBlockInfo[VBlockIndex - 1] = temp;
                Index->BlockEaseSum[temp] += USR_BLOCK_ADD;
                Index->BlockState[temp] = USR_BLOCK;

                /* 块擦除 */
                if (FFSBlockErase(Index, BlockIndex) != TRUE)
                {
                    FFSSetBadBlock(Index, BlockIndex);
                }
            }
            return DISK_WRITE_OK;
        }
    }
err1:
    if (FFSBlockErase(Index, temp) != TRUE)
    {
        FFSSetBadBlock(Index, temp);
    }
err:
    return DISK_WRITE_NOT_OK;
}

/*********************************************************************************************************
** 函数名称: ZLG_FFS
** 功能描述: 底层驱动程序与上层的接口程序
**
** 输 入: Cammand:DISK_INIT:驱动程序初始化
**                 DISK_CLOSE:关闭驱动器(移除驱动程序)                 
**                 DISK_READ_SECTOR:读扇区
**                 DISK_WRITE_SECTOR:写扇区
**                 DISK_FREE_SECTOR: 释放扇区    
**        Parameter:剩余参数
** 输 出: DISK_READ_OK:读扇区完成
**        DISK_READ_NOT_OK:读扇区失败
**        DISK_WRITE_OK:写扇区完成
**        DISK_WRITE_NOT_OK:写扇区失败
**        DISK_INIT_OK:初始化完成
**        DISK_INIT_NOT_OK:初始化失败
**        BAD_DISK_COMMAND:无效的命令
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2003年9月3日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        uint16 ZLG_FFS(uint8 Cammand, void *Parameter)
{
    uint16 rt;
    Disk_RW_Parameter * Dp;
    FFSDisk *Disk;
    
    Dp = (Disk_RW_Parameter *)Parameter;
    Disk = (FFSDisk *) Dp->RsvdForLow;
    
    OS_ENTER_CRITICAL();
    switch (Cammand)
    {
        case DISK_INIT:
            rt = FFSDiskInit(Disk);
            break;
        case DISK_CLOSE:
            rt = FFSDiskClose(Disk);
            break;
        case DISK_READ_SECTOR:
            rt = FFSDiskRead(Disk, Dp->Buf, Dp->SectorIndex);
            break;
        case DISK_WRITE_SECTOR:
            if ((rt = FFSDiskWrite(Disk, Dp->Buf, Dp->SectorIndex)) == DISK_WRITE_NOT_OK)
            {
                if ((rt = FFSDiskWrite(Disk, Dp->Buf, Dp->SectorIndex)) == DISK_WRITE_NOT_OK)
                {
                    rt = FFSDiskWrite(Disk, Dp->Buf, Dp->SectorIndex);
                }
            }
            break;
        case DISK_DRIVER_VER:
            Dp->SectorIndex = 110;
            rt = DISK_RETURN_OK;
            break;
        case DISK_CHECK_CMD:
            rt = DISK_FALSE;
            if ((Dp->SectorIndex == DISK_INIT)
               || (Dp->SectorIndex == DISK_CLOSE)
               || (Dp->SectorIndex == DISK_READ_SECTOR)
               || (Dp->SectorIndex == DISK_WRITE_SECTOR)
               || (Dp->SectorIndex == DISK_DRIVER_VER)
               || (Dp->SectorIndex == DISK_CHECK_CMD)
               || (Dp->SectorIndex == DISK_LOW_FORMAT)
               || (Dp->SectorIndex == DISK_FREE_SECTOR)
               || (Dp->SectorIndex == DISK_GET_SECTOR_NUMBER)
               || (Dp->SectorIndex == DISK_GET_BYTES_PER_SECTOR)
               || (Dp->SectorIndex == DISK_CHECK_CHANGE)
               )
            {
                rt = DISK_TRUE;
            }
            break;
        case DISK_LOW_FORMAT:
            if (Dp->SectorIndex == 0)
            {
                NFFormat(Disk);
            }
            else
            {
                NFFormatA(Disk);
            }
            rt = DISK_RETURN_OK;
            break;
        case DISK_FREE_SECTOR:
            FFSFreeSector(Disk, Dp->SectorIndex);
            rt = DISK_RETURN_OK;
            break;
        case DISK_GET_SECTOR_NUMBER:
            Dp->SectorIndex = (Disk->BlockSum) * (Disk->Drive->SecsPreBlock);
            rt = DISK_RETURN_OK;
            break;
        case DISK_GET_BYTES_PER_SECTOR:
            Dp->SectorIndex = Disk->Drive->BytsPerSec;
            rt = DISK_RETURN_OK;
            break;
        case DISK_CHECK_CHANGE:
            rt = DISK_FALSE;
        case DISK_GET_SECTORS_PER_BLOCK:
            rt = BAD_DISK_COMMAND;
            break;
        case DISK_READ_BLOCK:
            rt = BAD_DISK_COMMAND;
            break;
        case DISK_WRITE_BLOCK:
            rt = BAD_DISK_COMMAND;
            break;
        default:
            rt = BAD_DISK_COMMAND;
            break;
    }
    OS_EXIT_CRITICAL();
    return rt;
}

/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -