UFFSファイルシステムとNandFlash
9106 ワード
1.ハードウェアチップ駆動下位駆動関数では、特定のチップ特性に対して、上位UFFSシステム呼び出しに提供する6つの基礎関数を作成する必要がある.
そして異なるチップに対して特定のnandチップのパラメータをまとめ、
nandプロファイルでは、複数のNandFlashの情報を含む構造を定義できます.他のモデルのNandFlashを移植すると、NandFlash_InitInfoでは対応する情報が見つかり、コードは基本的に修正されず、移植性が強い:nand.cでは、一般的なnandチップに関する情報が定義されています.
2.チップを交換した後、変更するプロファイルが必要です.既存のハブプロジェクトでは、「nandflash-interface.c」というファイルが最下位のnandドライバと上位UFFSとの直接的な互換構成をしています.目的は、ドライバ層にリストされているチップにあります.どちらのチップもコードを変更せずに使用できます.
この層の動作構想:まず標準関数ReadID()を介してそのブロックnandのID番号を読み出す.ID番号でNandFlash_InitInfoで比較します.そして,このブロックnandの基礎情報を調べ,SNandInitInfoに記録した.
uffs初期化時にこれらの基礎情報をuffsに構成する
さらにこの層では,読み書き関数も1層カプセル化する.異なるリーフサイズの読み書きを互換化することを目的としています.nandを具体的に読み書きすると、nandのリーフサイズに基づいて、比較的一致する関数が具体的に呼び出されます.(nandが書かれているページは2 kも512もあるので互換性のある処理が必要です)
この層は最終的に上層UFFSの3つの関数に提供され,残りの関数は使用されなかった.
他の関数は、一部のチップの高度な機能にインタフェースを提供するべきであり、例えば、一部のeccの検証はハードウェアで完了し、ソフトウェア計算を必要としない.
ReadID() ID
EraseBlock()
ReadPage()
ReadPageSpare()
WritePage()
WritePageSpare()
そして異なるチップに対して特定のnandチップのパラメータをまとめ、
typedef struct SNandInitInfo
{
rt_uint16_t uNandID ; /* Nand Chip ID */
rt_uint16_t uNandNbBlocks ;
rt_uint32_t uNandBlockSize ;
rt_uint16_t uNandSectorSize; ; ( )
rt_uint8_t uNandSpareSize ;
rt_uint8_t uNandBusWidth ;
rt_uint8_t uNandBadOffset ;
char name[16] ; /* Nand Name */
} SNandInitInfo, *PSNandInitInfo;
nandプロファイルでは、複数のNandFlashの情報を含む構造を定義できます.他のモデルのNandFlashを移植すると、NandFlash_InitInfoでは対応する情報が見つかり、コードは基本的に修正されず、移植性が強い:nand.cでは、一般的なnandチップに関する情報が定義されています.
const struct SNandInitInfo NandFlash_InitInfo[] = {
/*
{0xecda, 0x800, 0x20000, 0x800, 0x40, 0x0,0x0, "K9F2G08U0M\0"},
{0xecaa, 0x800, 0x20000, 0x800, 0x40, 0x0,0x0, "K9F2G08R0A\0"},
*/
{0xec75, 0x800, 0x4000, 0x200, 0x10, 0x0,0x04, "k9f5608\0"}, /*add by misswhile*/
{0xecf1, 0x400, 0x20000, 0x800, 0x40, 0x0,0x0, "K9F1G08U0M\0"}, /*add by misswhile*/
{0xec76, 0x1000, 0x4000, 0x200, 0x10, 0x0,0x04, "K9F12808u0b\0"}, /*add by misswhile*/
{0xeca5, 0x800, 0x4000, 0x200, 0x10, 0x0,0x0, "K9F1G08U0A\0"}, /*add by misswhile*/
/*
{0x20aa, 0x800, 0x20000, 0x800, 0x40, 0x0,0x0, "STMNAND02GR3B\0"},
{0x2caa, 0x800, 0x20000, 0x800, 0x40, 0x0,0x0, "MT29F2G08ABD\0"}, */
{0,}
};
2.チップを交換した後、変更するプロファイルが必要です.既存のハブプロジェクトでは、「nandflash-interface.c」というファイルが最下位のnandドライバと上位UFFSとの直接的な互換構成をしています.目的は、ドライバ層にリストされているチップにあります.どちらのチップもコードを変更せずに使用できます.
この層の動作構想:まず標準関数ReadID()を介してそのブロックnandのID番号を読み出す.ID番号でNandFlash_InitInfoで比較します.そして,このブロックnandの基礎情報を調べ,SNandInitInfoに記録した.
uffs初期化時にこれらの基礎情報をuffsに構成する
static void setup_flash_storage(struct uffs_StorageAttrSt *attr ,PSNandInitInfo info)
{
attr->page_data_size = info->uNandSectorSize;//NAND_PAGE_DATA_SIZE; /* page data size */
attr->pages_per_block = info->uNandBlockSize/info->uNandSectorSize;//NAND_PAGES_PER_BLOCK; /* pages per block */
attr->spare_size = info->uNandSpareSize;//NAND_PAGE_SPARE_SIZE; /* page spare size */
attr->block_status_offs = 4;//info->uNandBadOffset;//4; /* block status offset is 5th u8 in spare */
attr->ecc_opt = UFFS_ECC_SOFT; /* ecc option */
//attr->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
//attr->ecc_opt = UFFS_ECC_HW_AUTO;//UFFS_ECC_NONE;//UFFS_ECC_SOFT; /* ecc option */
attr->layout_opt = UFFS_LAYOUT_UFFS;//UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
}
さらにこの層では,読み書き関数も1層カプセル化する.異なるリーフサイズの読み書きを互換化することを目的としています.nandを具体的に読み書きすると、nandのリーフサイズに基づいて、比較的一致する関数が具体的に呼び出されます.(nandが書かれているページは2 kも512もあるので互換性のある処理が必要です)
static int nand_read_page(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
u8 *spare, int spare_len)
{
u8 val = 0;
int ret = UFFS_FLASH_NO_ERR;
if (data && data_len > 0) {
nand_read_page_data(dev, block, page, data, data_len, ecc);
}
if (spare && spare_len > 0) {
nand_read_page_spare(dev, block, page, spare, 0, spare_len);
}
if (data == NULL && spare == NULL) {
nand_read_page_spare(dev, block, page, &val, dev->attr->block_status_offs, 1);
ret = (val == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK);
}
return ret;
}
この層は最終的に上層UFFSの3つの関数に提供され,残りの関数は使用されなかった.
const struct uffs_FlashOpsSt my_nand_driver_ops = {
NULL,
NULL,
nand_read_page, //ReadPageData
NULL, //ReadPageSpareWithLayout
nand_write_page, //WritePageData
NULL,
NULL, //spi_isbad_block, //IsBadBlock
NULL, //MarkBadBlock
nand_erase_block, //EraseBlock
};
他の関数は、一部のチップの高度な機能にインタフェースを提供するべきであり、例えば、一部のeccの検証はハードウェアで完了し、ソフトウェア計算を必要としない.