📄 yaffs_fileem.cpp
字号:
/* * YAFFS: Yet another FFS. A NAND-flash specific file system. * yaffs_ramdisk.c: yaffs ram disk component * * Copyright (C) 2002 Aleph One Ltd. * * Created by Charles Manning <charles@aleph1.co.uk> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * */// This provides a YAFFS nand emulation on a file.// THis is only intended as test code to test persistence etc.#ifdef _WIN32#include "stdafx.h"#endif#include "stdlib.h"const char *yaffs_flashif_c_version = "$Id: yaffs_fileem.c,v 1.1 2003/01/21 03:32:17 charles Exp $";#include "..\yaffs\yportenv.h"#include "yaffs_flashif.h"#include "..\yaffs\yaffs_guts.h"//#include "devextras.h"//#include <sys/types.h>//#include <sys/stat.h>//#include <fcntl.h>//#include <unistd.h> #include "yaffsfs.h"#define SIZE_IN_MB 16#define PAGES_PER_BLOCK YAFFS_CHUNKS_PER_BLOCK //YAFFS_CHUNKS_PER_BLOCK#define BLOCK_SIZE (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_PAGE) //528#define BLOCKS_PER_MEG ((1024*1024)/(PAGES_PER_BLOCK * YAFFS_BYTES_PER_PAGE)) //512#define FLASH_START_ADDR 0x20000000#define FLASH_END_ADDR 0x20200000#define FLASH_BLK_NUM ((FLASH_END_ADDR-FLASH_START_ADDR)/0x1000)/*typedef struct { __u8 data[YAFFS_BYTES_PER_PAGE]; //528 Data + spare} yflash_Page;typedef struct{ yflash_Page page[PAGES_PER_BLOCK]; // The pages in the block } yflash_Block;typedef struct{ CFile file; int nBlocks;} yflash_Device;static yflash_Device filedisk; */extern void Erase_One_Sector (WORD *Dst);//2K WORD = 4K BYTEextern bool FlashWriteData(char *Dst,char *Src,unsigned long Size);extern void Program_One_Word (WORD SrcWord, WORD *Dst); static int CheckInit(yaffs_Device *dev){ return 1;}int yflash_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare){ int written; //CheckInit(dev); WORD notuse; // BYTE bBuf[YAFFS_BYTES_PER_CHUNK]; if(data) { if ((DWORD )data & 0x01) { memcpy(bBuf, data, YAFFS_BYTES_PER_CHUNK); data = bBuf; } if (FlashWriteData((char* )(FLASH_START_ADDR+chunkInNAND * YAFFS_BYTES_PER_PAGE), (char* )data, YAFFS_BYTES_PER_CHUNK) == false) return YAFFS_FAIL; } if(spare) { if (FlashWriteData((char* )(FLASH_START_ADDR+chunkInNAND * YAFFS_BYTES_PER_PAGE + YAFFS_BYTES_PER_CHUNK), (char* )spare, YAFFS_BYTES_PER_SPARE) == false) return YAFFS_FAIL; } return YAFFS_OK; }int yflash_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare){ int nread; //CheckInit(dev);/* //VDK::PushCriticalRegion(); if(data) { //filedisk.file.Seek(chunkInNAND * YAFFS_BYTES_PER_PAGE, CFile::begin); //nread = filedisk.file.Read(data, YAFFS_BYTES_PER_CHUNK); memcpy(data, (char* )(FLASH_START_ADDR+chunkInNAND*YAFFS_BYTES_PER_PAGE), YAFFS_BYTES_PER_CHUNK); //if(nread != YAFFS_BYTES_PER_CHUNK) return YAFFS_FAIL; //512 } if(spare) { //filedisk.file.Seek(chunkInNAND * YAFFS_BYTES_PER_PAGE + YAFFS_BYTES_PER_CHUNK, CFile::begin); // //nread = filedisk.file.Read(spare, 16); //if(nread != 16) return YAFFS_FAIL; memcpy(spare, (char* )(FLASH_START_ADDR+chunkInNAND * YAFFS_BYTES_PER_PAGE + YAFFS_BYTES_PER_CHUNK), YAFFS_BYTES_PER_SPARE); } //VDK::PopCriticalRegion();*/ WORD* pwDest; WORD* pwSrc; int i; BYTE bBuf[YAFFS_BYTES_PER_CHUNK]; if (data) { pwSrc = (WORD* )(FLASH_START_ADDR + chunkInNAND*YAFFS_BYTES_PER_PAGE); if ((DWORD )data & 0x01) pwDest = (WORD* )bBuf; else pwDest = (WORD* )data; for (i=0; i<YAFFS_BYTES_PER_CHUNK/sizeof(WORD); i++) { *pwDest++ = *pwSrc++; } if ((DWORD )data & 0x01) { memcpy(data, bBuf, YAFFS_BYTES_PER_CHUNK); } } if(spare) { pwSrc = (WORD* )(FLASH_START_ADDR + chunkInNAND*YAFFS_BYTES_PER_PAGE + YAFFS_BYTES_PER_CHUNK); pwDest = (WORD* )spare; for (i=0; i<YAFFS_BYTES_PER_SPARE/sizeof(WORD); i++) { *pwDest++ = *pwSrc++; } } return YAFFS_OK; }int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber){ int i; //CheckInit(dev); if(blockNumber<0 || blockNumber >= FLASH_BLK_NUM) { T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber)); return YAFFS_FAIL; } else { Erase_One_Sector((WORD* )(FLASH_START_ADDR+blockNumber*0x1000));//2K WORD = 4K BYTE return YAFFS_OK; } }int yflash_InitialiseNAND(yaffs_Device *dev){ dev->useNANDECC = 1; // force on useNANDECC which gets faked. // This saves us doing ECC checks. return YAFFS_OK;}int yflash_WriteSpare(yaffs_Device *dev, int chunkInNAND, int offset, const __u16 data){ Program_One_Word(data, (WORD* )(FLASH_START_ADDR + chunkInNAND*YAFFS_BYTES_PER_PAGE + YAFFS_BYTES_PER_CHUNK + offset)); return YAFFS_OK;}void yflash_Read(WORD* pwDest, WORD* pwSrc, DWORD cnt){ for (WORD i=0; i<cnt; i++) { *pwDest++ = *pwSrc++; }}int yflash_RepairWriteChunkError(struct yaffs_DeviceStruct *dev, int chunk, const __u8 *data, yaffs_Spare *spare){ WORD i; WORD block1[BLOCK_SIZE/sizeof(WORD)]; WORD block2[BLOCK_SIZE/sizeof(WORD)]; WORD* pwBlockAddr = (WORD* )(FLASH_START_ADDR + BLOCK_SIZE * (chunk / YAFFS_CHUNKS_PER_BLOCK)); //把整个block读到内存 for (i=0; i<3; i++) { yflash_Read(block1, pwBlockAddr, BLOCK_SIZE/sizeof(WORD)); yflash_Read(block2, pwBlockAddr, BLOCK_SIZE/sizeof(WORD)); if (memcmp((BYTE* )block1, (BYTE* )block2, BLOCK_SIZE) == 0) //连续两次读到的一样才认为正确 break; } if (i >= 3) return YAFFS_FAIL; DWORD dwOffset = (DWORD )YAFFS_BYTES_PER_PAGE * (chunk % YAFFS_CHUNKS_PER_BLOCK); if (data) memcpy((BYTE* )block1+dwOffset, data, YAFFS_BYTES_PER_CHUNK); if (spare) memcpy((BYTE* )block1+dwOffset+YAFFS_BYTES_PER_CHUNK, spare, YAFFS_BYTES_PER_SPARE); for (i=0; i<3; i++) { Erase_One_Sector(pwBlockAddr); FlashWriteData((char* )pwBlockAddr, (char* )block1, BLOCK_SIZE); yflash_Read(block2, pwBlockAddr, BLOCK_SIZE/sizeof(WORD)); if (memcmp((BYTE* )block1, (BYTE* )block2, BLOCK_SIZE) == 0) return YAFFS_OK; } return YAFFS_FAIL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -