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

📄 复件 zlg_ffs.c

📁 周立功ARM9 2410试验平台的uCOS-II基础实验代码
💻 C
📖 第 1 页 / 共 4 页
字号:
********************************************************************************************************/
        static uint8 BlockCopyBE(FFSDisk *Index, uint32 SourBlockIndex, uint32 DestBlockIndex)

{
    unsigned int i;
    uint32 temp2;
    const FlashDriver *Drive;
    uint8 *BufA;

    Drive = Index->Drive;
    BufA = Drive->BufA;

    FFSBlockErase(Index, SourBlockIndex);

    i = Drive->SecsPreBlock;
    temp2 = DestBlockIndex * i;
    do
    {
        Drive->ExSectorRead(Drive->Index, BufA, temp2);
        if (BufA[5] == 0x55)
        {
            BufA[5] = 0;
            if (Drive->ExSectorWrite(Drive->Index, BufA, temp2) != TRUE)
            {
                //FFSBlockErase(Index, DestBlockIndex);
                return FALSE;
            }

            if (Drive->ExSectorCheck(Drive->Index, BufA, temp2) != TRUE)
            {
                //FFSBlockErase(Index, DestBlockIndex);
                return FALSE;
            }
        }
        temp2++;
    } while (--i != 0);

    /* 块擦除 */
//    if (FFSBlockErase(Index, SourBlockIndex) != TRUE)
//    {
//        return FALSE;
//    }
    return TRUE;
}

/*********************************************************************************************************
** Function name: AddVBlock
** Descriptions:  增加逻辑块  add logistic block
** Input:Index:   底层驱动信息 low driver info
** Output: 0:     没有空闲块 no free block
**         other: 块索引 block index
** Created by: chenmingji
** Created Date: 2005-10-15
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        static uint32 AddVBlock(FFSDisk *Index)
{
#if 0
    uint32 BlockIndex, temp;

    BlockIndex = FildBlockA(Index);
    if (BlockIndex == 0)
    {
        goto err;
    }
    if (Index->BlockState[BlockIndex] == USR_BLOCK)         /* 此块已被使用 */
    {
        temp = FildBlockB(Index);                            /* 找空闲块  */
        if (temp == 0)
        {
            goto err;
        }
       
        /* 拷贝数据到空闲块  */
        if (BlockCopyA(Index, BlockIndex, temp) == FALSE)
        {
            goto err;
        }
    }
    return BlockIndex;
err:
    return 0;
#else
    return FildBlockB(Index);
#endif
}        

/*********************************************************************************************************
** Function name: SecWrite
** Descriptions:  写物理扇区 write physical sector
** Input:Index:   底层驱动信息 low driver info
**       SecIndex:写物理扇区索引 sector index
**       VBlockIndex:所在的逻辑块索引 logistic block index of the sector
**       BlockIndex:所在的物理块索引 physical block index of the sector
** Output: TRUE:  成功 OK
**         FALSE: 失败 NOT OK
**
** Created by: chenmingji
** Created Date: 2005-10-15
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        static uint8 SecWrite(FFSDisk *Index, uint8 *Buf, uint32 SecIndex, uint32 VBlockIndex, uint32 BlockIndex)
{
    uint8 *BufA;
    const FlashDriver *Drive;
    uint32 temp1;

    Drive = Index->Drive;
    BufA = Drive->BufA;
    
//    Drive->ExSectorRead(Drive->Index, BufA, SecIndex);

    /* 标明正在更改数据*/
    VBlockIndex++;
    BufA[0] = VBlockIndex & 0xff;
    BufA[1] = (VBlockIndex >> 8) & 0xff;
    BufA[2] = (VBlockIndex >> 16) & 0xff;
    BufA[3] = (VBlockIndex >> 24) & 0xff;
    BufA[5] = 0x55;
    if (Drive->ExSectorWrite(Drive->Index, BufA, SecIndex) != TRUE)
    {
        goto err;
    }
    if (Drive->ExSectorCheck(Drive->Index, BufA, SecIndex) != TRUE)
    {
        goto err;
    }

    /* 写数据*/

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

    /* 建立新的物理扇区与逻辑扇区的映射 */
    BufA[5] = 0;
    if (Drive->ExSectorWrite(Drive->Index, BufA, SecIndex) != TRUE)
    {
        goto err;
    }
    if (Drive->ExSectorCheck(Drive->Index, BufA, SecIndex) != TRUE)
    {
        goto err;
    }

    temp1 = BufA[10] | (BufA[11] << 8);
    temp1 = temp1  << 16;
    temp1 |= (BufA[8] | (BufA[9] << 8));

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

    return TRUE;
err:
    BufA[0] = 0;
    BufA[1] = 0;
    BufA[2] = 0;
    BufA[3] = 0;
    BufA[5] = 0;
    Drive->ExSectorWrite(Drive->Index, BufA, SecIndex);
    return FALSE;
}

