?? nandfs.c
字號:
// ulCount += 512; } // // De-select the on-board NAND FLASH. // pulGPIO[HwPortABCD >> 2] |= HwPortABCD_NAND1_CS; // // Success. // return(ulCount); } // // Write data to the currently opened file. // case IOCTL_FS_WRITE: { tNANDFile *pFile; unsigned long ulCount; // // Get a pointer to the file structure. // pFile = (tNANDFile *)ulInstance; // // Make sure that the current file pointer is a multiple of 512. // if(pFile->ulFilePos & 511) { return(0); } // // Select the on-board NAND FLASH. // pulGPIO[HwPortABCD >> 2] &= ~HwPortABCD_NAND1_CS; // // Write pages to the on-board NAND FLASH. // ulCount = 0; while(ulParam2) { // // Stop writing data if we've reached the end of the on-board // NAND FLASH. // if(pFile->ulPage == (sNAND.usNumBlocks * sNAND.ucPagesPerBlock)) { break; } // // If this is the first page of a block, then erase the block. // if((pFile->ulPage & (sNAND.ucPagesPerBlock - 1)) == 0) { NANDWaitTilNotBusy(HwNANDAddress); (sNAND.pfnErase)(HwNANDAddress, pFile->ulPage / sNAND.ucPagesPerBlock); } // // Write the next page to the on-board NAND FLASH. // NANDWaitTilNotBusy(HwNANDAddress); (sNAND.pfnWrite)(HwNANDAddress, NextPage(&(pFile->ulPage)), (unsigned char *)ulParam1, pucScratch); // // See if this was a partial sector at the end of the write. // if(ulParam2 < 512) { // // Increment the file length. // sNAND.ulFileLength += ulParam2; // // Increment the count of the bytes written. // ulCount += ulParam2; // // There are no byte remaining to be written. // ulParam2 = 0; } // // Otherwise, it was a full sector. // else { // // Increment the write buffer pointer. // ulParam1 += 512; // // Decrement the count of bytes to write. // ulParam2 -= 512; // // Increment the file length. // sNAND.ulFileLength += 512; // // Increment the count of the bytes written. // ulCount += 512; } } // // De-select the on-board NAND FLASH. // pulGPIO[HwPortABCD >> 2] |= HwPortABCD_NAND1_CS; // // Success. // return(ulCount); } // // Seek to the specified position in the currently opened file. // case IOCTL_FS_SEEK: { tNANDFile *pFile; unsigned long ulCount; // // Make sure that the seek position is a multiple of 512. // if(ulParam1 & 511) { return(0); } // // Make sure that the seek position is within the file. // if(ulParam1 > sNAND.ulFileLength) { return(0); } // // Get a pointer to the file structure. // pFile = (tNANDFile *)ulInstance; // // Set the file position to the seek position. // pFile->ulFilePos = ulParam1; // // Compute the page number for this position within the file. // pFile->ulPage = sNAND.ucPagesPerBlock + 1 + (ulParam1 / 512); // // Skip the bad blocks in the NAND FLASH. This works by adding a // block's worth of offset when the offset is greater than the // offset of a bad block. // for(ulCount = 0; ulCount < sNAND.usNumBadBlocks; ulCount++) { // // Does this page start at or after a bad block? // if((pFile->ulPage / sNAND.ucPagesPerBlock) >= sNAND.usBadBlocks[ulCount]) { // // It does, so skip a block's worth of data. // pFile->ulPage += sNAND.ucPagesPerBlock; } } // // Success. // return(1); } // // Return the current read/write pointer of the file. // case IOCTL_FS_TELL: { tNANDFile *pFile; // // Get a pointer to the file structure. // pFile = (tNANDFile *)ulInstance; // // Return the current read/write pointer. // return(pFile->ulFilePos); } // // Return the length of the currently opened file. // case IOCTL_FS_LENGTH: { // // Return the file length. // return(sNAND.ulFileLength); } // // Close the currently opened file. // case IOCTL_FS_CLOSE: { tNANDFile *pFile; // // Get a pointer to the file structure. // pFile = (tNANDFile *)ulInstance; // // See if we were writing this file. // if(ulParam1 & FS_OPEN_WRITE) { // // Select the on-board NAND FLASH. // pulGPIO[HwPortABCD >> 2] &= ~HwPortABCD_NAND1_CS; // // Go back to the first page of the file. // pFile->ulPage = sNAND.ucPagesPerBlock - 1; NextPage(&(pFile->ulPage)); // // Write the first page of the file. // NANDWaitTilNotBusy(HwNANDAddress); (sNAND.pfnWrite)(HwNANDAddress, pFile->ulPage, (unsigned char *)&(sNAND.ulFileLength), pucScratch); // // Make sure that the on-board NAND FLASH is done programming // the page before we continue. // NANDWaitTilNotBusy(HwNANDAddress); // // De-select the on-board NAND FLASH. // pulGPIO[HwPortABCD >> 2] |= HwPortABCD_NAND1_CS; } // // Success. // return(1); } // // Deletes the specified file from the file system. We do not support // multiple files, so we also don't care what the file name is...any // delete will work for the single file in the file system. // // We also use this to handle formatting the file system, since a // format will simply blast the singe file. // case IOCTL_FS_DELETE: case IOCTL_FS_FORMAT: { unsigned long ulPage; // // Select the on-board NAND FLASH. // pulGPIO[HwPortABCD >> 2] &= ~HwPortABCD_NAND1_CS; // // Go to the first page of the file. // ulPage = sNAND.ucPagesPerBlock - 1; NextPage(&ulPage); // // Erase the first block of the file. // NANDWaitTilNotBusy(HwNANDAddress); (sNAND.pfnErase)(HwNANDAddress, ulPage / sNAND.ucPagesPerBlock); // // Set the file length to zero. // sNAND.ulFileLength = 0; // // Write a file length of zero. // NANDWaitTilNotBusy(HwNANDAddress); (sNAND.pfnWrite)(HwNANDAddress, ulPage, (unsigned char *)&(sNAND.ulFileLength), pucScratch); // // Make sure that the on-board NAND FLASH is done programming the // page before we continue. // NANDWaitTilNotBusy(HwNANDAddress); // // De-select the on-board NAND FLASH. // pulGPIO[HwPortABCD >> 2] |= HwPortABCD_NAND1_CS; // // Success. // return(1); } // // Opens the directory of the file system. // case IOCTL_FS_OPENDIR: { tNANDDir *pDir; // // Get a pointer to the directory structure. // pDir = (tNANDDir *)ulInstance; // // Indicate that the next IOCTL_FS_READDIR will be the first. // if(sNAND.ulFileLength) { pDir->bIsFirstDirEntry = 1; } else { pDir->bIsFirstDirEntry = 0; } // // Success. // return(1); } // // Read the next directory entry from the file system. // case IOCTL_FS_READDIR: { tNANDDir *pDir; // // Get a pointer to the directory structure. // pDir = (tNANDDir *)ulInstance; // // If this is not the first IOCTL_FS_READDIR, then return a failure // since we only support a single file in the on-board NAND FLASH. // if(!pDir->bIsFirstDirEntry) { return(0); } // // Fill in the file name with a bogus name. // memcpy((void *)ulParam1, "n\0a\0n\0d\0.\0d\0a\0t\0\0", 18); // // Indicate that the next IOCTL_FS_READDIR will not be the first. // pDir->bIsFirstDirEntry = 0; // // Success. // return(1); } // // Close the directory of the file system. // case IOCTL_FS_CLOSEDIR: { // // Success. // return(1); } // // Create a new directory in the file system. // case IOCTL_FS_MAKEDIR: { // // We do not support subdirectories, so return a failure. // return(0); } // // Remove the specified directory from the file system. // case IOCTL_FS_REMOVEDIR: { // // We do not support subdirectories, so return a failure. // return(0); } // // Determine the total capacity of the file system. // case IOCTL_FS_TOTALSPACE: { // // The total capacity of the file system is the number of good // blocks minus 1, times the number of pages per block, minus 1, // time 512 bytes per page. // return((((sNAND.usNumBlocks - sNAND.usNumBadBlocks - 1) * sNAND.ucPagesPerBlock) - 1) * 512); } // // Determine the available capacity in the file system. // case IOCTL_FS_FREESPACE: { // // The free space is the total capacity minus the space used by our // one file. // return(((((sNAND.usNumBlocks - sNAND.usNumBadBlocks - 1) * sNAND.ucPagesPerBlock) - 1) * 512) - sNAND.ulFileLength); } // // We should never get here, but just in case... // default: { // // Return a failure. // return(0); } }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -