📄 zlg_ffs.c
字号:
bufa = malloc(i * sizeof(uint8));
if (bufa == NULL)
{
return DISK_INIT_NOT_OK;
}
Index->BlockState = bufa;
/* 初始化内存空间 */
do
{
*bufa++ = BAD_BLOCK;
} while (--i != 0);
/* 获取必须的内存空间 */
i = Drive->BlockPreDisk;
VBlockInfo = malloc(i * sizeof(uint32));
if (VBlockInfo == NULL)
{
free(Index->BlockState);
Index->BlockState = NULL;
return DISK_INIT_NOT_OK;
}
Index->BlockEaseSum = VBlockInfo;
/* 初始化内存空间 */
do
{
*VBlockInfo++ = ~1;
} while (--i != 0);
/* 获得有效块数 */
bufa = Drive->BufA;
j = Drive->BlockPreDisk;
i = 0;
k = 0;
temp = 0;
BytsPerSec = Drive->BytsPerSec;
Drive->SectorRead(Drive->Index, bufa, 0);
do
{
if ((bufa[(i / 8) % BytsPerSec] & (1 << (i % 8))) != 0)
{
temp++;
}
i++;
if ((i % (BytsPerSec * 8)) == 0)
{
k++;
Drive->ExSectorRead(Index, bufa, k);
}
} while (--j != 0) ;
if (temp <= 1)
{
return DISK_INIT_NOT_OK;
}
/* 获取必须的内存空间 */
temp--; /* 1个保留块 */
Index->BlockSum = temp;
VBlockInfo = malloc(temp * sizeof(uint32));
if (VBlockInfo == NULL)
{
free(Index->BlockState);
Index->BlockState = NULL;
free(Index->BlockEaseSum);
Index->BlockEaseSum = NULL;
return DISK_INIT_NOT_OK;
}
Index->VBlockInfo = VBlockInfo;
/* 初始化内存空间 */
do
{
*VBlockInfo++ = 0;
} while (--temp != 0);
/* 获取虚拟块与物理块的映射表、物理块擦除计数表和物理块状态表 */
VBlockInfo = (Index->VBlockInfo) - 1;
bufa = Drive->BufA;
k = 0;
j = Index->BlockSum;
Drive->SectorRead(Drive->Index, bufa, 0);
for (i = 1; i < j; i++)
{
if ((i % (BytsPerSec * 8)) == 0)
{
k++;
Drive->ExSectorRead(Drive->Index, bufa, k);
}
if ((bufa[(i / 8) % BytsPerSec] & (1 << (i % 8))) != 0)
{
Index->BlockState[i] = FREE_BLOCK;
m = Drive->SecsPreBlock;
n = m * i;
temp2 = 0;
temp1 = 0;
do
{
Drive->ExSectorRead(Drive->Index, bufa, n++);
temp = bufa[2] | bufa[3] << 8;
temp = temp << 16;
temp |= (bufa[0] | bufa[1] << 8);
temp3 = bufa[10] | bufa[11] << 8;
temp3 = temp3 << 16;
temp3 |= (bufa[8] | bufa[9] << 8);
if (temp3 != ~0)
{
temp1 = temp3;
}
if (temp < j && temp != 0)
{
VBlockInfo[temp] = i;
Index->BlockState[i] = USR_BLOCK;
temp2 = USR_BLOCK_ADD;
break;
}
} while (--m != 0);
Index->BlockEaseSum[i] = temp1 + temp2;
Drive->SectorRead(Drive->Index, bufa, k);
}
}
return DISK_INIT_OK;
}
/*********************************************************************************************************
关闭
*********************************************************************************************************/
static uint8 FFSDiskClose(FFSDisk *Index)
{
if (Index != NULL)
{
if (Index->BlockState != NULL)
{
free(Index->BlockState);
}
Index->BlockState = NULL;
if (Index->BlockEaseSum != NULL)
{
free(Index->BlockEaseSum);
}
Index->BlockEaseSum = NULL;
if (Index->VBlockInfo != NULL)
{
free(Index->VBlockInfo);
}
Index->VBlockInfo = NULL;
Index->BlockSum = 0;
}
return DISK_RETURN_OK;
}
/*********************************************************************************************************
释放扇区
*********************************************************************************************************/
static uint8 FFSFreeSector(FFSDisk *Index, uint32 SecIndex)
{
uint32 VBlockIndex, BlockIndex;
unsigned int i;
const FlashDriver *Drive;
uint8 *Buf;
Drive = Index->Drive;
VBlockIndex = SecIndex / Drive->SecsPreBlock;
Buf = Drive->BufA;
if (Index != NULL)
if (Drive != NULL)
if (VBlockIndex < Index->BlockSum)
{
BlockIndex = Index->VBlockInfo[VBlockIndex]; /* 获得物理块号 */
if (BlockIndex < Index->BlockSum)
if (BlockIndex != 0)
{
SecIndex = SecIndex % Drive->SecsPreBlock; /* 获得块内偏移 */
SecIndex = SecIndex + BlockIndex * Drive->SecsPreBlock; /* 获得物理扇区号 */
if (Drive->ExSectorRead(Drive->Index, Buf, SecIndex) == TRUE)
{
if (Buf[0] != 0xff ||
Buf[1] != 0xff ||
Buf[2] != 0xff ||
Buf[3] != 0xff)
{
Buf[0] = 0x00;
Buf[1] = 0x00;
Buf[2] = 0x00;
Buf[3] = 0x00;
if (Drive->ExSectorWrite(Drive->Index, Buf, SecIndex) != TRUE)
{
goto err;
}
if (Drive->ExSectorCheck(Drive->Index, Buf, SecIndex) != TRUE)
{
goto err;
}
}
SecIndex = BlockIndex * Drive->SecsPreBlock;
i = Drive->SecsPreBlock;
do
{
if (Drive->ExSectorRead(Drive->Index, Buf, SecIndex) == FALSE)
{
goto err;
}
if (Buf[0] == 0x00 &&
Buf[1] == 0x00 &&
Buf[2] == 0x00 &&
Buf[3] == 0x00)
{
SecIndex++;
continue;
}
if (Buf[0] == 0xff &&
Buf[1] == 0xff &&
Buf[2] == 0xff &&
Buf[3] == 0xff)
{
SecIndex++;
continue;
}
break;
} while (--i != 0);
if (i == 0)
{
Index->VBlockInfo[VBlockIndex] = 0x00000000;
Index->BlockState[BlockIndex] = FREE_BLOCK;
if (FFSBlockErase(Index, BlockIndex) != TRUE)
{
FFSSetBadBlock(Index, BlockIndex);
return FALSE;
}
}
}
}
}
return TRUE;
err:
Index->VBlockInfo[VBlockIndex] = 0x00000000;
FFSSetBadBlock(Index, BlockIndex);
return FALSE;
}
/*********************************************************************************************************
读扇区
*********************************************************************************************************/
static uint8 FFSDiskRead(FFSDisk *Index, uint8 *Buf, uint32 SecIndex)
{
uint32 BlockIndex;
const FlashDriver *Drive;
uint16 Rt;
Rt = DISK_READ_NOT_OK;
Drive = Index->Drive;
BlockIndex = SecIndex / Drive->SecsPreBlock;
if (Index != NULL)
if (Drive != NULL)
if (BlockIndex < Index->BlockSum)
{
Rt = DISK_READ_OK;
BlockIndex = Index->VBlockInfo[BlockIndex]; /* 获得物理块号 */
if (BlockIndex < Index->BlockSum)
if (BlockIndex != 0)
{
SecIndex = SecIndex % Drive->SecsPreBlock; /* 获得块内偏移 */
SecIndex = SecIndex + BlockIndex * Drive->SecsPreBlock; /* 获得物理扇区号 */
if (Drive->SectorRead(Drive->Index, Buf, SecIndex) != TRUE)
{
Rt = DISK_READ_NOT_OK;
}
}
}
return Rt;
}
/*********************************************************************************************************
查找空闲块中擦除次数最少的块)
*********************************************************************************************************/
static uint32 FildBockB(FFSDisk *Index)
{
uint32 BlockIndex;
uint32 i, j, temp2;
uint32 min;
uint8 *BlockState, temp1;
uint32 *BlockEaseSum;
uint8 *Buf;
j = Index->Drive->BlockPreDisk;
Buf = Index->Drive->BufA;
min = ~0;
BlockIndex = 0;
i = j - 1;
BlockState = Index->BlockState + 1;
BlockEaseSum = Index->BlockEaseSum + 1;
do
{
temp1 = *BlockState++;
temp2 = *BlockEaseSum++;
if (temp1 == FREE_BLOCK)
if (temp2 < min)
{
min = temp2;
BlockIndex = j - i;
if (min == 0)
{
break;
}
}
} while (--i != 0);
if (BlockIndex < j)
{
return BlockIndex;
}
return 0;
}
/*********************************************************************************************************
查找擦除次数最少的块(非空闲块要加权,以尽量在空闲块重分配)
*********************************************************************************************************/
static uint32 FildBockA(FFSDisk *Index)
{
uint32 BlockIndex;
uint32 i, j, temp2;
uint32 min;
uint8 *BlockState, temp1;
uint32 *BlockEaseSum;
uint8 *Buf;
j = Index->Drive->BlockPreDisk;
Buf = Index->Drive->BufA;
min = ~0;
BlockIndex = 0;
i = j - 1;
BlockState = Index->BlockState + 1;
BlockEaseSum = Index->BlockEaseSum + 1;
do
{
temp1 = *BlockState++;
temp2 = *BlockEaseSum++;
if (temp1 != BAD_BLOCK)
if (temp2 < min)
{
min = temp2;
BlockIndex = j - i;
if (min == 0)
{
break;
}
}
} while (--i != 0);
if (BlockIndex < j)
{
return BlockIndex;
}
return 0;
}
/*********************************************************************************************************
增加虚拟块
*********************************************************************************************************/
static uint32 AddVBlock(FFSDisk *Index)
{
uint32 BlockIndex, k, temp, temp1, temp2;
const FlashDriver *Drive;
uint8 *BufA;
uint8 C[4];
BlockIndex = FildBockA(Index);
if (BlockIndex == 0)
{
goto err;
}
if (Index->BlockState[BlockIndex] == USR_BLOCK) /* 此块已被使用 */
{
temp = FildBockB(Index); /* 找空闲块 */
if (temp == 0)
{
goto err;
}
/* 拷贝数据到空闲块 */
Drive = Index->Drive;
k = Drive->SecsPreBlock;
temp1 = BlockIndex * k;
temp2 = temp * k;
BufA = Drive->BufA;
do
{
Drive->ExSectorRead(Drive->Index, BufA, temp1);
if (BufA[5] == 0)
{
C[0] = BufA[0];
C[1] = BufA[1];
C[2] = BufA[2];
C[3] = BufA[3];
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -