/* ################################################################### ** This component module is generated by Processor Expert. Do not modify it. ** Filename : McuFatFS.h ** Project : FRDM-K64F_Generator ** Processor : MK64FN1M0VLL12 ** Component : FAT_FileSystem ** Version : Component 01.214, Driver 01.00, CPU db: 3.00.000 ** Compiler : GNU C Compiler ** Date/Time : 2021-05-13, 11:07, # CodeGen: 738 ** Abstract : ** ** Settings : ** Component name : McuFatFS ** FatFs Version : R0.12 (Patch 3, 29-April-2016) ** Tiny : no ** Volumes : 1 ** Drives : 1 ** Drive0 : SDCard ** FS_MINIMIZE : 0 ** Maximum Sector Size : 512 ** Relative Path : Enabled with f_getcwd() ** Code Page : U.S. (OEM) ** File Sharing : 0 ** Multipartion : no ** Fast Seek : yes ** Use Find : Disable (0) ** String Functions : enable ** LFN : Long File Name Support ** Use LFN : Disable ** exFAT : no ** Max LFN Length : 255 ** LFN Unicode : no ** Write enabled : Enabled ** Use TimeDate : Enabled ** Realtime clock : McuTimeDate ** Reentrant : Enabled ** Timeout ticks : 1000 ** Handle : HANDLE ** User Sync Functions : no ** RTOS : Enabled ** RTOS : McuRTOS ** Use dynamic heap : yes ** Utility : McuUtility ** Wait : McuWait ** SDK : McuLib ** Shell : Enabled ** Shell : McuShell ** Card Insert Delay (ms) : 100 ** File print buffer size : 32 ** File copy buffer size : 32 ** Contents : ** open - FRESULT McuFatFS_open(FIL *fp, const XCHAR *path, BYTE mode); ** close - FRESULT McuFatFS_close(FIL *fp); ** read - FRESULT McuFatFS_read(FIL *fp, void *buff, UINT btr, UINT *br); ** write - FRESULT McuFatFS_write(FIL *fp, const *void buff, UINT btw, UINT *bw); ** opendir - FRESULT McuFatFS_opendir(DIR *dj, const XCHAR *path); ** readdir - FRESULT McuFatFS_readdir(DIR *dj, FILINFO *fno); ** lseek - FRESULT McuFatFS_lseek(FIL *fp, DWORD ofs); ** unlink - FRESULT McuFatFS_unlink(const XCHAR *path); ** mount - FRESULT McuFatFS_mount(FATFS *fs, const TCHAR* path, byte opt); ** getfree - FRESULT McuFatFS_getfree(const XCHAR *path, dword *nclst, FATFS **fatfs); ** sync - FRESULT McuFatFS_sync(FIL *fp); ** rename - FRESULT McuFatFS_rename(const XCHAR *path_old, const XCHAR *path_new); ** isWriteProtected - bool McuFatFS_isWriteProtected(uint8_t *drvStr); ** isDiskPresent - bool McuFatFS_isDiskPresent(uint8_t *drvStr); ** mkdir - FRESULT McuFatFS_mkdir(const XCHAR *path); ** chmod - FRESULT McuFatFS_chmod(const TCHAR* FileName, uint8_t Attribute, uint8_t... ** truncate - FRESULT McuFatFS_truncate(FIL *FileObject); ** stat - FRESULT McuFatFS_stat(const TCHAR* FileName, FILINFO* FileInfo); ** utime - FRESULT McuFatFS_utime(const TCHAR* FileName, const FILINFO* TimeDate); ** mkfs - FRESULT McuFatFS_mkfs(byte drive, uint8_t PartitioningRule, UINT AllocSize); ** chdir - FRESULT McuFatFS_chdir(const TCHAR* Path); ** chdrive - FRESULT McuFatFS_chdrive(uint8_t Drive); ** getcwd - FRESULT McuFatFS_getcwd(TCHAR* Buffer, UINT BufferLen); ** errFResultMsg - char* McuFatFS_errFResultMsg(int errNo); ** errDResultMsg - char* McuFatFS_errDResultMsg(int errNo); ** f_gets - McuFatFS_CHARP McuFatFS_f_gets(TCHAR* buff, int len, FIL *fil); ** f_puts - McuFatFS_INT McuFatFS_f_puts(const TCHAR* str, FIL *fil); ** f_putc - McuFatFS_INT McuFatFS_f_putc(TCHAR c, FIL *fil); ** f_printf - McuFatFS_INT McuFatFS_f_printf(FIL* fil, const TCHAR* str, ...); ** f_eof - byte McuFatFS_f_eof(FIL *fil); ** f_error - uint8_t McuFatFS_f_error(FIL *fil); ** f_tell - dword McuFatFS_f_tell(FIL *fil); ** f_size - dword McuFatFS_f_size(FIL *fil); ** f_getlabel - FRESULT McuFatFS_f_getlabel(const TCHAR* path, TCHAR* label, DWORD* vsn); ** f_setlabel - FRESULT McuFatFS_f_setlabel(const TCHAR* label); ** f_expand - FRESULT McuFatFS_f_expand(FIL* fp, FSIZE_t fsz, BYTE opt); ** f_findfirst - FRESULT McuFatFS_f_findfirst(DIR* dp, FILINFO* fno, const TCHAR* path, const... ** f_findnext - FRESULT McuFatFS_f_findnext(DIR* dp, FILINFO* fno); ** f_opendir - FRESULT McuFatFS_f_opendir(DIR* dp, const TCHAR* path); ** f_readdir - FRESULT McuFatFS_f_readdir(DIR *dj, FILINFO *fno); ** f_closedir - FRESULT McuFatFS_f_closedir(DIR* dp); ** get_fattime - uint32_t McuFatFS_get_fattime(void); ** ParseCommand - uint8_t McuFatFS_ParseCommand(const unsigned char *cmd, bool *handled, const... ** StrToDriveNumber - uint8_t McuFatFS_StrToDriveNumber(uint8_t *drvStr); ** CheckCardPresence - uint8_t McuFatFS_CheckCardPresence(bool *cardMounted, uint8_t *drive, FATFS... ** MountFileSystem - uint8_t McuFatFS_MountFileSystem(FATFS *fileSystemObject, uint8_t... ** UnMountFileSystem - uint8_t McuFatFS_UnMountFileSystem(uint8_t *logicalDrive, const... ** PrintDirectory - uint8_t McuFatFS_PrintDirectory(const uint8_t *dirName, const... ** CopyFile - uint8_t McuFatFS_CopyFile(const uint8_t*srcFileName, const uint8_t... ** DeleteFile - uint8_t McuFatFS_DeleteFile(const uint8_t *fileName, const... ** CreateFile - uint8_t McuFatFS_CreateFile(const uint8_t *fileName, const... ** PrintFile - uint8_t McuFatFS_PrintFile(const uint8_t *fileName, const... ** PrintHexFile - uint8_t McuFatFS_PrintHexFile(const uint8_t *fileName, const... ** MakeDirectory - uint8_t McuFatFS_MakeDirectory(const uint8_t *dirName, const... ** ChangeDirectory - uint8_t McuFatFS_ChangeDirectory(const uint8_t *dirName, const... ** RenameFile - uint8_t McuFatFS_RenameFile(const uint8_t *srcFileName, const uint8_t... ** PrintSector - uint8_t McuFatFS_PrintSector(uint8_t drive, uint32_t sectorNo, const... ** PrintDiskInfo - uint8_t McuFatFS_PrintDiskInfo(uint8_t *drive, const... ** Benchmark - uint8_t McuFatFS_Benchmark(const %@Shell@'ModuleName'%.StdIOType *io); ** Deinit - uint8_t McuFatFS_Deinit(void); ** Init - uint8_t McuFatFS_Init(void); ** ** Copyright (c) 2014-2021, Erich Styger ** Web: http://mcuoneclipse.com/ ** SourceForge: https://sourceforge.net/projects/mcuoneclipse ** Git: https://github.com/ErichStyger/McuOnEclipse_PEx ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without modification, ** are permitted provided that the following conditions are met: ** - Redistributions of source code must retain the above copyright notice, this list ** of conditions and the following disclaimer. ** - Redistributions in binary form must reproduce the above copyright notice, this ** list of conditions and the following disclaimer in the documentation and/or ** other materials provided with the distribution. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ###################################################################*/ /*! ** @file McuFatFS.h ** @version 01.00 ** @brief ** */ /*! ** @addtogroup McuFatFS_module McuFatFS module documentation ** @{ */ /* MODULE McuFatFS. */ #include "ff.h" #include "McuFatFS.h" #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT #include "SDCard.h" #endif /*-----------------------------------------------------------------------*/ #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT /* Initialize a Drive */ DSTATUS disk_initialize ( uint8_t drv /* Physical drive number (0..) */ ) { switch(drv) { case 0: return SDCard_disk_initialize(drv); default: break; } /* switch */ return (DSTATUS)RES_PARERR; } #endif /*-----------------------------------------------------------------------*/ #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT /* Return Disk Status */ DSTATUS disk_status ( uint8_t drv /* Physical drive number (0..) */ ) { switch(drv) { case 0: return SDCard_disk_status(drv); default: break; } /* switch */ return (DSTATUS)RES_PARERR; } #endif /*-----------------------------------------------------------------------*/ #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT /* Read Sector(s) */ DRESULT disk_read ( uint8_t drv, /* Physical drive number (0..) */ uint8_t *buff, /* Data buffer to store read data */ uint32_t sector, /* Sector address (LBA) */ unsigned int count /* Number of sectors to read */ ) { switch(drv) { case 0: return SDCard_disk_read(drv, buff, sector, count); default: break; } /* switch */ return RES_PARERR; } #endif /*-----------------------------------------------------------------------*/ #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT /* Write Sector(s) */ #if _READONLY == 0 DRESULT disk_write ( uint8_t drv, /* Physical drive number (0..) */ const uint8_t *buff, /* Data to be written */ uint32_t sector, /* Sector address (LBA) */ unsigned int count /* Number of sectors to write */ ) { switch(drv) { case 0: return SDCard_disk_write(drv, buff, sector, count); default: break; } /* switch */ return RES_PARERR; } #endif /* _READONLY == 0 */ #endif /*-----------------------------------------------------------------------*/ #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT DRESULT disk_ioctl ( uint8_t drv, /* Physical drive number (0..) */ uint8_t ctrl, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { switch(drv) { case 0: return SDCard_disk_ioctl(drv, ctrl, buff); default: break; } /* switch */ return RES_PARERR; } #endif /*-----------------------------------------------------------------------*/ #define McuFatFS_8_3_SIZE sizeof("0:/12345678.txt") /* length of a 8.3 file name (13 including the zero byte) including the optional drive letter */ #if McuFatFS_USE_LFN == 0 /* No LFN */ #define McuFatFS_DEF_NAMEBUF(name) uint8_t name[McuFatFS_8_3_SIZE] #define McuFatFS_PTR_NAMEBUF(name) &name[0] #define McuFatFS_SIZE_NAMEBUF(name) sizeof(name) #define McuFatFS_INIT_NAMEBUF(name) #define McuFatFS_FREE_NAMEBUF(name) #elif McuFatFS_USE_LFN == 1 /* LFN with static LFN working buffer */ static TCHAR McuFatFS_FileName[McuFatFS_MAX_LFN+1]; #define McuFatFS_DEF_NAMEBUF(name) #define McuFatFS_PTR_NAMEBUF(name) &McuFatFS_FileName[0] #define McuFatFS_SIZE_NAMEBUF(name) sizeof(McuFatFS_FileName) #define McuFatFS_INIT_NAMEBUF(name) #define McuFatFS_FREE_NAMEBUF(name) #elif McuFatFS_USE_LFN == 2 /* LFN with dynamic LFN working buffer on the stack */ #define McuFatFS_DEF_NAMEBUF(name) uint8_t name[McuFatFS_MAX_LFN+1] #define McuFatFS_PTR_NAMEBUF(name) &name[0] #define McuFatFS_SIZE_NAMEBUF(name) sizeof(name) #define McuFatFS_INIT_NAMEBUF(name) #define McuFatFS_FREE_NAMEBUF(name) #elif McuFatFS_USE_LFN == 3 /* LFN with dynamic LFN working buffer on the heap */ #define McuFatFS_DEF_NAMEBUF(name) uint8_t *name #define McuFatFS_PTR_NAMEBUF(name) name #define McuFatFS_SIZE_NAMEBUF(name) (McuFatFS_MAX_LFN+1) #define McuFatFS_INIT_NAMEBUF(name) { name = ff_memalloc(McuFatFS_MAX_LFN+1); \ if (!name) { \ McuShell_SendStr((unsigned char*)"ff_memalloc failed!", io->stdErr); \ return ERR_FAILED; \ } \ } #define McuFatFS_FREE_NAMEBUF(name) ff_memfree(name) #else #error Wrong LFN configuration. #endif static void FatFsFResultMsg(uint8_t *msg, McuFatFS_FRESULT errNo, const McuShell_StdIOType *io) { unsigned char buf[sizeof("1234")]; McuShell_SendStr((unsigned char*)"ERROR: ", io->stdErr); McuShell_SendStr(msg, io->stdErr); McuShell_SendStr((unsigned char*)": (", io->stdErr); McuUtility_Num16sToStr(buf, sizeof(buf), (int16_t)errNo); McuShell_SendStr(buf, io->stdErr); McuShell_SendStr((unsigned char*)") ", io->stdErr); McuShell_SendStr((unsigned char*)McuFatFS_errFResultMsg((int)errNo), io->stdErr); McuShell_SendStr((unsigned char*)"\r\n", io->stdErr); } static void FatFsDResultMsg(uint8_t *msg, McuFatFS_DRESULT errNo, const McuShell_StdIOType *io) { unsigned char buf[sizeof("1234")]; McuShell_SendStr((unsigned char*)"ERROR: ", io->stdErr); McuShell_SendStr(msg, io->stdErr); McuShell_SendStr((unsigned char*)": (", io->stdErr); McuUtility_Num16sToStr(buf, sizeof(buf), (int16_t)errNo); McuShell_SendStr(buf, io->stdErr); McuShell_SendStr((unsigned char*)") ", io->stdErr); McuShell_SendStr((unsigned char*)McuFatFS_errDResultMsg((int)errNo), io->stdErr); McuShell_SendStr((unsigned char*)"\r\n", io->stdErr); } static void CmdUsageError(const unsigned char *cmd, uint8_t *usage, const McuShell_StdIOType *io) { McuShell_SendStr((unsigned char*)"*** error while reading command: ", io->stdErr); McuShell_SendStr(cmd, io->stdErr); McuShell_SendStr((unsigned char*)"\r\n*** Usage: ", io->stdErr); McuShell_SendStr((unsigned char*)usage, io->stdErr); McuShell_SendStr((unsigned char*)"\r\n", io->stdErr); } static void PrintInASCII(uint8_t *buf, size_t bufSize, size_t LineLen, uint8_t nonASCIIchar, uint8_t fillChar, const McuShell_StdIOType *io) { unsigned int i; uint8_t ch; /* print in ASCII */ McuShell_SendCh(' ', io->stdOut); for (i=0; i= ' ' && ch <= 0x7f) { McuShell_SendCh(ch, io->stdOut); } else { McuShell_SendCh(nonASCIIchar, io->stdOut); /* place holder */ } } for (/*empty*/; istdOut); } } /*! * \brief Writes a directory listing of the given path * \param[in] dirPathPtr Pointer to a directory path string. Pass e.g. "0:/" for the root directory * \param[in] io Callback to write directory output * \return Error code, otherwise ERR_OK */ static uint8_t PrintDir(const uint8_t *dirPathPtr, const McuShell_StdIOType *io) { McuFatFS_FILINFO fInfo; McuFatFS_FRESULT fres; uint32_t p1; UINT s1, s2; McuFatFS_DIR dir; /* Directory object */ uint8_t buf[sizeof("yyyy-mm-dd hh:ss")+1]; #if !McuFatFS_FS_READONLY McuFatFS_FATFS *fs; #endif McuShell_SendStr((unsigned char*)"Directory of ", io->stdOut); McuShell_SendStr(dirPathPtr, io->stdOut); McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); fres = McuFatFS_f_opendir(&dir, (const TCHAR*)dirPathPtr); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"opendir failed", fres, io); return ERR_FAULT; } p1 = s1 = s2 = 0; for(;;) { fres = McuFatFS_readdir(&dir, &fInfo); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"readdir failed", fres, io); break; } if (!fInfo.fname[0]) { /* end of directory list */ break; } /* file attributes */ if (fInfo.fattrib & AM_DIR) { /* directory */ s2++; io->stdOut('D'); } else { s1++; p1 += fInfo.fsize; io->stdOut('-'); } if (fInfo.fattrib & AM_RDO) { /* read only */ io->stdOut('R'); } else { io->stdOut('-'); } if (fInfo.fattrib & AM_HID) { /* hidden */ io->stdOut('H'); } else { io->stdOut('-'); } if (fInfo.fattrib & AM_SYS) { /* system */ io->stdOut('S'); } else { io->stdOut('-'); } if (fInfo.fattrib & AM_ARC) { /* archive */ io->stdOut('A'); } else { io->stdOut('-'); } io->stdOut(' '); /* file date & time */ buf[0] = '\0'; McuUtility_strcatNum16sFormatted(buf, sizeof(buf), (int16_t)((fInfo.fdate >> 9) + 1980), ' ', 4); /* year */ McuUtility_strcat(buf, sizeof(buf), (unsigned char*)"-"); McuUtility_strcatNum16sFormatted(buf, sizeof(buf), (int16_t)((fInfo.fdate >> 5) & 15), '0', 2); /* month */ McuUtility_strcat(buf, sizeof(buf), (unsigned char*)"-"); McuUtility_strcatNum16sFormatted(buf, sizeof(buf), (int16_t)(fInfo.fdate & 31), '0', 2); /* day */ McuUtility_strcat(buf, sizeof(buf), (unsigned char*)" "); McuUtility_strcatNum16sFormatted(buf, sizeof(buf), (int16_t)((fInfo.ftime >> 11)), '0', 2); /* hour */ McuUtility_strcat(buf, sizeof(buf), (unsigned char*)":"); McuUtility_strcatNum16sFormatted(buf, sizeof(buf), (int16_t)((fInfo.ftime >> 5) & 63), '0', 2); /* minute */ McuShell_SendStr(buf, io->stdOut); io->stdOut(' '); buf[0] = '\0'; /* file size */ McuUtility_strcatNum32uFormatted(buf, sizeof(buf), fInfo.fsize, ' ', 10); /* size */ McuShell_SendStr(buf, io->stdOut); /* file name */ io->stdOut(' '); McuShell_SendStr((unsigned char*)fInfo.fname, io->stdOut); #if McuFatFS_USE_LFN io->stdOut(' '); McuShell_SendStr((unsigned char*)fInfo.altname, io->stdOut); #endif io->stdOut('\r'); io->stdOut('\n'); } /* number of files and bytes used */ buf[0] = '\0'; McuUtility_strcatNum16u(buf, sizeof(buf), (uint16_t)s1); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)" File(s), ", io->stdOut); buf[0] = '\0'; McuUtility_strcatNum32u(buf, sizeof(buf), p1); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)" bytes total\r\n", io->stdOut); /* number of directories and number of free bytes */ buf[0] = '\0'; McuUtility_strcatNum16u(buf, sizeof(buf), (uint16_t)s2); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)" Dir(s)", io->stdOut); #if !McuFatFS_FS_READONLY /* number of free bytes */ fres = McuFatFS_getfree((const TCHAR*)dirPathPtr, &p1, &fs); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"getfree failed", fres, io); } else { io->stdOut(','); io->stdOut(' '); buf[0] = '\0'; McuUtility_strcatNum32s(buf, sizeof(buf), (long)(p1*fs->csize/2)); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)" KBytes free", io->stdOut); } #endif (void)McuFatFS_f_closedir(&dir); /* close directory */ io->stdOut('\r'); io->stdOut('\n'); return ERR_OK; } static uint8_t DirCmd(const unsigned char *cmd, const McuShell_ConstStdIOType *io) { /* precondition: cmd starts with "dir" */ uint8_t res = ERR_OK; McuFatFS_DEF_NAMEBUF(fileName); McuFatFS_INIT_NAMEBUF(fileName); if (*(cmd+sizeof("dir")-1)== ' ') { /* space after "dir": read name */ if (McuUtility_ReadEscapedName(cmd+sizeof("dir"), (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), NULL, NULL, NULL)==ERR_OK ) { /* ok, have now directory name */ } else { McuShell_SendStr((unsigned char*)"reading directory name failed!\r\n", io->stdErr); res = ERR_FAILED; } } else { /* use current directory */ #if McuFatFS_FS_RPATH >= 2 McuFatFS_FRESULT fres; fres = McuFatFS_getcwd((TCHAR*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName)); if(fres!=FR_OK) { FatFsFResultMsg((unsigned char*)"getcwd failed", fres, io); res = ERR_FAILED; } else { /* ok, have now directory name */ } #else McuUtility_strcpy(McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), (unsigned char*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING); /* use root */ #endif } if (res == ERR_OK) { res = McuFatFS_PrintDirectory((const uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), io); } McuFatFS_FREE_NAMEBUF(fileName); return res; } static uint8_t CopyCmd(const unsigned char *cmd, const McuShell_ConstStdIOType *io) { /* precondition: cmd starts with "copy" */ uint8_t res = ERR_OK; size_t lenRead; McuFatFS_DEF_NAMEBUF(fileName); McuFatFS_DEF_NAMEBUF(fileName2); McuFatFS_INIT_NAMEBUF(fileName); McuFatFS_INIT_NAMEBUF(fileName2); if ( (McuUtility_ReadEscapedName(cmd+sizeof("copy"), (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), &lenRead, NULL, NULL)==ERR_OK) && *(cmd+sizeof("copy")+lenRead)==' ' && (McuUtility_ReadEscapedName(cmd+sizeof("copy")+lenRead+1, (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName2), McuFatFS_SIZE_NAMEBUF(fileName2), NULL, NULL, NULL)==ERR_OK) ) { res = McuFatFS_CopyFile((uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_PTR_NAMEBUF(fileName2), io); } else { CmdUsageError(cmd, (unsigned char*)"copy srcFileName dstFileName", io); res = ERR_FAILED; } McuFatFS_FREE_NAMEBUF(fileName); McuFatFS_FREE_NAMEBUF(fileName2); return res; } static uint8_t DeleteCmd(const unsigned char *cmd, const McuShell_ConstStdIOType *io) { /* precondition: cmd starts with "delete" */ uint8_t res = ERR_OK; McuFatFS_DEF_NAMEBUF(fileName); McuFatFS_INIT_NAMEBUF(fileName); if (McuUtility_ReadEscapedName(cmd+sizeof("delete"), (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), NULL, NULL, NULL)==ERR_OK ) { res = McuFatFS_DeleteFile((uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), io); } else { CmdUsageError(cmd, (unsigned char*)"delete fileName", io); res = ERR_FAILED; } McuFatFS_FREE_NAMEBUF(fileName); return res; } static uint8_t MkdirCmd(const unsigned char *cmd, const McuShell_ConstStdIOType *io) { /* precondition: cmd starts with "mkdir" */ uint8_t res = ERR_OK; McuFatFS_DEF_NAMEBUF(fileName); McuFatFS_INIT_NAMEBUF(fileName); if (McuUtility_ReadEscapedName(cmd+sizeof("mkdir"), (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), NULL, NULL, NULL)==ERR_OK ) { res = McuFatFS_MakeDirectory((uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), io); } else { CmdUsageError(cmd, (unsigned char*)"mkdir directoryName", io); res = ERR_FAILED; } McuFatFS_FREE_NAMEBUF(fileName); return res; } static uint8_t RenameCmd(const unsigned char *cmd, const McuShell_ConstStdIOType *io) { /* precondition: cmd starts with "rename" */ uint8_t res = ERR_OK; size_t lenRead; McuFatFS_DEF_NAMEBUF(fileName); McuFatFS_DEF_NAMEBUF(fileName2); McuFatFS_INIT_NAMEBUF(fileName); McuFatFS_INIT_NAMEBUF(fileName2); if ( (McuUtility_ReadEscapedName(cmd+sizeof("rename"), (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), &lenRead, NULL, NULL)==ERR_OK) && *(cmd+sizeof("rename")+lenRead)==' ' && (McuUtility_ReadEscapedName(cmd+sizeof("rename")+lenRead+1, (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName2), McuFatFS_SIZE_NAMEBUF(fileName2), NULL, NULL, NULL)==ERR_OK) ) { res = McuFatFS_RenameFile((unsigned char*)McuFatFS_PTR_NAMEBUF(fileName), (unsigned char*)McuFatFS_PTR_NAMEBUF(fileName2), io); } else { CmdUsageError(cmd, (unsigned char*)"rename srcFileName dstFileName", io); res = ERR_FAILED; } McuFatFS_FREE_NAMEBUF(fileName); McuFatFS_FREE_NAMEBUF(fileName2); return res; } static uint8_t SectorCmd(const unsigned char *cmd, const McuShell_ConstStdIOType *io) { /* precondition: cmd starts with "sector" */ uint8_t res; uint32_t sectorNo; const unsigned char *p = cmd+sizeof("printsector"); res = McuUtility_ScanDecimal32uNumber(&p, §orNo); if (res == ERR_OK) { /* format fine */ res = McuFatFS_PrintSector(0, sectorNo, io); if (res!=ERR_OK) { return res; } } else { CmdUsageError(cmd, (unsigned char*)"printsector ", io); return ERR_FAILED; } return ERR_OK; } static uint8_t PrintCmd(const unsigned char *cmd, const McuShell_ConstStdIOType *io) { /* precondition: cmd starts with "print" */ uint8_t res = ERR_OK; McuFatFS_DEF_NAMEBUF(fileName); McuFatFS_INIT_NAMEBUF(fileName); if (McuUtility_ReadEscapedName(cmd+sizeof("print"), (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), NULL, NULL, NULL)==ERR_OK ) { res = McuFatFS_PrintFile((uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), io); } else { CmdUsageError(cmd, (unsigned char*)"print fileName", io); res = ERR_FAILED; } McuFatFS_FREE_NAMEBUF(fileName); return res; } static uint8_t PrintHexCmd(const unsigned char *cmd, const McuShell_ConstStdIOType *io) { /* precondition: cmd starts with "printhex" */ uint8_t res = ERR_OK; McuFatFS_DEF_NAMEBUF(fileName); McuFatFS_INIT_NAMEBUF(fileName); if (McuUtility_ReadEscapedName(cmd+sizeof("printhex"), (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), NULL, NULL, NULL)==ERR_OK ) { res = McuFatFS_PrintHexFile((uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), io); } else { CmdUsageError(cmd, (unsigned char*)"printhex fileName", io); res = ERR_FAILED; } McuFatFS_FREE_NAMEBUF(fileName); return res; } static uint8_t CdCmd(const unsigned char *cmd, const McuShell_ConstStdIOType *io) { /* precondition: cmd starts with "cd" */ #if McuFatFS_FS_RPATH > 0 uint8_t res = ERR_OK; McuFatFS_DEF_NAMEBUF(fileName); McuFatFS_INIT_NAMEBUF(fileName); if (*(cmd+sizeof("cd")-1)== ' ') { /* space after "cd": read name */ if (McuUtility_ReadEscapedName(cmd+sizeof("cd"), (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), NULL, NULL, NULL)==ERR_OK ) { res = McuFatFS_ChangeDirectory((uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), io); } else { McuShell_SendStr((unsigned char*)"reading directory name failed!\r\n", io->stdErr); res = ERR_FAILED; } } else { /* print current directory */ #if McuFatFS_FS_RPATH >= 2 McuFatFS_FRESULT fres; fres = McuFatFS_getcwd((TCHAR*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName)); if(fres!=FR_OK) { FatFsFResultMsg((unsigned char*)"getcwd failed", fres, io); res = ERR_FAILED; } else { McuShell_SendStr((uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), io->stdOut); McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } #else McuUtility_strcpy(McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), (unsigned char*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING); /* use root */ #endif } McuFatFS_FREE_NAMEBUF(fileName); return res; #else (void)cmd; #warning "relative directories not enabled in FatFS!" McuShell_SendStr((unsigned char*)"relative directories not available in file system\r\n", io->stdErr); return ERR_FAILED; #endif } static uint8_t CreateCmd(const unsigned char *cmd, const McuShell_ConstStdIOType *io) { /* precondition: cmd starts with "create" */ uint8_t res = ERR_OK; McuFatFS_DEF_NAMEBUF(fileName); McuFatFS_INIT_NAMEBUF(fileName); if (McuUtility_ReadEscapedName(cmd+sizeof("create"), (uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), McuFatFS_SIZE_NAMEBUF(fileName), NULL, NULL, NULL)==ERR_OK ) { res = McuFatFS_CreateFile((uint8_t*)McuFatFS_PTR_NAMEBUF(fileName), io); } else { CmdUsageError(cmd, (unsigned char*)"create fileName", io); res = ERR_FAILED; } McuFatFS_FREE_NAMEBUF(fileName); return res; } static uint8_t PrintStatus(const McuShell_StdIOType *io) { McuShell_SendStatusStr((unsigned char*)"McuFatFS", (unsigned char*)"FatFs status\r\n", io->stdOut); McuShell_SendStatusStr((unsigned char*)" present", McuFatFS_isDiskPresent((uint8_t*)"0")?(unsigned char*)"drive0: yes\r\n":(unsigned char*)"drive0: no\r\n", io->stdOut); McuShell_SendStatusStr((unsigned char*)" protected", McuFatFS_isWriteProtected((uint8_t*)"0")?(unsigned char*)"drive0: yes\r\n":(unsigned char*)"drive0: no\r\n", io->stdOut); McuShell_SendStatusStr((unsigned char*)" default drv", (unsigned char*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING "\r\n", io->stdOut); return ERR_OK; } static uint8_t PrintHelp(const McuShell_StdIOType *io) { McuShell_SendHelpStr((unsigned char*)"McuFatFS", (unsigned char*)"Group of McuFatFS commands\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" help|status", (unsigned char*)"Print help or status information\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" cd []", (const unsigned char*)"Change the current directory or display the name of the current directory\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" dir []", (const unsigned char*)"Prints a directory\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" copy ", (const unsigned char*)"Copy a file\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" delete ", (const unsigned char*)"Delete a file\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" create ", (const unsigned char*)"Create a file\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" mkdir ", (const unsigned char*)"Create a directory\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" rename ", (const unsigned char*)"Rename a file\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" print ", (const unsigned char*)"Print a file\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" printhex ", (const unsigned char*)"Print a file as hexdump\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" printsector ", (const unsigned char*)"Print disk sector\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" diskinfo", (const unsigned char*)"Print disk information\r\n", io->stdOut); McuShell_SendHelpStr((unsigned char*)" benchmark", (const unsigned char*)"Run disk benchmark\r\n", io->stdOut); return ERR_OK; } /* Unicode support functions */ #if McuFatFS_USE_LFN /* Unicode - OEM code conversion */ #if McuFatFS_USE_LFN == 3 /* Memory functions */ void *ff_memalloc(UINT size) { /* Allocate memory block */ /* FreeRTOS */ return McuRTOS_pvPortMalloc(size); } void ff_memfree (void* ptr) { /* Free memory block */ /* FreeRTOS */ McuRTOS_vPortFree(ptr); } #endif #endif #if McuFatFS_FS_REENTRANT /*! * \brief Create a Synchronization Object * This function is called in f_mount function to create a new * synchronization object, such as semaphore and mutex. When a FALSE is * returned, the f_mount function fails with FR_INT_ERR. * \param[in] vol Corresponding logical drive being processed * \param[out] sobj Pointer to return the created sync object * \return TRUE: Function succeeded, FALSE: Could not create due to any error */ #if configSUPPORT_STATIC_ALLOCATION static StaticSemaphore_t xMutexBuffer[FF_VOLUMES]; #endif int ff_cre_syncobj(uint8_t vol, McuFatFS_SYNC_t *sobj) { (void)vol; /* argument not used */ #if configSUPPORT_STATIC_ALLOCATION *sobj = xSemaphoreCreateMutexStatic(&xMutexBuffer[vol]); #else *sobj = xSemaphoreCreateMutex(); /* create semaphore */ #endif if (*sobj!=NULL) { vQueueAddToRegistry(*sobj, "McuFatFS_Mutex"); } return (*sobj != NULL) ? TRUE : FALSE; } /*! * \brief Delete a Synchronization Object * This function is called in f_mount function to delete a synchronization * object that created with ff_cre_syncobj function. When a FALSE is * returned, the f_mount function fails with FR_INT_ERR. * \param[out] sobj Sync object tied to the logical drive to be deleted * \return TRUE: Function succeeded, FALSE: Could not create due to any error */ int ff_del_syncobj(McuFatFS_SYNC_t sobj) { vQueueUnregisterQueue(sobj); McuRTOS_vSemaphoreDelete(sobj); /* FreeRTOS: free up memory for semaphore */ return TRUE; /* everything ok */ } /*! * \brief Request Grant to Access the Volume * This function is called on entering file functions to lock the volume. * When a FALSE is returned, the file function fails with FR_TIMEOUT. * \param[in] sobj Sync object to wait * \return TRUE: Function succeeded, FALSE: Could not create due to any error */ int ff_req_grant (McuFatFS_SYNC_t sobj) { if (McuRTOS_xSemaphoreTake(sobj, McuFatFS_FS_TIMEOUT) == pdTRUE) { return TRUE; /* success */ } else { /* failed to get the sync object? */ return FALSE; /* failure */ } } /*! * \brief Release Grant to Access the Volume * This function is called on leaving file functions to unlock the volume. * \param[in] sobj Sync object to be signaled */ void ff_rel_grant (McuFatFS_SYNC_t sobj) { (void)McuRTOS_xSemaphoreGive(sobj); /* FreeRTOS */ } #endif /* McuFatFS_FS_REENTRANT */ /* ** =================================================================== ** Method : open (component FAT_FileSystem) ** ** Description : ** Open/Create a file ** Parameters : ** NAME - DESCRIPTION ** fp - Pointer to the blank file object structure ** path - Pointer to a null-terminated string that ** specifies the file name to create or open. ** mode - Specifies the type of access and open ** method for the file. It is specified by a ** combination of following flags. ** FA_READ: Specifies read access to the ** object. Data can be read from the file. ** Combine with FA_WRITE for read-write access. ** FA_WRITE: Specifies write access to the ** object. Data can be written to the file. ** Combine with FA_READ for read-write access. ** FA_OPEN_EXISTING: Opens the file. The ** function fails if the file is not existing. ** (Default) ** FA_OPEN_ALWAYS: Opens the file if it is ** existing. If not, a new file is created. To ** append data to the file, use f_lseek ** function after file open in this method. ** FA_CREATE_NEW: Creates a new file. The ** function fails if the file is already ** existing. ** FA_CREATE_ALWAYS: Creates a new file. If ** the file is existing, it is truncated and ** overwritten. ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_open(FIL *fp, const XCHAR *path, BYTE mode) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : close (component FAT_FileSystem) ** ** Description : ** Close a file ** Parameters : ** NAME - DESCRIPTION ** fp - Pointer to the open file object structure to ** be closed. ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_close(FIL *fp) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : read (component FAT_FileSystem) ** ** Description : ** Read file ** Parameters : ** NAME - DESCRIPTION ** fp - Pointer to the file object ** buff - Pointer to the data buffer ** btr - Number of bytes to read ** br - Pointer to the number of bytes read ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_read(FIL *fp, void *buff, UINT btr, UINT *br) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : write (component FAT_FileSystem) ** ** Description : ** Write to a file ** Parameters : ** NAME - DESCRIPTION ** fp - Pointer to the file object structure ** buff - Pointer to the data to be written ** btw - Number of bytes to write ** bw - Pointer to the variable to return number of ** bytes written ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_write(FIL *fp, const *void buff, UINT btw, UINT *bw) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : opendir (component FAT_FileSystem) ** ** Description : ** Open a directory ** Parameters : ** NAME - DESCRIPTION ** dj - Pointer to the blank directory object to be ** created. ** path - Pointer to the null-terminated string ** that specifies the directory name to be ** opened. ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_opendir(DIR *dj, const XCHAR *path) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : readdir (component FAT_FileSystem) ** ** Description : ** Read a directory item ** Parameters : ** NAME - DESCRIPTION ** dir - Pointer to the open directory object ** fno - Pointer to the file information structure ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_readdir(DIR *dj, FILINFO *fno) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : lseek (component FAT_FileSystem) ** ** Description : ** The f_lseek function moves the file read/write pointer of an ** open file object. It can also be used to increase the file ** size (cluster pre-allocation). ** Parameters : ** NAME - DESCRIPTION ** fp - Pointer to the file object ** ofs - File pointer from top of file ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_lseek(FIL *fp, DWORD ofs) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : unlink (component FAT_FileSystem) ** ** Description : ** Remove a file or directory ** Parameters : ** NAME - DESCRIPTION ** path - Pointer to the object name ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_unlink(const XCHAR *path) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : mount (component FAT_FileSystem) ** ** Description : ** Mount/unmount a logical drive ** Parameters : ** NAME - DESCRIPTION ** fs - pointer to the new file system object (NULL ** for unmount) ** * path - Logical drive number to be ** mounted/unmounted ** opt - options: 0:Do not mount (delayed mount), 1: ** Mount immediately ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_mount(FATFS *fs, const TCHAR* path, uint8_t opt) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : getfree (component FAT_FileSystem) ** ** Description : ** Get Number of Free Clusters ** Parameters : ** NAME - DESCRIPTION ** path - Pointer to the logical drive number ** (root dir) ** * nclst - Pointer to the variable to return ** number of free clusters ** fatfs - Pointer to pointer to file system ** object ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_getfree(const XCHAR *path, dword *nclst, FATFS **fatfs) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : sync (component FAT_FileSystem) ** ** Description : ** Flush cached data of a writing file ** Parameters : ** NAME - DESCRIPTION ** fp - Pointer to the file object ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_sync(FIL *fp) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : rename (component FAT_FileSystem) ** ** Description : ** Delete a file or directory ** Parameters : ** NAME - DESCRIPTION ** path_old - Pointer to old object name ** path_new - Pointer to new object name ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_rename(const XCHAR *path_old, const XCHAR *path_new) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : mkdir (component FAT_FileSystem) ** ** Description : ** Creates a directory ** Parameters : ** NAME - DESCRIPTION ** path - Name of directory to be created ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_mkdir(const XCHAR *path) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : chmod (component FAT_FileSystem) ** ** Description : ** Changes the attribute of a file or directory ** Following attribute flags to be set in one or more ** combination of the following flags. The specified flags are ** set and others are cleared. ** AM_RDO Read only ** AM_ARC Archive ** AM_SYS System ** AM_HID Hidden ** Parameters : ** NAME - DESCRIPTION ** FileName - Pointer to the file or directory ** Attribute - Attribute flags. Attribute ** flags to be set in one or more combination ** of the following flags. The specified flags ** are set and others are cleard. ** AttributeMask - Attribute mask. ** Attribute mask that specifies which ** attribute is changed. The specified ** aattributes are set or cleard. ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_chmod(const TCHAR* FileName, uint8_t Attribute, uint8_t AttributeMask) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : truncate (component FAT_FileSystem) ** ** Description : ** Truncates the file size. ** The truncate() function truncates the file size to the ** current file read/write point. This function has no effect ** if the file read/write pointer is already pointing end of ** the file. ** Parameters : ** NAME - DESCRIPTION ** * FileObject - Pointer to the file object ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_truncate(FIL *FileObject) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : stat (component FAT_FileSystem) ** ** Description : ** The f_stat gets the information of a file or directory. For ** details of the infomation, refer to the FILINFO structure ** and f_readdir function. This function is not supported in ** minimization level of >= 1. ** Parameters : ** NAME - DESCRIPTION ** FileName - Pointer to the file or directory ** path ** * FileInfo - Pointer to the FILINFO structure ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_stat(const TCHAR* FileName, FILINFO* FileInfo) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : utime (component FAT_FileSystem) ** ** Description : ** The f_utime function changes the timestamp of a file or ** directory ** Parameters : ** NAME - DESCRIPTION ** * FileName - Pointer to the file or directory ** path ** * TimeDate - Pointer to time and data to be ** set ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_utime(const TCHAR* FileName, const FILINFO* TimeDate) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : mkfs (component FAT_FileSystem) ** ** Description : ** The f_mkfs fucntion creates a file system on the drive. ** Parameters : ** NAME - DESCRIPTION ** drive - Logical drive number ** PartitioningRule - When 0 is given, ** a partition table is created into the ** master boot record and a primary DOS ** partition is created and then an FAT volume ** is created on the partition. This is called ** FDISK format and used for harddisk and ** memory cards. When 1 is given, the FAT ** volume starts from the first sector on the ** drive without partition table. This is ** called SFD format and used for floppy disk ** and most optical disk ** AllocSize - Size of the allocation unit. ** Force the allocation unit (cluster) size in ** unit of byte. The value must be power of 2 ** and between the sector size and 128 times ** sector size. When invalid value is ** specified, the cluster size is determined ** depends on the volume size. ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_mkfs(uint8_t drive, uint8_t PartitioningRule, UINT AllocSize) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : chdir (component FAT_FileSystem) ** ** Description : ** The f_chdir function changes the current directory of the ** logical drive. The current directory of a drive is ** initialized to the root directory when the drive is ** auto-mounted. Note that the current directory is retained in ** the each file system object so that it also affects other ** tasks that using the drive. ** Parameters : ** NAME - DESCRIPTION ** Path - Pointer to the path name ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_chdir(const TCHAR* Path) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : chdrive (component FAT_FileSystem) ** ** Description : ** The f_chdrive function changes the current drive. The ** initial value of the current drive number is 0. Note that ** the current drive is retained in a static variable so that ** it also affects other tasks that using the file functions. ** Parameters : ** NAME - DESCRIPTION ** Drive - Logical drive number ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_chdrive(uint8_t Drive) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : getcwd (component FAT_FileSystem) ** ** Description : ** The f_getcwd function retrieves the current directory of the ** current drive in full path string including drive number. ** Parameters : ** NAME - DESCRIPTION ** Buffer - Pointer to the buffer to receive the ** current directory string. ** BufferLen - Size of the buffer in unit of ** TCHAR. ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_getcwd(TCHAR* Buffer, UINT BufferLen) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : errFResultMsg (component FAT_FileSystem) ** ** Description : ** Returns for a given FatFs FRESULT error code a string ** Parameters : ** NAME - DESCRIPTION ** errNo - FatFs error code ** Returns : ** --- - Error code ** =================================================================== */ char* McuFatFS_errFResultMsg(int errNo) { switch(errNo) { case FR_OK: return (char*)"Succeeded"; case FR_DISK_ERR: return (char*)"A hard error occurred in the low level disk I/O layer"; case FR_INT_ERR: return (char*)"Assertion failed"; case FR_NOT_READY: return (char*)"The physical drive cannot work"; case FR_NO_FILE: return (char*)"Could not find the file"; case FR_NO_PATH: return (char*)"Could not find the path"; case FR_INVALID_NAME: return (char*)"The path name format is invalid"; case FR_DENIED: return (char*)"Access denied due to prohibited access or directory full"; case FR_EXIST: return (char*)"Access denied due to prohibited access"; case FR_INVALID_OBJECT: return (char*)"The file/directory object is invalid"; case FR_WRITE_PROTECTED: return (char*)"The physical drive is write protected"; case FR_INVALID_DRIVE: return (char*)"The logical drive number is invalid"; case FR_NOT_ENABLED: return (char*)"The volume has no work area"; case FR_NO_FILESYSTEM: return (char*)"There is no valid FAT volume on the physical drive"; case FR_MKFS_ABORTED: return (char*)"The f_mkfs() aborted due to any parameter error"; case FR_TIMEOUT: return (char*)"Could not get a grant to access the volume within defined period"; case FR_LOCKED: return (char*)"The operation is rejected according to the file sharing policy"; case FR_NOT_ENOUGH_CORE: return (char*)"LFN working buffer could not be allocated"; case FR_TOO_MANY_OPEN_FILES: return (char*)"Number of open files > _FS_SHARE"; /*default: return (char*)"unknown";*/ } /* switch */ return (char*)"*error*"; } /* ** =================================================================== ** Method : errDResultMsg (component FAT_FileSystem) ** ** Description : ** Returns for a given FatFs DRESULT error code a string ** Parameters : ** NAME - DESCRIPTION ** errNo - FatFs error code ** Returns : ** --- - Error code ** =================================================================== */ char* McuFatFS_errDResultMsg(int errNo) { switch(errNo) { case RES_OK: return (char*)"Successful"; case RES_ERROR: return (char*)"R/W Error"; case RES_WRPRT: return (char*)"Write Protected"; case RES_NOTRDY: return (char*)"Not Ready"; case RES_PARERR: return (char*)"Invalid Parameter"; /*default: return (char*)"unknown";*/ } /* switch */ return (char*)"*error*"; } /* ** =================================================================== ** Method : isWriteProtected (component FAT_FileSystem) ** ** Description : ** Determines if the file system is write protected. ** Parameters : ** NAME - DESCRIPTION ** * drvStr - Pointer to drive string, e.g. "" or ** "0" ** Returns : ** --- - TRUE if file system is write protected ** =================================================================== */ bool McuFatFS_isWriteProtected(uint8_t *drvStr) { #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT uint8_t drv; drv = McuFatFS_StrToDriveNumber(drvStr); switch(drv) { case 0: return SDCard_isWriteProtected(); default: break; } /* switch */ return TRUE; #else return McuFatFS_CONFIG_IS_WRITE_PROTECTED_CALLBACK(drvStr); #endif } /* ** =================================================================== ** Method : isDiskPresent (component FAT_FileSystem) ** ** Description : ** Determines if the disk is present or not (e.g. disk inserted). ** Parameters : ** NAME - DESCRIPTION ** * drvStr - drive string, "" or "0" or "1" ** Returns : ** --- - TRUE if file system is write protected ** =================================================================== */ bool McuFatFS_isDiskPresent(uint8_t *drvStr) { #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT uint8_t drv; drv = McuFatFS_StrToDriveNumber(drvStr); switch(drv) { case 0: return SDCard_CardPresent(); default: break; } /* switch */ return FALSE; #else return McuFatFS_CONFIG_IS_DISK_PRESENT_CALLBACK(drvStr); #endif } /* ** =================================================================== ** Method : f_gets (component FAT_FileSystem) ** ** Description : ** Get a string from the file ** Parameters : ** NAME - DESCRIPTION ** * buff - Pointer to the string buffer to read ** len - Size of string buffer (characters) ** fil - Pointer to the file object ** Returns : ** --- - zero (NULL) if failed, otherwise a string ** to the buffer is returned. ** =================================================================== */ /* McuFatFS_CHARP McuFatFS_f_gets(TCHAR* buff, int len, FIL *fil) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_puts (component FAT_FileSystem) ** ** Description : ** Put a string to the file ** Parameters : ** NAME - DESCRIPTION ** * buff - A character to be output ** fil - Pointer to the file object ** Returns : ** --- - number of characters written. ** =================================================================== */ /* McuFatFS_INT McuFatFS_f_puts(const TCHAR* str, FIL *fil) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_putc (component FAT_FileSystem) ** ** Description : ** Put a character to the file ** Parameters : ** NAME - DESCRIPTION ** * buff - A character to be output ** fil - Pointer to the file object ** Returns : ** --- - 1 if ok, EOF otherwise ** =================================================================== */ /* McuFatFS_INT McuFatFS_f_putc(TCHAR c, FIL *fil) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_printf (component FAT_FileSystem) ** ** Description : ** Put a formatted string to the file ** Parameters : ** NAME - DESCRIPTION ** Variable_1 - Pointer to the file object ** str - Pointer to the format string ** Variable_2 - Optional arguments... ** Returns : ** --- - Error code ** =================================================================== */ /* McuFatFS_INT McuFatFS_f_printf(FIL* fil, const TCHAR* str, ...) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_eof (component FAT_FileSystem) ** ** Description : ** Wrapper to to the f_eof() macro. Returns 1 if at the end of ** the file, 0 otherwise. ** Parameters : ** NAME - DESCRIPTION ** * fp - Pointer to file object ** Returns : ** --- - Error code ** =================================================================== */ /* uint8_t McuFatFS_f_eof(FIL *fil) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_error (component FAT_FileSystem) ** ** Description : ** Wrapper to to the f_eof() macro. Returns 1 if at the end of ** the file, 0 otherwise. ** Parameters : ** NAME - DESCRIPTION ** * fp - Pointer to file object ** Returns : ** --- - Error code ** =================================================================== */ /* uint8_t McuFatFS_f_error(FIL *fil) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_tell (component FAT_FileSystem) ** ** Description : ** Wrapper to to the f_tell() macro. Returns the file ** read/write pointer (0 on file open). ** Parameters : ** NAME - DESCRIPTION ** * fp - Pointer to file object ** Returns : ** --- - Error code ** =================================================================== */ /* dword McuFatFS_f_tell(FIL *fil) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_size (component FAT_FileSystem) ** ** Description : ** Wrapper to to the f_size() macro. Returns the file size. ** Parameters : ** NAME - DESCRIPTION ** * fp - Pointer to file object ** Returns : ** --- - Error code ** =================================================================== */ /* dword McuFatFS_f_size(FIL *fil) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : Init (component FAT_FileSystem) ** ** Description : ** Initializes the device driver. ** Parameters : None ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuFatFS_Init(void) { uint8_t res = ERR_OK; #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT if (SDCard_Init(NULL)!=ERR_OK) { res = ERR_FAILED; } #endif return res; } /* ** =================================================================== ** Method : Deinit (component FAT_FileSystem) ** ** Description : ** Deinitializes the driver. ** Parameters : None ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuFatFS_Deinit(void) { uint8_t res = ERR_OK; #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT if (SDCard_Deinit(NULL)!=ERR_OK) { res = ERR_FAILED; } #endif return res; } #if !McuFatFS_FS_READONLY /* ** =================================================================== ** Method : get_fattime (component FAT_FileSystem) ** ** Description : ** Returns the current time ** Parameters : None ** Returns : ** --- - Error code ** =================================================================== */ uint32_t McuFatFS_get_fattime(void) { /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */ /* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */ /* Pack date and time into a uint32_t variable */ TIMEREC time; DATEREC date; uint8_t res; res = McuTimeDate_GetTime(&time); /* get time information */ if (res!=ERR_OK) { return 0; /* failed */ } res = McuTimeDate_GetDate(&date); /* get date information */ if (res!=ERR_OK) { return 0; /* failed */ } return ((uint32_t)(date.Year - 1980) << 25) | ((uint32_t)date.Month << 21) | ((uint32_t)date.Day << 16) | ((uint32_t)time.Hour << 11) | ((uint32_t)time.Min << 5) | ((uint32_t)time.Sec); } uint32_t get_fattime(void) { return McuFatFS_get_fattime(); } #endif /* !McuFatFS_FS_READONLY */ /* ** =================================================================== ** Method : ParseCommand (component FAT_FileSystem) ** ** Description : ** Shell Command Line parser. This method is enabled/disabled ** depending on if you have the Shell enabled/disabled in the ** properties. ** Parameters : ** NAME - DESCRIPTION ** * cmd - Pointer to command string ** * handled - Pointer to variable which tells if ** the command has been handled or not ** * io - Pointer to I/O structure ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuFatFS_ParseCommand(const unsigned char *cmd, bool *handled, const McuShell_StdIOType *io) { if (McuUtility_strcmp((char*)cmd, McuShell_CMD_HELP)==0 || McuUtility_strcmp((char*)cmd, "McuFatFS help")==0) { *handled = TRUE; return PrintHelp(io); } else if ((McuUtility_strcmp((char*)cmd, McuShell_CMD_STATUS)==0) || (McuUtility_strcmp((char*)cmd, "McuFatFS status")==0)) { *handled = TRUE; return PrintStatus(io); } else if (McuUtility_strncmp((char*)cmd, "McuFatFS cd", sizeof("McuFatFS cd")-1)==0) { *handled = TRUE; return CdCmd(cmd+sizeof("McuFatFS"), io); } else if (McuUtility_strncmp((char*)cmd, "McuFatFS dir", sizeof("McuFatFS dir")-1)==0) { *handled = TRUE; return DirCmd(cmd+sizeof("McuFatFS"), io); } else if (McuUtility_strncmp((char*)cmd, "McuFatFS copy ", sizeof("McuFatFS copy ")-1)==0) { *handled = TRUE; return CopyCmd(cmd+sizeof("McuFatFS"), io); } else if (McuUtility_strncmp((char*)cmd, "McuFatFS delete ", sizeof("McuFatFS delete ")-1)==0) { *handled = TRUE; return DeleteCmd(cmd+sizeof("McuFatFS"), io); } else if (McuUtility_strncmp((char*)cmd, "McuFatFS create ", sizeof("McuFatFS create ")-1)==0) { *handled = TRUE; return CreateCmd(cmd+sizeof("McuFatFS"), io); } else if (McuUtility_strncmp((char*)cmd, "McuFatFS mkdir ", sizeof("McuFatFS mkdir ")-1)==0) { *handled = TRUE; return MkdirCmd(cmd+sizeof("McuFatFS"), io); } else if (McuUtility_strncmp((char*)cmd, "McuFatFS rename ", sizeof("McuFatFS rename ")-1)==0) { *handled = TRUE; return RenameCmd(cmd+sizeof("McuFatFS"), io); } else if (McuUtility_strncmp((char*)cmd, "McuFatFS printhex ", sizeof("McuFatFS printhex ")-1)==0) { *handled = TRUE; return PrintHexCmd(cmd+sizeof("McuFatFS"), io); } else if (McuUtility_strncmp((char*)cmd, "McuFatFS printsector ", sizeof("McuFatFS printsector ")-1)==0) { *handled = TRUE; return SectorCmd(cmd+sizeof("McuFatFS"), io); } else if (McuUtility_strncmp((char*)cmd, "McuFatFS print ", sizeof("McuFatFS print ")-1)==0) { *handled = TRUE; return PrintCmd(cmd+sizeof("McuFatFS"), io); } else if (McuUtility_strcmp((char*)cmd, "McuFatFS diskinfo")==0) { *handled = TRUE; return McuFatFS_PrintDiskInfo((unsigned char*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING, io); } else if (McuUtility_strcmp((char*)cmd, "McuFatFS benchmark")==0) { *handled = TRUE; return McuFatFS_Benchmark(io); } return ERR_OK; } /* ** =================================================================== ** Method : CheckCardPresence (component FAT_FileSystem) ** ** Description : ** This method checks if card has been inserted or removed and ** mounts or unmounts the file system. ** Parameters : ** NAME - DESCRIPTION ** * cardMounted - Pointer to initialize this ** variable to FALSE on the caller side the ** first time. ** * drive - drive string, or "" ** * fileSystemObject - Pointer to file ** system object ** io - Pointer to io handler to be used. Can be ** NULL, then no messages are written. ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuFatFS_CheckCardPresence(bool *cardMounted, uint8_t *drive, FATFS *fileSystemObject, const McuShell_StdIOType *io) { if (drive==NULL) { /* backward compatibility with drive numbers before (which could be zero or NULL) */ drive = (unsigned char*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING; } if (!(*cardMounted) && McuFatFS_isDiskPresent(drive)) { /* card inserted */ #if McuFatFS_CONFIG_CARD_INSERT_DELAY_TIME_MS>0 McuWait_WaitOSms(McuFatFS_CONFIG_CARD_INSERT_DELAY_TIME_MS); /* give card some time to power up */ #endif if (McuFatFS_MountFileSystem(fileSystemObject, drive, io)==ERR_OK) { *cardMounted = TRUE; if (io!=NULL) { McuShell_SendStr((unsigned char*)"File System mounted\r\n", io->stdOut); } #if (McuFatFS_FS_RPATH >= 1U && McuFatFS_VOLUMES >= 2) if (f_chdrive((char const *)drive)!=FR_OK) { /* change default drive */ return ERR_FAILED; } #endif } else { return ERR_FAILED; } } else if (*cardMounted && !McuFatFS_isDiskPresent(drive)) { /* card removed */ if (McuFatFS_UnMountFileSystem(drive, io)==ERR_OK) { *cardMounted = FALSE; if (io!=NULL) { McuShell_SendStr((unsigned char*)"File System unmounted\r\n", io->stdOut); } } else { return ERR_FAILED; } } return ERR_OK; } /* ** =================================================================== ** Method : MountFileSystem (component FAT_FileSystem) ** ** Description : ** Mounts a file system ** Parameters : ** NAME - DESCRIPTION ** * fileSystemObject - Pointer to a ** file system object ** * logicalDrive - Pointer to the drive ** string, or "" ** * io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ /*! * \brief Mounts the file system for a drive * \param[in] fileSystemObject Pointer to the file system object * \param[in] logicalDrive The drive number to be used * \param[in] io IO handler for output * \return Error code, ERR_OK for success. */ uint8_t McuFatFS_MountFileSystem(FATFS *fileSystemObject, uint8_t *logicalDrive, const McuShell_StdIOType *io) { McuFatFS_FRESULT fres; fres = McuFatFS_mount(fileSystemObject, (const TCHAR*)logicalDrive, 1 /* 1: mount immediately; 0: delayed mount */); if (fres != FR_OK) { if (io!=NULL) { FatFsFResultMsg((unsigned char*)"mount failed", fres, io); } return ERR_FAILED; } return ERR_OK; } /* ** =================================================================== ** Method : UnMountFileSystem (component FAT_FileSystem) ** ** Description : ** Mounts a file system ** Parameters : ** NAME - DESCRIPTION ** * logicalDrive - Pointer to the drive ** string, or "" ** * io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ /*! * \brief Unmounts the file system for a drive * \param[in] logicalDrive The drive number to be used * \param[in] io IO handler for output * \return Error code, ERR_OK for success. */ uint8_t McuFatFS_UnMountFileSystem(uint8_t *logicalDrive, const McuShell_StdIOType *io) { McuFatFS_FRESULT fres; fres = McuFatFS_mount(NULL, (const TCHAR*)logicalDrive, 0); if (fres != FR_OK) { if (io!=NULL) { FatFsFResultMsg((unsigned char*)"unmount failed", fres, io); } return ERR_FAILED; } return ERR_OK; } /* ** =================================================================== ** Method : PrintDirectory (component FAT_FileSystem) ** ** Description : ** Prints a directory ** Parameters : ** NAME - DESCRIPTION ** dirName - Directory folder to be printed ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ /*! * \brief Prints a directory listing * \param[in] dirName Directory to be used * \param[in] io IO handler for output * \return Error code, ERR_OK for success. */ uint8_t McuFatFS_PrintDirectory(const uint8_t *dirName, const McuShell_StdIOType *io) { uint8_t res; res = PrintDir(dirName, io); if (res != ERR_OK) { McuShell_SendStr((unsigned char*)"PrintDir failed\r\n", io->stdErr); return res; } return ERR_OK; } /* ** =================================================================== ** Method : CopyFile (component FAT_FileSystem) ** ** Description : ** Copy a file ** Parameters : ** NAME - DESCRIPTION ** srcFileName - Source file name ** dstFileName - Destination file name ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ /*! * \brief Copy the source file to a destination file * \param[in] srcFileName Source file name * \param[in] dstFileName Destination file name * \param[in] io IO handler for output * \return Error code, ERR_OK for success. */ uint8_t McuFatFS_CopyFile(const uint8_t*srcFileName, const uint8_t *dstFileName, const McuShell_StdIOType *io) { #if !McuFatFS_FS_READONLY McuFatFS_FIL fsrc, fdst; /* file objects */ McuFatFS_FRESULT fres; uint8_t buffer[32]; /* copy buffer */ UINT br, bw; /* file read/write counters */ uint8_t res = ERR_OK; if (McuFatFS_isWriteProtected((uint8_t*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING)) { McuShell_SendStr((unsigned char*)"disk is write protected!\r\n", io->stdErr); return ERR_FAILED; } /* open source file */ fres = McuFatFS_open(&fsrc, (const TCHAR*)srcFileName, FA_OPEN_EXISTING | FA_READ); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"open source file failed", fres, io); return ERR_FAILED; } /* create destination file */ fres = McuFatFS_open(&fdst, (const TCHAR*)dstFileName, FA_CREATE_ALWAYS | FA_WRITE); if (fres != FR_OK) { (void)McuFatFS_close(&fsrc); /* close the source file which we have open */ FatFsFResultMsg((unsigned char*)"open destination file failed", fres, io); return ERR_FAILED; } /* now copy source to destination */ for (;;) { fres = McuFatFS_read(&fsrc, buffer, sizeof(buffer), &br); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"reading source file failed", fres, io); res = ERR_FAILED; break; } if (br == 0) { /* EOF */ break; /* get out of loop */ } fres = McuFatFS_write(&fdst, buffer, br, &bw); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"writing destination file failed", fres, io); res = ERR_FAILED; break; } if (bw < br) { McuShell_SendStr((unsigned char*)"failed writing destination file, or disk full\r\n", io->stdErr); res = ERR_FAILED; break; } } /* for */ /* close all files */ fres = McuFatFS_close(&fsrc); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"closing source file failed", fres, io); res = ERR_FAILED; } fres = McuFatFS_close(&fdst); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"closing destination file failed", fres, io); res = ERR_FAILED; } return res; #else (void)srcFileName; /* unused argument */ (void)dstFileName; /* unused argument */ McuShell_SendStr((unsigned char*)"File System is in Read-Only mode\r\n", io->stdErr); return ERR_FAILED; #endif } /* ** =================================================================== ** Method : DeleteFile (component FAT_FileSystem) ** ** Description : ** Deletes a file ** Parameters : ** NAME - DESCRIPTION ** fileName - Filename of file to be deleted ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ /*! * \brief Deletes a file * \param[in] fileName Name of file to be deleted * \param[in] io IO handler for output * \return Error code, ERR_OK for success. */ uint8_t McuFatFS_DeleteFile(const uint8_t *fileName, const McuShell_StdIOType *io) { McuFatFS_FRESULT fres; if (McuFatFS_isWriteProtected((uint8_t*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING)) { McuShell_SendStr((unsigned char*)"disk is write protected!\r\n", io->stdErr); return ERR_FAILED; } fres = McuFatFS_unlink((const TCHAR*)fileName); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"unlink failed", fres, io); return ERR_FAILED; } return ERR_OK; } /* ** =================================================================== ** Method : CreateFile (component FAT_FileSystem) ** ** Description : ** Creates an empty file ** Parameters : ** NAME - DESCRIPTION ** fileName - Filename of file to be created ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuFatFS_CreateFile(const uint8_t *fileName, const McuShell_StdIOType *io) { McuFatFS_FRESULT fres; FIL fp; if (McuFatFS_isWriteProtected((uint8_t*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING)) { McuShell_SendStr((unsigned char*)"disk is write protected!\r\n", io->stdErr); return ERR_FAILED; } fres = McuFatFS_open(&fp, (const TCHAR*)fileName, FA_CREATE_NEW); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"creating new file failed", fres, io); return ERR_FAILED; } fres = McuFatFS_close(&fp); if (fres != FR_OK) { FatFsFResultMsg((unsigned char*)"closing file failed", fres, io); return ERR_FAILED; } return ERR_OK; } /* ** =================================================================== ** Method : PrintFile (component FAT_FileSystem) ** ** Description : ** Prints the content of a file ** Parameters : ** NAME - DESCRIPTION ** fileName - Name of file to be printed ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ /*! * \brief Print the content of a file * \param[in] fileName Name of file to be printed * \param[in] io IO handler for output * \return Error code, ERR_OK for success. */ uint8_t McuFatFS_PrintFile(const uint8_t *fileName, const McuShell_StdIOType *io) { McuFatFS_FIL file; McuFatFS_FRESULT fres; UINT nofRead = 0; uint8_t buf[32]; uint8_t res = ERR_OK; fres = McuFatFS_open(&file, (const TCHAR *)fileName, FA_READ); if (fres == FR_OK) { do { nofRead = 0; fres=McuFatFS_read(&file, buf, sizeof(buf)-1, &nofRead); /* read one byte less for zero byte */ if (fres != FR_OK) { McuShell_SendStr((unsigned char*)"fread failed\r\n", io->stdErr); res = ERR_FAILED; } else { buf[nofRead] = '\0'; /* terminate buffer */ McuShell_SendStr(buf, io->stdOut); } } while(nofRead>0 && fres==FR_OK); fres=McuFatFS_close(&file); if (fres != FR_OK) { McuShell_SendStr((unsigned char*)"fclose failed\r\n", io->stdErr); res = ERR_FAILED; } } else { FatFsFResultMsg((unsigned char*)"open file failed", fres, io); res = ERR_FAILED; } McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); return res; } /* ** =================================================================== ** Method : PrintHexFile (component FAT_FileSystem) ** ** Description : ** Prints the content of a file in hexadecimal format, useful ** for binary files. ** Parameters : ** NAME - DESCRIPTION ** fileName - Name of file to be printed ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuFatFS_PrintHexFile(const uint8_t *fileName, const McuShell_StdIOType *io) { McuFatFS_FIL file; McuFatFS_FRESULT fres; UINT nofRead = 0; #define PRINT_HEX_NOF_BYTES_PER_LINE 16 uint8_t filebuf[PRINT_HEX_NOF_BYTES_PER_LINE]; uint8_t buf[16]; uint8_t res = ERR_OK; uint32_t address; UINT i; fres = McuFatFS_open(&file, (const TCHAR *)fileName, FA_READ); if (fres == FR_OK) { address = 0; do { nofRead = 0; fres=McuFatFS_read(&file, filebuf, sizeof(filebuf), &nofRead); /* read one byte less for zero byte */ if (fres != FR_OK) { McuShell_SendStr((unsigned char*)"fread failed\r\n", io->stdErr); res = ERR_FAILED; } else if (nofRead>0) { for(i=0; istdOut); buf[0] = '\0'; McuUtility_strcatNum32Hex(buf, sizeof(buf), address); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)": ", io->stdOut); address += PRINT_HEX_NOF_BYTES_PER_LINE; } buf[0] = '\0'; McuUtility_strcatNum8Hex(buf, sizeof(buf), filebuf[i]); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)" ", io->stdOut); } /* fill up line if not a full line */ for (/*empty*/; istdOut); } /* print in ASCII */ PrintInASCII(&filebuf[0], nofRead, PRINT_HEX_NOF_BYTES_PER_LINE, '.', '-', io); McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } } while(nofRead>0 && fres==FR_OK); fres=McuFatFS_close(&file); if (fres != FR_OK) { McuShell_SendStr((unsigned char*)"fclose failed\r\n", io->stdErr); res = ERR_FAILED; } } else { FatFsFResultMsg((unsigned char*)"open file failed\r\n", fres, io); res = ERR_FAILED; } return res; } /* ** =================================================================== ** Method : MakeDirectory (component FAT_FileSystem) ** ** Description : ** Creates a directory ** Parameters : ** NAME - DESCRIPTION ** dirName - Directory name ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ /*! * \brief Creates a new directory * \param[in] dirName Name of the directory to be created * \param[in] io IO handler for output * \return Error code, ERR_OK for success. */ uint8_t McuFatFS_MakeDirectory(const uint8_t *dirName, const McuShell_StdIOType *io) { McuFatFS_FRESULT fres; if (McuFatFS_isWriteProtected((uint8_t*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING)) { McuShell_SendStr((unsigned char*)"disk is write protected!\r\n", io->stdErr); return ERR_FAILED; } fres = McuFatFS_mkdir((const TCHAR*)dirName); if(fres!=FR_OK) { FatFsFResultMsg((unsigned char*)"mkdir failed", fres, io); return ERR_FAILED; } return ERR_OK; } /* ** =================================================================== ** Method : ChangeDirectory (component FAT_FileSystem) ** ** Description : ** Changes to a directory ** Parameters : ** NAME - DESCRIPTION ** dirName - Directory name ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuFatFS_ChangeDirectory(const uint8_t *dirName, const McuShell_StdIOType *io) { #if McuFatFS_FS_RPATH > 0 McuFatFS_FRESULT fres; if ((fres=McuFatFS_chdir((const TCHAR*)dirName)) != FR_OK) { FatFsFResultMsg((unsigned char*)"chdir failed", fres, io); return ERR_FAILED; } return ERR_OK; #else (void)dirName; #warning "relative directories not enabled in FatFS!" McuShell_SendStr((unsigned char*)"cd command not available as relative directories not enable in file system\r\n", io->stdErr); return ERR_FAILED; #endif } /* ** =================================================================== ** Method : RenameFile (component FAT_FileSystem) ** ** Description : ** Renames a file ** Parameters : ** NAME - DESCRIPTION ** srcFileName - Source file name ** dstFileName - Destination file name ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ /*! * \brief Renames a file * \param[in] srcFileName Source/existing file name * \param[in] dstFileName Destination/new file name * \param[in] io IO handler for output * \return Error code, ERR_OK for success. */ uint8_t McuFatFS_RenameFile(const uint8_t *srcFileName, const uint8_t *dstFileName, const McuShell_StdIOType *io) { McuFatFS_FRESULT fres; if (McuFatFS_isWriteProtected((uint8_t*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING)) { McuShell_SendStr((unsigned char*)"disk is write protected!\r\n", io->stdErr); return ERR_FAILED; } fres = McuFatFS_rename((const TCHAR*)srcFileName, (const TCHAR*)dstFileName); if(fres!=FR_OK) { FatFsFResultMsg((unsigned char*)"rename failed", fres, io); return ERR_FAILED; } return ERR_OK; } /* ** =================================================================== ** Method : PrintSector (component FAT_FileSystem) ** ** Description : ** Prints information about the current disk ** Parameters : ** NAME - DESCRIPTION ** drive - drive number, starting with zero ** sectorNo - sector number ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ #if McuFatFS_USE_RTOS_DYNAMIC_MEMORY #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT #define SECTOR_BUF_SIZE0 SDCard_BLOCK_SIZE #else #define SECTOR_BUF_SIZE0 512 #endif #else #if McuLib_CONFIG_SDK_VERSION_USED == McuLib_CONFIG_SDK_PROCESSOR_EXPERT static uint8_t print_buf0[SDCard_BLOCK_SIZE]; #define SECTOR_BUF_SIZE0 sizeof(print_buf0) #else static uint8_t print_buf0[512]; #define SECTOR_BUF_SIZE0 sizeof(print_buf0) #endif #endif uint8_t McuFatFS_PrintSector(uint8_t drive, uint32_t sectorNo, const McuShell_StdIOType *io) { #define PRINT_SECTOR_NOF_BYTES_PER_LINE 16 uint16_t i; unsigned char buf[8]; McuFatFS_DRESULT dres; #if McuFatFS_USE_RTOS_DYNAMIC_MEMORY #if configFRTOS_MEMORY_SCHEME==1 /* this scheme does not allow deallocation of memory */ static unsigned char *print_buf0=NULL; /* use global buffer pointer, allocated only once, and not deallocated! */ #else unsigned char *print_buf0; #endif #endif if ((disk_initialize(drive)&STA_NOINIT)!=(DSTATUS)RES_OK) { McuShell_SendStr((unsigned char*)"disk initialize failed\r\n", io->stdErr); return ERR_FAILED; } #if McuFatFS_USE_RTOS_DYNAMIC_MEMORY #if configFRTOS_MEMORY_SCHEME==1 /* this scheme does not allow deallocation of memory */ if (print_buf0==NULL) { /* only if not allocated yet */ print_buf0 = pvPortMalloc(SECTOR_BUF_SIZE0); } #else print_buf0 = pvPortMalloc(SECTOR_BUF_SIZE0); #endif if (print_buf0 == NULL) { McuShell_SendStr((unsigned char*)"allocating memory failed\r\n", io->stdErr); return ERR_FAILED; } #endif dres = disk_read(drive, &print_buf0[0], sectorNo, 1); if (dres==RES_OK) { /* read one sector */ McuShell_SendStr((unsigned char*)"dumping disk sector: 0x", io->stdOut); buf[0] = '\0'; McuUtility_strcatNum32Hex(buf, sizeof(buf), sectorNo); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)", sector size ", io->stdOut); McuShell_SendNum32u(SECTOR_BUF_SIZE0, io->stdOut); for(i=0; istdOut); buf[0] = '\0'; McuUtility_strcatNum16Hex(buf, sizeof(buf), i); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)": ", io->stdOut); } buf[0] = '\0'; McuUtility_strcatNum8Hex(buf, sizeof(buf), (uint8_t)print_buf0[i]); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)" ", io->stdOut); } PrintInASCII(&print_buf0[i-PRINT_SECTOR_NOF_BYTES_PER_LINE], PRINT_SECTOR_NOF_BYTES_PER_LINE, PRINT_SECTOR_NOF_BYTES_PER_LINE, '.', '-', io); McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } else { FatFsDResultMsg((unsigned char*)"disk_read failed", dres, io); } #if McuFatFS_USE_RTOS_DYNAMIC_MEMORY #if configFRTOS_MEMORY_SCHEME!=1 /* this scheme does not allow deallocation of memory */ vPortFree(print_buf0); #endif #endif if (dres==RES_OK) { return ERR_OK; } else { return ERR_FAILED; } } /* ** =================================================================== ** Method : PrintDiskInfo (component FAT_FileSystem) ** ** Description : ** Prints information about the current disk ** Parameters : ** NAME - DESCRIPTION ** * drive - Drive string, can be NULL or e.g. ** pointing to "0" ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ /*! * \brief Prints information about the disk * \param[in] drive Disk drive number, starting with zero * \param[in] io IO handler for output * \return Error code, ERR_OK for success. */ uint8_t McuFatFS_PrintDiskInfo(uint8_t *drvStr, const McuShell_StdIOType *io) { /* see for details: * http://www.retroleum.co.uk/electronics-articles/basic-mmc-card-access/ */ uint8_t buf[8]; int32_t val32; int16_t val16; int8_t val8; uint8_t buff[64]; uint8_t driverVersion; /* 0: SPI, 1: SDHC_LDD */ uint8_t driveNr; driveNr = McuFatFS_StrToDriveNumber(drvStr); if (!McuFatFS_isDiskPresent(drvStr)) { McuShell_SendStr((unsigned char*)"disk not present!\r\n", io->stdErr); return ERR_FAILED; } if ((disk_initialize(McuFatFS_StrToDriveNumber(drvStr))&STA_NOINIT)!=0) { McuShell_SendStr((unsigned char*)"disk initialize failed!\r\n", io->stdErr); return ERR_FAILED; } if (disk_ioctl(driveNr, MMC_GET_DRIVER_VERSION, &driverVersion)!=RES_OK) { McuShell_SendStr((unsigned char*)"failed identification of driver version\r\n", io->stdErr); return ERR_FAILED; } McuShell_SendStatusStr((unsigned char*)"Card type", (unsigned char*)"", io->stdOut); if (disk_ioctl(driveNr, MMC_GET_TYPE, &val8)==RES_OK) { if (val8&CT_SD1) { McuShell_SendStr((unsigned char*)"SD1 ", io->stdOut); } if (val8&CT_SD2) { McuShell_SendStr((unsigned char*)"SD2 ", io->stdOut); } if (val8&CT_BLOCK) { McuShell_SendStr((unsigned char*)"BLOCK ", io->stdOut); } if (val8&CT_MMC) { McuShell_SendStr((unsigned char*)"MMC ", io->stdOut); } if (val8&CT_SDC) { McuShell_SendStr((unsigned char*)"SDC ", io->stdOut); } if (val8&CT_ATA) { McuShell_SendStr((unsigned char*)"ATA ", io->stdOut); } McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } else { McuShell_SendStr((unsigned char*)"ERROR\r\n", io->stdOut); } if (driverVersion==0) { /* only SPI cards implement this */ McuShell_SendStatusStr((unsigned char*)"SDC version", (unsigned char*)"", io->stdOut); if (disk_ioctl(driveNr, MMC_GET_SDC_VERSION, &val8)==RES_OK) { if (val8==1) { McuShell_SendStr((unsigned char*)"SDC ver 1.XX or MMC\r\n", io->stdOut); } else if (val8==2) { McuShell_SendStr((unsigned char*)"SDC ver 2.00\r\n", io->stdOut); } else { McuShell_SendStr((unsigned char*)"unknown\r\n", io->stdOut); } } else { McuShell_SendStr((unsigned char*)"ERROR\r\n", io->stdOut); } } McuShell_SendStatusStr((unsigned char*)"Sector count", (unsigned char*)"", io->stdOut); if (disk_ioctl(driveNr, GET_SECTOR_COUNT, &val32)==RES_OK) { McuUtility_Num32sToStr(buf, sizeof(buf), val32); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } else { McuShell_SendStr((unsigned char*)"ERROR\r\n", io->stdOut); } McuShell_SendStatusStr((unsigned char*)"Sector size", (unsigned char*)"", io->stdOut); if (disk_ioctl(driveNr, GET_SECTOR_SIZE, &val16)==RES_OK) { McuUtility_Num16sToStr(buf, sizeof(buf), val16); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } else { McuShell_SendStr((unsigned char*)"ERROR\r\n", io->stdOut); } McuShell_SendStatusStr((unsigned char*)"READ_BL_LEN", (unsigned char*)"", io->stdOut); if (disk_ioctl(driveNr, MMC_GET_READ_BL_LEN, &val16)==RES_OK) { McuUtility_Num16sToStr(buf, sizeof(buf), val16); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } else { McuShell_SendStr((unsigned char*)"ERROR\r\n", io->stdOut); } if (driverVersion==0) { /* only SPI cards implement this */ McuShell_SendStatusStr((unsigned char*)"Block size", (unsigned char*)"", io->stdOut); if (disk_ioctl(driveNr, GET_BLOCK_SIZE, &val32)==RES_OK) { McuUtility_Num32sToStr(buf, sizeof(buf), val32); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } else { McuShell_SendStr((unsigned char*)"ERROR\r\n", io->stdOut); } McuShell_SendStatusStr((unsigned char*)"CSD", (unsigned char*)"", io->stdOut); if (disk_ioctl(driveNr, MMC_GET_CSD, &buff[0])==RES_OK) { for(val8=0; val8<16; val8++) { buf[0] = '\0'; McuUtility_strcatNum8Hex(buf, sizeof(buf), (uint8_t)buff[val8]); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)" ", io->stdOut); } McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } else { McuShell_SendStr((unsigned char*)"ERROR\r\n", io->stdOut); } McuShell_SendStatusStr((unsigned char*)"CID", (unsigned char*)"", io->stdOut); if (disk_ioctl(driveNr, MMC_GET_CID, &buff[0])==RES_OK) { for(val8=0; val8<16; val8++) { buf[0] = '\0'; McuUtility_strcatNum8Hex(buf, sizeof(buf), (uint8_t)buff[val8]); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)" ", io->stdOut); } McuShell_SendStr((unsigned char*)"\r\n Manufacturer ", io->stdOut); for(val8=3; val8<=8; val8++) { io->stdOut(buff[val8]); } McuShell_SendStr((unsigned char*)"\r\n Serial Number ", io->stdOut); buf[0] = '\0'; McuUtility_strcatNum32Hex(buf, sizeof(buf), (uint32_t)((buff[0xa]<<24)|(buff[0xb]<<16)|(buff[0xc]<<8)|buff[0xd])); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } else { McuShell_SendStr((unsigned char*)"ERROR\r\n", io->stdOut); } McuShell_SendStatusStr((unsigned char*)"OCR", (unsigned char*)"", io->stdOut); if (disk_ioctl(driveNr, MMC_GET_OCR, &buff[0])==RES_OK) { for(val8=0; val8<4; val8++) { buf[0] = '\0'; McuUtility_strcatNum8Hex(buf, sizeof(buf), (uint8_t)buff[val8]); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)" ", io->stdOut); } McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } else { McuShell_SendStr((unsigned char*)"ERROR\r\n", io->stdOut); } McuShell_SendStatusStr((unsigned char*)"SD Status", (unsigned char*)"", io->stdOut); if (disk_ioctl(driveNr, MMC_GET_SDSTAT, &buff[0])==RES_OK) { for(val8=0; val8<64; val8++) { buf[0] = '\0'; if (val8!=0 && (val8%16)==0) { /* new line to make things readable */ McuShell_SendStr((unsigned char*)"\r\n ", io->stdOut); } McuUtility_strcatNum8Hex(buf, sizeof(buf), (uint8_t)buff[val8]); McuShell_SendStr(buf, io->stdOut); McuShell_SendStr((unsigned char*)" ", io->stdOut); } McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } else { McuShell_SendStr((unsigned char*)"ERROR\r\n", io->stdOut); } } if (driverVersion==1) { /* only LLD_SDHD cards implement this */ buff[1] = sizeof(buf)-2; /* size of buffer */ buff[0] = MMC_GET_LLD_CMD_HIGH_CAPACITY; /* cmd */ if (disk_ioctl(driveNr, MMC_GET_LLD_INFO, &buff[0])==RES_OK) { McuShell_SendStatusStr((unsigned char*)"High capacity", (unsigned char*)(buff[2]!=0?"yes\r\n":"no\r\n"), io->stdOut); } buff[0] = MMC_GET_LLD_CMD_HIGH_SPEED; /* cmd */ if (disk_ioctl(driveNr, MMC_GET_LLD_INFO, &buff[0])==RES_OK) { McuShell_SendStatusStr((unsigned char*)"High speed", (unsigned char*)(buff[2]!=0?"yes\r\n":"no\r\n"), io->stdOut); } buff[0] = MMC_GET_LLD_CMD_LOW_VOLTAGE; /* cmd */ if (disk_ioctl(driveNr, MMC_GET_LLD_INFO, &buff[0])==RES_OK) { McuShell_SendStatusStr((unsigned char*)"Low voltage", (unsigned char*)(buff[2]!=0?"yes\r\n":"no\r\n"), io->stdOut); } buff[0] = MMC_GET_LLD_CMD_DATA_WIDTHS; /* cmd */ if (disk_ioctl(driveNr, MMC_GET_LLD_INFO, &buff[0])==RES_OK) { McuShell_SendStatusStr((unsigned char*)"Data widths", (unsigned char*)"", io->stdOut); if (buff[2]&0x1) { McuShell_SendStr((unsigned char*)"1 ", io->stdOut); } if (buff[2]&0x2) { McuShell_SendStr((unsigned char*)"4 ", io->stdOut); } if (buff[2]&0x4) { McuShell_SendStr((unsigned char*)"8 ", io->stdOut); } McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } buff[0] = MMC_GET_LLD_CMD_OPERATIONS; /* cmd */ if (disk_ioctl(driveNr, MMC_GET_LLD_INFO, &buff[0])==RES_OK) { McuShell_SendStatusStr((unsigned char*)"Operations", (unsigned char*)"", io->stdOut); if (buff[2]&0x1) { McuShell_SendStr((unsigned char*)"BlockRead ", io->stdOut); } if (buff[2]&0x2) { McuShell_SendStr((unsigned char*)"BlockWrite ", io->stdOut); } if (buff[2]&0x4) { McuShell_SendStr((unsigned char*)"BlockErase ", io->stdOut); } if (buff[2]&0x8) { McuShell_SendStr((unsigned char*)"WriteProtect ", io->stdOut); } if (buff[2]&0x10) { McuShell_SendStr((unsigned char*)"I/O ", io->stdOut); } McuShell_SendStr((unsigned char*)"\r\n", io->stdOut); } } return ERR_OK; } /* ** =================================================================== ** Method : Benchmark (component FAT_FileSystem) ** ** Description : ** Performs a disk benchmark ** Parameters : ** NAME - DESCRIPTION ** io - Pointer to I/O handler ** Returns : ** --- - Error code ** =================================================================== */ /*! \brief Simple benchmark function: first we are going to write a file, then we will copy it */ uint8_t McuFatFS_Benchmark(const McuShell_StdIOType *io) { static FIL fp; uint16_t i; UINT bw; uint8_t read_buf[10]; TIMEREC time, startTime; int32_t start_mseconds, mseconds; if (McuFatFS_isWriteProtected((uint8_t*)McuFatFS_CONFIG_DEFAULT_DRIVE_STRING)) { McuShell_SendStr((unsigned char*)"disk is write protected!\r\n", io->stdErr); return ERR_FAILED; } /* write benchmark */ McuShell_SendStr((const unsigned char*)"Benchmark: write/copy/read a 100kB file:\r\n", io->stdOut); McuShell_SendStr((const unsigned char*)"Delete existing benchmark files...\r\n", io->stdOut); (void)McuFatFS_DeleteFile((const unsigned char*)"./bench.txt", io); (void)McuFatFS_DeleteFile((const unsigned char*)"./copy.txt", io); McuShell_SendStr((const unsigned char*)"Create benchmark file...\r\n", io->stdOut); (void)McuTimeDate_GetTime(&startTime); if (McuFatFS_open(&fp, (const TCHAR*)"./bench.txt", FA_CREATE_ALWAYS|FA_WRITE)!=FR_OK) { McuShell_SendStr((const unsigned char*)"*** Failed opening benchmark file!\r\n", io->stdErr); return ERR_FAILED; } for(i=0;i<10240;i++) { if (McuFatFS_write(&fp, "benchmark ", sizeof("benchmark ")-1, &bw)!=FR_OK) { McuShell_SendStr((const unsigned char*)"*** Failed writing file!\r\n", io->stdErr); (void)McuFatFS_close(&fp); return ERR_FAILED; } } (void)McuFatFS_close(&fp); (void)McuTimeDate_GetTime(&time); start_mseconds = startTime.Hour*60*60*1000 + startTime.Min*60*1000 + startTime.Sec*1000 #if McuTimeDate_HAS_SEC100_IN_TIMEREC + startTime.Sec100*10 #endif ; mseconds = time.Hour*60*60*1000 + time.Min*60*1000 + time.Sec*1000 #if McuTimeDate_HAS_SEC100_IN_TIMEREC + time.Sec100*10 #endif - start_mseconds; McuShell_SendNum32s(mseconds, io->stdOut); McuShell_SendStr((const unsigned char*)" ms for writing (", io->stdOut); McuShell_SendNum32s((100*1000)/mseconds, io->stdOut); McuShell_SendStr((const unsigned char*)" kB/s)\r\n", io->stdOut); /* read benchmark */ McuShell_SendStr((const unsigned char*)"Read 100kB benchmark file...\r\n", io->stdOut); (void)McuTimeDate_GetTime(&startTime); if (McuFatFS_open(&fp, (const TCHAR*)"./bench.txt", FA_READ)!=FR_OK) { McuShell_SendStr((const unsigned char*)"*** Failed opening benchmark file!\r\n", io->stdErr); return ERR_FAILED; } for(i=0;i<10240;i++) { if (McuFatFS_read(&fp, &read_buf[0], sizeof(read_buf), &bw)!=FR_OK) { McuShell_SendStr((const unsigned char*)"*** Failed reading file!\r\n", io->stdErr); (void)McuFatFS_close(&fp); return ERR_FAILED; } } (void)McuFatFS_close(&fp); (void)McuTimeDate_GetTime(&time); start_mseconds = startTime.Hour*60*60*1000 + startTime.Min*60*1000 + startTime.Sec*1000 #if McuTimeDate_HAS_SEC100_IN_TIMEREC + startTime.Sec100*10 #endif ; mseconds = time.Hour*60*60*1000 + time.Min*60*1000 + time.Sec*1000 #if McuTimeDate_HAS_SEC100_IN_TIMEREC + time.Sec100*10 #endif - start_mseconds; McuShell_SendNum32s(mseconds, io->stdOut); McuShell_SendStr((const unsigned char*)" ms for reading (", io->stdOut); McuShell_SendNum32s((100*1000)/mseconds, io->stdOut); McuShell_SendStr((const unsigned char*)" kB/s)\r\n", io->stdOut); /* copy benchmark */ McuShell_SendStr((const unsigned char*)"Copy 100kB file...\r\n", io->stdOut); (void)McuTimeDate_GetTime(&startTime); (void)McuFatFS_CopyFile((const unsigned char*)"./bench.txt", (const unsigned char*)"./copy.txt", io); (void)McuTimeDate_GetTime(&time); start_mseconds = startTime.Hour*60*60*1000 + startTime.Min*60*1000 + startTime.Sec*1000 #if McuTimeDate_HAS_SEC100_IN_TIMEREC + startTime.Sec100*10 #endif ; mseconds = time.Hour*60*60*1000 + time.Min*60*1000 + time.Sec*1000 #if McuTimeDate_HAS_SEC100_IN_TIMEREC + time.Sec100*10 #endif - start_mseconds; McuShell_SendNum32s(mseconds, io->stdOut); McuShell_SendStr((const unsigned char*)" ms for copy (", io->stdOut); McuShell_SendNum32s((100*1000)/mseconds, io->stdOut); McuShell_SendStr((const unsigned char*)" kB/s)\r\n", io->stdOut); McuShell_SendStr((const unsigned char*)"done!\r\n", io->stdOut); return ERR_OK; } /* ** =================================================================== ** Method : f_getlabel (component FAT_FileSystem) ** ** Description : ** Get volume label ** Parameters : ** NAME - DESCRIPTION ** * path - Pointer to path name of the logical ** drive number ** * label - Pointer to a buffer to return the ** volume label ** vsn - ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_f_getlabel(const TCHAR* path, TCHAR* label, DWORD* vsn) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_setlabel (component FAT_FileSystem) ** ** Description : ** Set Volume Label ** Parameters : ** NAME - DESCRIPTION ** * label - Pointer to the volume label to set ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_f_setlabel(const TCHAR* label) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_expand (component FAT_FileSystem) ** ** Description : ** Allocate a Contiguous Blocks to the File ** Parameters : ** NAME - DESCRIPTION ** * fp - Pointer to the file object ** fsz - File size to be expanded to ** opt - Operation mode 0:Find and prepare or 1: ** Find and allocate ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_f_expand(FIL* fp, FSIZE_t fsz, BYTE opt) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_findfirst (component FAT_FileSystem) ** ** Description : ** Find FirstFile ** Parameters : ** NAME - DESCRIPTION ** dp - Pointer to the open directory object ** fno - Pointer to the file information structure ** path - Pointer to the directory to open ** pattern - Pointer to the matching pattern ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_f_findfirst(DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_findnext (component FAT_FileSystem) ** ** Description : ** Find Next File ** Parameters : ** NAME - DESCRIPTION ** dp - Pointer to the open directory object ** fno - Pointer to the file information structure ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_f_findnext(DIR* dp, FILINFO* fno) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_opendir (component FAT_FileSystem) ** ** Description : ** Open a directory ** Parameters : ** NAME - DESCRIPTION ** dp - Pointer to the open directory object ** path - path of directory ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_f_opendir(DIR* dp, const TCHAR* path) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_closedir (component FAT_FileSystem) ** ** Description : ** Close a directory ** Parameters : ** NAME - DESCRIPTION ** dp - Pointer to the open directory object ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_f_closedir(DIR* dp) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : f_readdir (component FAT_FileSystem) ** ** Description : ** Read a directory item ** Parameters : ** NAME - DESCRIPTION ** dir - Pointer to the open directory object ** fno - Pointer to the file information structure ** Returns : ** --- - Error code ** =================================================================== */ /* FRESULT McuFatFS_f_readdir(DIR *dj, FILINFO *fno) { *** method is implemented as macro in the header file } */ /* ** =================================================================== ** Method : StrToDriveNumber (component FAT_FileSystem) ** ** Description : ** Transforms a drive string ("0:/") into a drive number (0) ** Parameters : ** NAME - DESCRIPTION ** * drvStr - Pointer to drive string, e.g. "0:/" ** Returns : ** --- - Error code ** =================================================================== */ uint8_t McuFatFS_StrToDriveNumber(uint8_t *drvStr) { uint8_t drv = 0; const unsigned char *p; if (drvStr==NULL || *drvStr=='\0') { /* default, "" */ drv = 0; } else { p = drvStr; if (McuUtility_ScanDecimal8uNumber(&p, &drv)!=ERR_OK) { /* "0", "1", ... */ drv = 0; /* error, use default number */ } } return drv; } /* END McuFatFS. */ /*! ** @} */