Files
MSE-SoftwEng/pico-sensor/McuLib/FatFS/McuFatFS.c
2025-05-06 13:07:01 +00:00

3021 lines
111 KiB
C

/* ###################################################################
** 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<bufSize; i++) {
ch = buf[i];
if (ch >= ' ' && ch <= 0x7f) {
McuShell_SendCh(ch, io->stdOut);
} else {
McuShell_SendCh(nonASCIIchar, io->stdOut); /* place holder */
}
}
for (/*empty*/; i<LineLen; i++) { /* fill up line */
McuShell_SendCh(fillChar, io->stdOut);
}
}
/*!
* \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, &sectorNo);
if (res == ERR_OK) { /* format fine */
res = McuFatFS_PrintSector(0, sectorNo, io);
if (res!=ERR_OK) {
return res;
}
} else {
CmdUsageError(cmd, (unsigned char*)"printsector <number>", 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 [<directoryName>]", (const unsigned char*)"Change the current directory or display the name of the current directory\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" dir [<directoryName>]", (const unsigned char*)"Prints a directory\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" copy <src> <dst>", (const unsigned char*)"Copy a file\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" delete <filename>", (const unsigned char*)"Delete a file\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" create <filename>", (const unsigned char*)"Create a file\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" mkdir <directory>", (const unsigned char*)"Create a directory\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" rename <src> <dst>", (const unsigned char*)"Rename a file\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" print <filename>", (const unsigned char*)"Print a file\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" printhex <filename>", (const unsigned char*)"Print a file as hexdump\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" printsector <number>", (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; i<nofRead; i++) {
if ((i%PRINT_HEX_NOF_BYTES_PER_LINE)==0) { /* new line to make things readable */
McuShell_SendStr((unsigned char*)"0x", io->stdOut);
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*/; i<PRINT_HEX_NOF_BYTES_PER_LINE; i++) {
McuShell_SendStr((unsigned char*)"-- ", io->stdOut);
}
/* 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; i<SECTOR_BUF_SIZE0; i++) {
if ((i%PRINT_SECTOR_NOF_BYTES_PER_LINE)==0) { /* new line to make things readable */
if (i!=0) { /* not for first line */
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\n0x", io->stdOut);
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. */
/*!
** @}
*/