www.pudn.com > File_SD_OS.rar > ZLG_FFS.c
/****************************************Copyright (c)************************************************** ** Guangzou ZLG-MCU Development Co.,LTD. ** graduate school ** http://www.zlgmcu.com ** **--------------File Info------------------------------------------------------------------------------- ** File name: ZLG_FFS.c ** Last modified Date: 2004-11-08 ** Last Version: 1.0 ** Descriptions: k9f2808 driver ** **------------------------------------------------------------------------------------------------------ ** Created by: Chenmingji ** Created date: 2004-11-08 ** Version: 1.0 ** Descriptions: The original version ** **------------------------------------------------------------------------------------------------------ ** Modified by: ** Modified date: ** Version: ** Descriptions: ** ********************************************************************************************************/ #define IN_ZLG_FFS #include "config.h" #include#define BAD_BLOCK 0 #define FREE_BLOCK 1 #define USR_BLOCK 2 #define USR_BLOCK_ADD 0x20 /********************************************************************************************************* 设置坏块 *********************************************************************************************************/ static uint8 FFSSetBadBlock(FFSDisk *Index, uint16 BlockIndex) { uint8 *bufa; const FlashDriver *Drive; unsigned int BytsPerSec; if (Index != NULL) { Drive = Index->Drive; bufa = (uint8 *)(Drive->BufA); BytsPerSec = Drive->BytsPerSec; if (Drive->SectorRead(Drive->Index, bufa, BlockIndex / (BytsPerSec * 8)) == TRUE) { bufa[BlockIndex % BytsPerSec] &= ~(1 << (BlockIndex % 8)); Index->BlockState[BlockIndex] = BAD_BLOCK; Index->BlockEaseSum[BlockIndex] = ~0; return Drive->SectorWrite(Drive->Index, bufa, BlockIndex / (BytsPerSec * 8)); } } return FALSE; } /* 扇区扩展数据结构: */ /* buf[0..3]: 块索引,0x00000000和0xffffffff为空闲 */ /* buf[4..4]: 有效标志:'Z' */ /* buf[5..5]: 使用标志:0:已经使用 */ /* buf[5..7]: 保留原始状态 */ /* buf[8..11]: 擦除次数,低字节在前 */ /* buf[12..15]:保留 */ /********************************************************************************************************* 擦除块 *********************************************************************************************************/ static uint8 FFSBlockErase(FFSDisk *Index, uint16 BlockIndex) { const FlashDriver *Drive; uint32 temp1, temp2; uint8 *BufA; Drive = Index->Drive; BufA = Drive->BufA; if (Drive->ExSectorRead(Drive->Index, BufA, BlockIndex * (Drive->SecsPreBlock)) == FALSE) { goto err; } BufA[0] = 0xff; BufA[1] = 0xff; BufA[2] = 0xff; BufA[3] = 0xff; temp1 = (BufA[11] << 8) | BufA[10]; temp1 = temp1 << 16; temp1 |= ((BufA[9] << 8) | BufA[8]); if (BufA[4] == 'Z') { temp1++; } else { temp1 = 0; } Drive->BufA[4] = 'Z'; Drive->BufA[5] = 0xff; BufA[8] = temp1; BufA[9] = temp1 >> 8; BufA[10] = temp1 >> 16; BufA[11] = temp1 >> 24; Index->BlockEaseSum[BlockIndex] = temp1; Index->BlockState[BlockIndex] = FREE_BLOCK; if (Drive->BlockErase(Drive->Index, BlockIndex * Drive->SecsPreBlock) == FALSE) { goto err; } temp1 = Drive->SecsPreBlock; temp2 = BlockIndex * temp1; do { if (Drive->ExSectorWrite(Drive->Index, BufA, temp2) == FALSE) { goto err; } if (Drive->ExSectorCheck(Drive->Index, BufA, temp2) == FALSE) { goto err; } /* 校验 */ if ((Drive->ExSectorRead(Drive->Index, BufA, temp2++)) == FALSE) { goto err; } if (BufA[0] != 0xff) { goto err; } if (BufA[1] != 0xff) { goto err; } if (BufA[2] != 0xff) { goto err; } if (BufA[3] != 0xff) { goto err; } if (BufA[4] != 'Z') { goto err; } if (BufA[5] != 0xff) { goto err; } } while (--temp1 != 0); return TRUE; err: return FFSSetBadBlock(Index, BlockIndex); } /********************************************************************************************************* *********************************************************************************************************/ const static uint8 logo[16] = {'Z', 'L', 'G', '\\', 'F', 'F', 'S', 0, 'V', 0, 1, 0, 1, 0, 0, 0 }; const static uint8 logo1[16] = {0xb3, 0xc2, 0xc3, 0xf7, 0xbc, 0xc6, 0, 0, '2', '0', '0', '4', '1', '1', 0, 0 }; static uint8 NFFormatA(FFSDisk *Index) { uint32 i, temp; unsigned int j, k; const FlashDriver *Drive; uint8 *bufa; Drive = Index->Drive; temp = Drive->BlockPreDisk; /* 设置坏块表 */ Drive->BlockErase(Drive->Index, 0); bufa = Drive->BufA; j = Drive->BytsPerSec; do { *bufa++ = 0xff; } while ( --j != 0); bufa = Drive->BufA; for (i = 1; i < Drive->BlockPreDisk; i++) { if ((Drive->BlockCheck(Drive->Index, i)) != TRUE) { bufa[(i / 8) % (Drive->BytsPerSec)] &= ~(1 << (i % 8)); } if ((i % (Drive->BytsPerSec * 8)) == 0) { bufa = Drive->BufA; Drive->SectorWrite(Drive->Index, bufa, i / (Drive->BytsPerSec * 8)); j = Drive->BytsPerSec; do { *bufa++ = 0xff; } while (--j != 0); bufa = Drive->BufA; } } /* 设置logo */ Drive->ExSectorWrite(Drive->Index, (uint8 *)logo, 0); Drive->ExSectorWrite(Drive->Index, (uint8 *)logo, Drive->SecsPreBlock - 1); /* 初始化扇区 */ k = 0; bufa = Drive->BufA; Drive->SectorRead(Drive->Index, bufa, 0); for (i = 1; i < Drive->BlockPreDisk; i++) { if ((i % (Drive->BytsPerSec * 8)) == 0) { k++; Drive->SectorRead(Drive->Index, bufa, k); } if ((bufa[i % (Drive->BytsPerSec)] & (1 << (i % 8))) != 0) { FFSBlockErase(Index, i); Drive->SectorRead(Drive->Index, bufa, k); } } /* 初始化第0扇区 */ k = 0; bufa = Drive->BufA; Drive->SectorRead(Drive->Index, bufa, 0); for (i = 1; i < Drive->BlockPreDisk; i++) { if ((i % (Drive->BytsPerSec * 8)) == 0) { k++; Drive->SectorRead(Drive->Index, bufa, k); } if ((bufa[(i / 8) % (Drive->BytsPerSec)] & (1 << (i % 8))) != 0) { temp = (Drive->SecsPreBlock) * i; Drive->ExSectorRead(Drive->Index, bufa, temp); bufa[0] = 0x01; bufa[1] = 0x00; bufa[2] = 0x00; bufa[3] = 0x00; if (Drive->ExSectorWrite(Drive->Index, bufa, temp) ==FALSE) { FFSSetBadBlock(Drive->Index, temp / Drive->SecsPreBlock); break; } if (Drive->ExSectorCheck(Drive->Index, bufa, temp) ==FALSE) { FFSSetBadBlock(Drive->Index, temp / Drive->SecsPreBlock); break; } break; } } return TRUE; } static uint8 NFFormatB(FFSDisk *Index) { uint32 i, BlockPreDisk; unsigned int BytsPerSec; unsigned int k; const FlashDriver *Drive; uint8 *bufa; if (Index == NULL) { return FALSE; } Drive = Index->Drive; bufa = Drive->BufA; BytsPerSec = Drive->BytsPerSec; BlockPreDisk = Drive->BlockPreDisk; /* 初始化扇区 */ k = 0; Drive->SectorRead(Drive->Index, bufa, 0); for (i = 1; i < BlockPreDisk; i++) { if ((i % (BytsPerSec * 8)) == 0) { k++; Drive->SectorRead(Drive->Index, bufa, k); } if ((bufa[(i / 8) % BytsPerSec] & (1 << (i % 8))) != 0) { FFSBlockErase(Index, i); Drive->SectorRead(Drive->Index, bufa, k); } } /* 初始化第0扇区 */ k = 0; bufa = Drive->BufA; Drive->SectorRead(Drive->Index, bufa, 0); for (i = 1; i < Drive->BlockPreDisk; i++) { if ((i % (Drive->BytsPerSec * 8)) == 0) { k++; Drive->SectorRead(Drive->Index, bufa, k); } if ((bufa[i % (Drive->BytsPerSec)] & (1 << (i % 8))) != 0) { i = (Drive->SecsPreBlock) * i; Drive->ExSectorRead(Drive->Index, bufa, i); bufa[0] = 0x01; bufa[1] = 0x00; bufa[2] = 0x00; bufa[3] = 0x00; if (Drive->ExSectorWrite(Drive->Index, bufa, i) == FALSE) { FFSSetBadBlock(Drive->Index, i / Drive->SecsPreBlock); break; } if (Drive->ExSectorCheck(Drive->Index, bufa, i) == FALSE) { FFSSetBadBlock(Drive->Index, i / Drive->SecsPreBlock ); break; } break; } } return TRUE; } static uint8 NFFormat(FFSDisk *Index) { uint8 *buf; buf = Index->Drive->BufA; if (Index != NULL) if (Index->Drive->ExSectorRead(Index->Drive->Index, buf, 0) == TRUE) { if (buf[0] != 'Z' || buf[1] != 'L' || buf[2] != 'G' || buf[3] != '\\' || buf[4] != 'F' || buf[5] != 'F' || buf[6] != 'S' || buf[7] != 0) { return NFFormatA(Index); } else { return NFFormatB(Index); } } return FALSE; } /********************************************************************************************************* 初始化 *********************************************************************************************************/ static uint8 FFSDiskInit(FFSDisk *Index) { uint32 i, temp, temp1, temp2, temp3; unsigned int j, k, m, n, BytsPerSec; const FlashDriver *Drive; uint8 *bufa; uint32 *VBlockInfo; /* 检查参数有效性 */ if (Index == NULL) { return DISK_INIT_NOT_OK; } Drive = Index->Drive; if (Drive == NULL || Drive->SectorRead == NULL || Drive->ExSectorRead == NULL || Drive->SectorWrite == NULL || Drive->ExSectorWrite == NULL || Drive->BlockErase == NULL || //Drive->SecCopy == NULL || Drive->SectorCheck == NULL || Drive->ExSectorCheck == NULL ) { return DISK_INIT_NOT_OK; } bufa = Drive->BufA; if (Drive->ExSectorRead(Drive->Index, bufa, 0) == FALSE) { return DISK_INIT_NOT_OK; } /* 没有低级格式化就低级格式化 */ if (bufa[0] != 'Z' || bufa[1] != 'L' || bufa[2] != 'G' || bufa[3] != '\\' || bufa[4] != 'F' || bufa[5] != 'F' || bufa[6] != 'S' || bufa[7] != 0) { NFFormatA(Index); } /* 获取必须的内存空间 */ i = Drive->BlockPreDisk; 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; } 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 ********************************************************************************************************/