/*********************************************************************************************************
** Function name: FFSDiskWrite
** Descriptions:  写逻辑扇区 write logistic sector
** Input:Index:   底层驱动信息 low driver info
**       Buf:     存储要要写到flash的数据的缓冲区  Data buf
**       SecIndex:逻辑扇区索引 logistic sector index    
** Output: TRUE:  成功 OK
**         FALSE: 失败 NOT OK
** Created by: chenmingji
** Created Date: 2005-10-15
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        static uint16 FFSDiskWrite(FFSDisk *Index, uint8 *Buf, uint32 SecIndex)
{
    uint32 BlockIndex, VBlockIndex;
    const FlashDriver *Drive;
    uint32 temp, temp1;
    unsigned int j, 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);
            if (BlockIndex == 0)
            {
                goto err;
            }
            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] == 0xff )
            {
                if (SecWrite(Index, Buf, temp1, VBlockIndex, BlockIndex) == FALSE)
                {
                    goto err;
                }
                return DISK_WRITE_OK;
            }
            else
            {
                FFSBlockErase(Index, BlockIndex);
            }
        }
        if (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] == 0xff )
            {
                if (SecWrite(Index, Buf, temp1, VBlockIndex, BlockIndex) == FALSE)
                {
                    goto err;
                }
            }
            else
            {
                /* 获取新块 */
                temp = AddVBlock(Index);
                if (temp == 0)
                {
                    goto err;
                }
                
                /* 块数据拷贝 */
                SecsPreBlock = Drive->SecsPreBlock;
                j = SecIndex % SecsPreBlock;                            /* 获得块内偏移     */
                if (BlockCopyB(Index, BlockIndex, temp, j) == FALSE)
                {
                    goto err;
                }

                temp1 = j + temp * Drive->SecsPreBlock;                 /* 获得物理扇区号   */
                Drive->ExSectorRead(Drive->Index, BufA, temp1);

                if (BufA[0] == 0xff &&                                  /* 如果可写,则直接写  */
                    BufA[1] == 0xff &&
                    BufA[2] == 0xff &&
                    BufA[3] == 0xff &&
                    BufA[4] == 'Z'  &&
                    BufA[5] == 0xff )
                {
                    if (SecWrite(Index, Buf, temp1, VBlockIndex, temp) == FALSE)
                    {
                        goto err;
                    }
                    if (BlockCopyBE(Index, BlockIndex, temp) == FALSE)
                    {
                        goto err;
                    }
                }
                else
                {
                    FFSBlockErase(Index, temp);
                    goto err;
                }
            }
            return DISK_WRITE_OK;
        }
    }
err:
    return DISK_WRITE_NOT_OK;
}

/*********************************************************************************************************
** Function name: ZLG_FFS
** Descriptions: 底层驱动程序与上层的接口程序
**
** Input: Cammand:DISK_INIT:驱动程序初始化
**                 DISK_CLOSE:关闭驱动器(移除驱动程序)                 
**                 DISK_READ_SECTOR:读扇区
**                 DISK_WRITE_SECTOR:写扇区
**                 DISK_FREE_SECTOR: 释放扇区    
**        Parameter:剩余参数
** Output: DISK_READ_OK:读扇区完成
**        DISK_READ_NOT_OK:读扇区失败
**        DISK_WRITE_OK:写扇区完成
**        DISK_WRITE_NOT_OK:写扇区失败
**        DISK_INIT_OK:初始化完成
**        DISK_INIT_NOT_OK:初始化失败
**        BAD_DISK_COMMAND:无效的命令
** Created by: chenmingji
** Created Date: 2005-10-15
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        uint16 ZLG_FFS(uint8 Cammand, void *Parameter)
{
    Disk_RW_Parameter * Dp;
    FFSDisk *Disk;
    unsigned int rt;
    uint32 temp;
    
    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:
            rt = FFSDiskWrite(Disk, Dp->Buf, Dp->SectorIndex);
            if (rt == DISK_WRITE_NOT_OK)
            {
                rt = FFSDiskWrite(Disk, Dp->Buf, Dp->SectorIndex);
                if (rt == 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);
            }
            FFSDiskClose(Disk);
            FFSDiskInit(Disk);
            rt = DISK_RETURN_OK;
            break;
        case DISK_FREE_SECTOR:
            FFSFreeSector(Disk, Dp->SectorIndex);
            rt = DISK_RETURN_OK;
            break;
        case DISK_GET_SECTOR_NUMBER:
            temp = (Disk->BlockSum) * (Disk->Drive->SecsPreBlock);
            temp = temp * 243;
            temp = temp >> 8;
            Dp->SectorIndex = temp;
            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 + -