/*----------------------------------------------------------------------*/ /* FAT file system sample project for FatFs (C)ChaN, 2014 */ /*----------------------------------------------------------------------*/ #include #include #include "ff.h" #include "ff_shell.h" #include "brtc.h" #include "date_calc.h" #include "xprintf.h" #include "diskio.h" #include "usart.h" #include "exfuns.h" #include "malloc.h" #include "delay.h" #include "boot_update.h" #include "includes.h" //ucos Use DWORD AccSize; /* Work register for fs command */ WORD AccFiles, AccDirs; FILINFO Finfo; #define FBUFF_MAX 4096 #define CLINE_MAX 256 #define WORK_SPACE_MAX 1024 BYTE *fBuff; char *cLine; BYTE *work_space; FATFS FatFs; /* File system object for each logical drive */ FIL File[2]; /* File objects */ DIR Dir; /* Directory object */ volatile UINT Timer; u8 sem_file_used = 0; u32 sem_file_time = 0; void ff_shell_init(void) { work_space = mymalloc(WORK_SPACE_MAX); } unsigned char ReqUseFatfs(void) { CPU_SR_ALLOC(); if (sem_file_used == 0) { CPU_CRITICAL_ENTER(); sem_file_used = 1; sem_file_time = 5000; CPU_CRITICAL_EXIT(); return 1; } else { return 0; } } unsigned char ReqUseFatfsWhile(void) { CPU_SR_ALLOC(); while (sem_file_used) { delay_os_ms(5); } CPU_CRITICAL_ENTER(); sem_file_used = 1; sem_file_time = 5000; CPU_CRITICAL_EXIT(); return 1; } void leaveFatfs(void) { sem_file_used = 0; } void UpdateFatfsSemTime(void) { CPU_SR_ALLOC(); CPU_CRITICAL_ENTER(); sem_file_time = 5000; CPU_CRITICAL_EXIT(); } void CheckTimeOutFatfsSem(void) { if (sem_file_used == 1) { if (sem_file_time == 0) sem_file_used = false; } } void DecFatfsSemTime(u32 tick) { if (sem_file_time > tick) sem_file_time -= tick; } int FileOpen(char *filename, int mode) { FRESULT rc; rc = f_open(&File[0], filename, mode); return (int)rc; } int FileClose(void) { return (int)f_close(&File[0]); } /*---------------------------------------------------------*/ /* User provided RTC function for FatFs module */ /*---------------------------------------------------------*/ /* This is a real time clock service to be called back */ /* from FatFs module. */ #if !_FS_NORTC && !_FS_READONLY //Access time //User defined function to give a current time to fatfs module */ //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) */ DWORD get_fattime (void) { /* Pack date and time into a DWORD variable */ return ((DWORD)(GetTimeYear() - 1980) << 25) | ((DWORD)GetTimeMonth() << 21) | ((DWORD)GetTimeDate() << 16) | ((DWORD)GetTimeHour() << 11) | ((DWORD)GetTimeMinute() << 5) | ((DWORD)GetTimeSec() >> 1); } #endif /*--------------------------------------------------------------------------*/ /* Monitor */ /*--------------------------------------------------------------------------*/ #ifdef CONSOLE_DEBUG static FRESULT scan_files ( char* path /* Pointer to the path name working buffer */ ) { DIR dirs; FRESULT res; BYTE i; char *fn; if ((res = f_opendir(&dirs, path)) == FR_OK) { i = strlen(path); while (((res = f_readdir(&dirs, &Finfo)) == FR_OK) && Finfo.fname[0]) { if (_FS_RPATH && Finfo.fname[0] == '.') continue; fn = Finfo.fname; if (Finfo.fattrib & AM_DIR) { AccDirs++; *(path+i) = '/'; strcpy(path+i+1, fn); res = scan_files(path); *(path+i) = '\0'; if (res != FR_OK) break; } else { /* printf("%s/%s\r\n", path, fn); */ AccFiles++; AccSize += Finfo.fsize; } } } return res; } void put_rc (FRESULT rc) { const char *str = "OK\0" "DISK_ERR\0" "INT_ERR\0" "NOT_READY\0" "NO_FILE\0" "NO_PATH\0" "INVALID_NAME\0" "DENIED\0" "EXIST\0" "INVALID_OBJECT\0" "WRITE_PROTECTED\0" "INVALID_DRIVE\0" "NOT_ENABLED\0" "NO_FILE_SYSTEM\0" "MKFS_ABORTED\0" "TIMEOUT\0" "LOCKED\0" "NOT_ENOUGH_CORE\0" "TOO_MANY_OPEN_FILES\0"; BYTE i; for (i = 0; i != (BYTE)rc && *str; i++) { while (*str++) ; } printf("rc=%u FR_%s\r\n", (UINT)rc, str); } static const char HelpMsg[] = "[Disk contorls]\r\n" " di - Initialize disk\r\n" " dd [ ] - Dump a secrtor\r\n" " ds - Show disk status\r\n" "[Buffer controls]\r\n" " bd - Dump working buffer\r\n" " be [] ... - Edit working buffer\r\n" " br [] - Read disk into working buffer\r\n" " bw [] - Write working buffer into disk\r\n" " bf - Fill working buffer\r\n" "[File system controls]\r\n" " fi []- Force initialized the volume\r\n" " fs [] - Show volume status\r\n" " fl [] - Show a directory\r\n" " fo - Open a file\r\n" " fc - Close the file\r\n" " fe - Move fp in normal seek\r\n" " fd - Read and dump the file\r\n" " fr - Read the file\r\n" " fw - Write to the file\r\n" " fn - Rename an object\r\n" " fu - Unlink an object\r\n" " fv - Truncate the file at current fp\r\n" " fk - Create a directory\r\n" " fa - Change attribute of an object\r\n" " ft - Change timestamp of an object\r\n" " fx - Copy a file\r\n" " fg - Change current directory\r\n" " fq - Show current directory\r\n" " fb - Set volume label\r\n" " fm - Create file system\r\n" " fz [] - Change/Show R/W length for fr/fw/fx command\r\n" "[Misc commands]\r\n" " md[b|h|w] [] - Dump memory\r\n" " mf - Fill memory\r\n" " me[b|h|w] [ ...] - Edit memory\r\n" " t [ ] - Set/Show RTC\r\n" "\r\n"; void ff_process(void) { char *ptr, *ptr2; long p1, p2, p3; BYTE res, b, drv = 0; // UINT s1, s2, cnt, blen = sizeof Buff; UINT s1, s2, cnt, blen = FBUFF_MAX; static const BYTE ft[] = {0, 12, 16, 32}; // static const char days[] = "Sun\0Mon\0Tue\0Wed\0Thu\0Fri\0Sat"; DWORD ofs = 0, sect = 0, blk[2]; FATFS *fs; printf("\r\nFile system monitor\r\n"); printf(_USE_LFN ? "LFN Enabled" : "LFN Disabled"); printf(", Code page: %u\r\n", _CODE_PAGE); /* Initiazlize RTC */ printf("Current time is %u/%u/%u %2u:%02u:%02u.\r\n", GetTimeYear(), GetTimeMonth(), GetTimeDate(), GetTimeHour(), GetTimeMinute(), GetTimeSec() ); fBuff = mymalloc(blen); cLine = mymalloc(CLINE_MAX); if ((fBuff == NULL)||(cLine == NULL)) { printf("FATFS MEM Error. \r\n"); return; } for (;;) { if (f_getcwd(cLine, CLINE_MAX) == FR_OK) printf("%s>", cLine); else printf(">"); xgets(cLine, CLINE_MAX); ptr = cLine; switch (*ptr++) { case 'q': myfree(fBuff); myfree(cLine); return; case '?' : /* Show Command List */ printf(HelpMsg); xputs(HelpMsg); break; case 'l': switch (*ptr++) { case 's': while (*ptr == ' ') ptr++; res = f_opendir(&Dir, ptr); if (res) { put_rc((FRESULT)res); break; } p1 = s1 = s2 = 0; for(;;) { res = f_readdir(&Dir, &Finfo); if ((res != FR_OK) || !Finfo.fname[0]) break; if (Finfo.fattrib & AM_DIR) { s2++; } else { s1++; p1 += Finfo.fsize; } printf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %-12s %s\r\n", (Finfo.fattrib & AM_DIR) ? 'D' : '-', (Finfo.fattrib & AM_RDO) ? 'R' : '-', (Finfo.fattrib & AM_HID) ? 'H' : '-', (Finfo.fattrib & AM_SYS) ? 'S' : '-', (Finfo.fattrib & AM_ARC) ? 'A' : '-', (Finfo.fdate >> 9) + 1980, (Finfo.fdate >> 5) & 15, Finfo.fdate & 31, (Finfo.ftime >> 11), (Finfo.ftime >> 5) & 63, Finfo.fsize, Finfo.fname, ""); } printf("%c%c", Dir.dir[0], Dir.dir[1]); printf("%4u File(s),%10lu bytes total\r\n%4u Dir(s)", s1, p1, s2); res = f_getfree(ptr, (DWORD*)&p1, &fs); if (res == FR_OK) printf(", %10lu bytes free\r\n", p1 * fs->csize * 512); else put_rc((FRESULT)res); break; } break; case 'c': switch (*ptr++) { case 'd': while (*ptr == ' ') ptr++; put_rc(f_chdir(ptr)); break; } break; case 'm' : /* Memory dump/fill/edit */ switch (*ptr++) { case 'd' : /* md[b|h|w]
[] - Dump memory */ switch (*ptr++) { case 'w': p3 = DW_LONG; break; case 'h': p3 = DW_SHORT; break; default: p3 = DW_CHAR; } if (!xatoi(&ptr, &p1)) break; if (!xatoi(&ptr, &p2)) p2 = 128 / p3; for (ptr = (char*)p1; p2 >= 16 / p3; ptr += 16, p2 -= 16 / p3) put_dump(ptr, (DWORD)ptr, 16 / p3, p3); if (p2) put_dump((BYTE*)ptr, (UINT)ptr, p2, p3); break; case 'f' : /* mf
- Fill memory */ if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break; while (p3--) { *(BYTE*)p1 = (BYTE)p2; p1++; } break; case 'e' : /* me[b|h|w]
[ ...] - Edit memory */ switch (*ptr++) { /* Get data width */ case 'w': p3 = DW_LONG; break; case 'h': p3 = DW_SHORT; break; default: p3 = DW_CHAR; } if (!xatoi(&ptr, &p1)) break; /* Get start address */ if (xatoi(&ptr, &p2)) { /* 2nd parameter is given (direct mode) */ do { switch (p3) { case DW_LONG: *(DWORD*)p1 = (DWORD)p2; break; case DW_SHORT: *(WORD*)p1 = (WORD)p2; break; default: *(BYTE*)p1 = (BYTE)p2; } p1 += p3; } while (xatoi(&ptr, &p2)); /* Get next value */ break; } for (;;) { /* 2nd parameter is not given (interactive mode) */ switch (p3) { case DW_LONG: printf("%08X 0x%08X-", (u32)p1, (u32)*(DWORD*)p1); break; case DW_SHORT: printf("%08X 0x%04X-", (u32)p1, (u32)*(WORD*)p1); break; default: printf("%08X 0x%02X-", (u32)p1, *(BYTE*)p1); } ptr = cLine; xgets(ptr, sizeof cLine); if (*ptr == '.') break; if ((BYTE)*ptr >= ' ') { if (!xatoi(&ptr, &p2)) continue; switch (p3) { case DW_LONG: *(DWORD*)p1 = (DWORD)p2; break; case DW_SHORT: *(WORD*)p1 = (WORD)p2; break; default: *(BYTE*)p1 = (BYTE)p2; } } p1 += p3; } break; } break; case 'd' : /* Disk I/O layer controls */ switch (*ptr++) { case 'd' : /* dd [ ] - Dump secrtor */ if (!xatoi(&ptr, &p1)) { p1 = drv; p2 = sect; } else { if (!xatoi(&ptr, &p2)) break; } drv = (BYTE)p1; sect = p2; res = disk_read(drv, fBuff, sect, 1); if (res) { printf("rc=%d\r\n", (WORD)res); break; } printf("PD#:%u LBA:%lu\r\n", drv, sect++); for (ptr=(char*)fBuff, ofs = 0; ofs < 0x200; ptr += 16, ofs += 16) put_dump((BYTE*)ptr, ofs, 16, DW_CHAR); break; case 'i' : /* di - Initialize disk */ if (!xatoi(&ptr, &p1)) break; printf("rc=%d\r\n", (WORD)disk_initialize((BYTE)p1)); break; case 's' : /* ds - Show disk status */ if (!xatoi(&ptr, &p1)) break; if (disk_ioctl((BYTE)p1, GET_SECTOR_COUNT, &p2) == RES_OK) { printf("Drive size: %lu sectors\r\n", p2); } if (disk_ioctl((BYTE)p1, GET_BLOCK_SIZE, &p2) == RES_OK) { printf("Block size: %lu sectors\r\n", p2); } if (disk_ioctl((BYTE)p1, MMC_GET_TYPE, &b) == RES_OK) { printf("Media type: %u\r\n", b); } if (disk_ioctl((BYTE)p1, MMC_GET_CSD, fBuff) == RES_OK) { printf("CSD:\r\n"); put_dump(fBuff, 0, 16, DW_CHAR); } if (disk_ioctl((BYTE)p1, MMC_GET_CID, fBuff) == RES_OK) { printf("CID:\r\n"); put_dump(fBuff, 0, 16, DW_CHAR); } if (disk_ioctl((BYTE)p1, MMC_GET_OCR, fBuff) == RES_OK) { printf("OCR:\r\n"); put_dump(fBuff, 0, 4, DW_CHAR); } if (disk_ioctl((BYTE)p1, MMC_GET_SDSTAT, fBuff) == RES_OK) { printf("SD Status:\r\n"); for (s1 = 0; s1 < 64; s1 += 16) put_dump(fBuff + s1, s1, 16, DW_CHAR); } break; case 'c' : /* Disk ioctl */ switch (*ptr++) { case 's' : /* dcs - CTRL_SYNC */ if (!xatoi(&ptr, &p1)) break; printf("rc=%d\r\n", disk_ioctl((BYTE)p1, CTRL_SYNC, 0)); break; case 'e' : /* dce - CTRL_TRIM */ if (!xatoi(&ptr, &p1) || !xatoi(&ptr, (long*)&blk[0]) || !xatoi(&ptr, (long*)&blk[1])) break; printf("rc=%d\r\n", disk_ioctl((BYTE)p1, CTRL_TRIM, blk)); break; } break; } break; case 'b' : /* Buffer controls */ switch (*ptr++) { case 'd' : /* bd - Dump R/W buffer */ if (!xatoi(&ptr, &p1)) break; for (ptr=(char*)&fBuff[p1], ofs = p1, cnt = 32; cnt; cnt--, ptr+=16, ofs+=16) put_dump((BYTE*)ptr, ofs, 16, DW_CHAR); break; case 'e' : /* be [] ... - Edit R/W buffer */ if (!xatoi(&ptr, &p1)) break; if (xatoi(&ptr, &p2)) { do { fBuff[p1++] = (BYTE)p2; } while (xatoi(&ptr, &p2)); break; } for (;;) { printf("%04X %02X-", (WORD)(p1), (WORD)fBuff[p1]); xgets(cLine, sizeof cLine); ptr = cLine; if (*ptr == '.') break; if (*ptr < ' ') { p1++; continue; } if (xatoi(&ptr, &p2)) fBuff[p1++] = (BYTE)p2; else printf("???\r\n"); } break; case 'r' : /* br [] - Read disk into R/W buffer */ if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break; if (!xatoi(&ptr, &p3)) p3 = 1; printf("rc=%u\r\n", (WORD)disk_read((BYTE)p1, fBuff, p2, p3)); break; case 'w' : /* bw [] - Write R/W buffer into disk */ if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break; if (!xatoi(&ptr, &p3)) p3 = 1; printf("rc=%u\r\n", (WORD)disk_write((BYTE)p1, fBuff, p2, p3)); break; case 'f' : /* bf - Fill working buffer */ if (!xatoi(&ptr, &p1)) break; memset(fBuff, (BYTE)p1, FBUFF_MAX); break; #ifdef BOOT_UPDATE case 'u': BootUpdateProcess(); break; case 'z': BootSectorCompare(); break; #endif // #ifdef BOOT_UPDATE } break; case 'f' : /* FatFS API controls */ switch (*ptr++) { #if _FS_RPATH && _VOLUMES >= 2 case 'f': while (*ptr == ' ') ptr++; put_rc(f_chdrive(ptr)); break; #endif case 'i' : /* fi []- Initialize logical drive */ if (!xatoi(&ptr, &p2)) p2 = 0; // f_mount(fs[1],"1:",1); put_rc(f_mount(&FatFs, "1:", (BYTE)p2)); break; case 's' : /* fs [] - Show volume status */ while (*ptr == ' ') ptr++; res = f_getfree(ptr, (DWORD*)&p1, &fs); if (res) { put_rc((FRESULT)res); break; } printf("FAT type = FAT%u\r\nBytes/Cluster = %lu\r\nNumber of FATs = %u\r\n" "Root DIR entries = %u\r\nSectors/FAT = %lu\r\nNumber of clusters = %lu\r\n" "Volume start (lba) = %lu\r\nFAT start (lba) = %lu\r\nDIR start (lba,clustor) = %lu\r\nData start (lba) = %lu\r\n\r\n", ft[fs->fs_type & 3], (DWORD)fs->csize * 512, fs->n_fats, fs->n_rootdir, fs->fsize, (DWORD)fs->n_fatent - 2, fs->volbase, fs->fatbase, fs->dirbase, fs->database); #if _USE_LABEL res = f_getlabel(ptr, (char*)fBuff, (DWORD*)&p2); if (res) { put_rc((FRESULT)res); break; } fBuff[0] ? printf("Volume name is %s\r\n", (char *)fBuff) : printf("No volume label\r\n"); // printf(fBuff[0] ? "Volume name is %s\r\n" : "No volume label\r\n", (char *)fBuff); printf("Volume S/N is %04X-%04X\r\n", (u32)((DWORD)p2 >> 16), (u32)((DWORD)p2 & 0xFFFF)); #endif AccSize = AccFiles = AccDirs = 0; printf("..."); res = scan_files(ptr); if (res) { put_rc((FRESULT)res); break; } printf("\r%u files, %lu bytes.\r\n%u folders.\r\n" "%lu KiB total disk space.\r\n%lu KiB available.\r\n", AccFiles, AccSize, AccDirs, (fs->n_fatent - 2) * (fs->csize / 2), (DWORD)p1 * (fs->csize / 2) ); break; case 'l' : /* fl [] - Directory listing */ while (*ptr == ' ') ptr++; res = f_opendir(&Dir, ptr); if (res) { put_rc((FRESULT)res); break; } p1 = s1 = s2 = 0; for(;;) { res = f_readdir(&Dir, &Finfo); if ((res != FR_OK) || !Finfo.fname[0]) break; if (Finfo.fattrib & AM_DIR) { s2++; } else { s1++; p1 += Finfo.fsize; } printf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %-12s %s\r\n", (Finfo.fattrib & AM_DIR) ? 'D' : '-', (Finfo.fattrib & AM_RDO) ? 'R' : '-', (Finfo.fattrib & AM_HID) ? 'H' : '-', (Finfo.fattrib & AM_SYS) ? 'S' : '-', (Finfo.fattrib & AM_ARC) ? 'A' : '-', (Finfo.fdate >> 9) + 1980, (Finfo.fdate >> 5) & 15, Finfo.fdate & 31, (Finfo.ftime >> 11), (Finfo.ftime >> 5) & 63, Finfo.fsize, Finfo.fname, ""); } printf("%c%c", Dir.dir[0], Dir.dir[1]); printf("%4u File(s),%10lu bytes total\r\n%4u Dir(s)", s1, p1, s2); res = f_getfree(ptr, (DWORD*)&p1, &fs); if (res == FR_OK) printf(", %10lu bytes free\r\n", p1 * fs->csize * 512); else put_rc((FRESULT)res); break; case 'o' : /* fo - Open a file */ if (!xatoi(&ptr, &p1)) break; while (*ptr == ' ') ptr++; put_rc(f_open(&File[0], ptr, (BYTE)p1)); break; case 'c' : /* fc - Close a file */ put_rc(f_close(&File[0])); break; case 'e' : /* fe - Seek file pointer */ if (!xatoi(&ptr, &p1)) break; res = f_lseek(&File[0], p1); put_rc((FRESULT)res); if (res == FR_OK) printf("fptr=%lu(0x%lX)\r\n", File[0].fptr, File[0].fptr); break; case 'd' : /* fd - read and dump file from current fp */ if (!xatoi(&ptr, &p1)) break; ofs = File[0].fptr; while (p1) { if ((UINT)p1 >= 16) { cnt = 16; p1 -= 16; } else { cnt = p1; p1 = 0; } res = f_read(&File[0], fBuff, cnt, &cnt); if (res != FR_OK) { put_rc((FRESULT)res); break; } if (!cnt) break; put_dump(fBuff, ofs, cnt, DW_CHAR); ofs += 16; } break; case 'r' : /* fr - read file */ if (!xatoi(&ptr, &p1)) break; p2 = 0; Timer = 0; while (p1) { if ((UINT)p1 >= blen) { cnt = blen; p1 -= blen; } else { cnt = p1; p1 = 0; } res = f_read(&File[0], fBuff, cnt, &s2); if (res != FR_OK) { put_rc((FRESULT)res); break; } p2 += s2; if (cnt != s2) break; } printf("%lu bytes read with %lu kB/sec.\r\n", p2, Timer ? (p2 / Timer) : 0); break; case 'w' : /* fw - write file */ if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break; memset(fBuff, (BYTE)p2, blen); p2 = 0; Timer = 0; while (p1) { if ((UINT)p1 >= blen) { cnt = blen; p1 -= blen; } else { cnt = p1; p1 = 0; } res = f_write(&File[0], fBuff, cnt, &s2); if (res != FR_OK) { put_rc((FRESULT)res); break; } p2 += s2; if (cnt != s2) break; } printf("%lu bytes written with %lu kB/sec.\r\n", p2, Timer ? (p2 / Timer) : 0); break; case 'n' : /* fn - Change name of an object */ while (*ptr == ' ') ptr++; ptr2 = strchr(ptr, ' '); if (!ptr2) break; *ptr2++ = 0; while (*ptr2 == ' ') ptr2++; put_rc(f_rename(ptr, ptr2)); break; case 'u' : /* fu - Unlink an object */ while (*ptr == ' ') ptr++; put_rc(f_unlink(ptr)); break; case 'v' : /* fv - Truncate file */ put_rc(f_truncate(&File[0])); break; case 'k' : /* fk - Create a directory */ while (*ptr == ' ') ptr++; put_rc(f_mkdir(ptr)); break; case 'a' : /* fa - Change attribute of an object */ if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break; while (*ptr == ' ') ptr++; put_rc(f_chmod(ptr, p1, p2)); break; case 't' : /* ft - Change timestamp of an object */ if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break; Finfo.fdate = ((p1 - 1980) << 9) | ((p2 & 15) << 5) | (p3 & 31); if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break; Finfo.ftime = ((p1 & 31) << 11) | ((p2 & 63) << 5) | ((p3 >> 1) & 31); put_rc(f_utime(ptr, &Finfo)); break; case 'x' : /* fx - Copy a file */ while (*ptr == ' ') ptr++; ptr2 = strchr(ptr, ' '); if (!ptr2) break; *ptr2++ = 0; while (*ptr2 == ' ') ptr2++; printf("Opening \"%s\"", ptr); res = f_open(&File[0], ptr, FA_OPEN_EXISTING | FA_READ); printf("\r\n"); if (res) { put_rc((FRESULT)res); break; } printf("Creating \"%s\"", ptr2); res = f_open(&File[1], ptr2, FA_CREATE_ALWAYS | FA_WRITE); printf("\r\n"); if (res) { put_rc((FRESULT)res); f_close(&File[0]); break; } printf("Copying file..."); Timer = 0; p1 = 0; for (;;) { res = f_read(&File[0], fBuff, blen, &s1); if (res || s1 == 0) break; /* error or eof */ res = f_write(&File[1], fBuff, s1, &s2); p1 += s2; if (res || s2 < s1) break; /* error or disk full */ } printf("\r\n%lu bytes copied with %lu kB/sec.\r\n", p1, p1 / Timer); f_close(&File[0]); f_close(&File[1]); break; #if _FS_RPATH case 'g' : /* fg - Change current directory */ while (*ptr == ' ') ptr++; put_rc(f_chdir(ptr)); break; #if _FS_RPATH >= 2 case 'q' : /* fq - Show current dir path */ res = f_getcwd(cLine, sizeof cLine); if (res) put_rc((FRESULT)res); else printf("%s\r\n", cLine); break; #endif #endif #if _USE_LABEL case 'b' : /* fb - Set volume label */ while (*ptr == ' ') ptr++; put_rc(f_setlabel(ptr)); break; #endif /* _USE_LABEL */ #if _USE_MKFS case 'm' : /* fm - Create file system */ if (!xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break; printf("The volume will be formatted. Are you sure? (Y/n)="); xgets(cLine, sizeof cLine); if (cLine[0] == 'Y') put_rc(f_mkfs("0:", (BYTE)p2, (WORD)p3, work_space, 1024)); break; #endif /* _USE_MKFS */ case 'z' : /* fz [] - Change/Show R/W length for fr/fw/fx command */ if (xatoi(&ptr, &p1) && p1 >= 1 && p1 <= (long)sizeof fBuff) blen = p1; printf("blen=%u\r\n", blen); break; } break; } } } #endif // #ifdef CONSOLE_DEBUG /* Pointer to the file name */ FRESULT FileCreate(const TCHAR *path) { FRESULT rc = FR_LOCKED; FIL pFile; /* File objects */ UINT wlen; if (ReqUseFatfs()) { rc = f_open(&pFile, path, FA_WRITE); if (rc == FR_NO_FILE) { rc = f_open(&pFile, path, FA_CREATE_NEW | FA_WRITE); if (rc == FR_OK) // rc = f_write(&pFile, path, strlen(path), &wlen); rc = f_close(&pFile); } else if (rc == FR_OK) { rc = f_truncate(&pFile); rc = f_write(&pFile, path, strlen(path), &wlen); f_close(&pFile); } leaveFatfs(); } return rc; } FRESULT FileCheck(const TCHAR *path) { FRESULT rc = FR_LOCKED; FIL pFile; /* File objects */ if (ReqUseFatfs()) { rc = f_open(&pFile, path, FA_READ); if (rc == FR_OK) { f_close(&pFile); } leaveFatfs(); } return rc; } /* Pointer to the file name */ FRESULT FileWrite(const TCHAR *path, BYTE *data, DWORD offset, DWORD size) { FRESULT rc = FR_LOCKED; UINT wlen; FIL pFile; /* File objects */ if (ReqUseFatfs()) { rc = f_open(&pFile, path, FA_WRITE); if (rc == FR_OK) { // printf("f_lseek:%d \r\n", (u32)f_size(&pFile)); if (offset == 0xffffffff) rc = f_lseek(&pFile, f_size(&pFile)); else rc = f_lseek(&pFile, offset); // printf("f_lseek:rc = %d (%d)\r\n", rc, (u32)f_size(&pFile)); rc = f_write(&pFile, data, size, &wlen); // printf("f_write:%d, len = %d, tsize = %d \r\n", rc, wlen, (u32)f_size(&pFile)); f_close(&pFile); } leaveFatfs(); } return rc; } /* Pointer to the file name */ FRESULT FileRead(const TCHAR *path, BYTE *data, DWORD offset, DWORD size, UINT *rlen) { FRESULT rc = FR_LOCKED; FIL pFile; /* File objects */ if (ReqUseFatfs()) { rc = f_open(&pFile, path, FA_READ); if (rc == FR_OK) { f_lseek(&pFile, offset); f_read(&pFile, data, size, rlen); f_close(&pFile); } leaveFatfs(); } return rc; } FRESULT GetFileSize(const TCHAR *path, UINT *size) { FRESULT rc = FR_LOCKED; FIL pFile; if (ReqUseFatfs()) { rc = f_open(&pFile, path, FA_READ); if (rc == FR_OK) { *size = pFile.obj.objsize; f_close(&pFile); } leaveFatfs(); } return rc; } FRESULT DirCreate(const TCHAR *path) { FRESULT rc = FR_LOCKED; if (ReqUseFatfs()) { rc = f_mkdir(path); leaveFatfs(); } return rc; }