📄 zlg_ffs.new.c
字号:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
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)
{
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;
}
/*********************************************************************************************************
** 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
{
if (FFSBlockErase(Index, BlockIndex) != TRUE)
{
goto err;
}
}
}
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 + -