Several examples run on only mbed-os5.13.0 (not 5.14.0)
Dependencies: BD_SD_DISCO_F769NI BSP_DISCO_F769NI LCD_DISCO_F769NI TS_DISCO_F769NI USBHost_F769NI
mon.cpp
00001 /* 00002 * mbed Application program for the mbed 00003 * FatFs Check program / monitor part 00004 * 00005 * Copyright (c) 2015,'18 Kenji Arai / JH1PJL 00006 * http://www.page.sannet.ne.jp/kenjia/index.html 00007 * https://os.mbed.com/users/kenjiArai/ 00008 * Created: May 5th, 2015 00009 * Revised: June 14th, 2015 00010 * Revised: April 7th, 2018 00011 */ 00012 00013 /* 00014 *---------------- REFERENCE --------------------------------------------------- 00015 * Original Source Information 00016 * FatFs sample program 00017 * ChaN FatFs http://elm-chan.org/ 00018 * http://elm-chan.org/fsw/ff/00index_e.html 00019 */ 00020 /*----------------------------------------------------------------------*/ 00021 /* FAT file system sample project for FatFs (C)ChaN, 2016 */ 00022 /*----------------------------------------------------------------------*/ 00023 00024 // Include -------------------------------------------------------------------- 00025 #include "mbed.h" 00026 #if (MBED_MAJOR_VERSION == 2) 00027 #include "SDFileSystem.h" 00028 #elif (MBED_MAJOR_VERSION == 5) 00029 #include "FATFileSystem.h" 00030 #endif 00031 #include "ff.h" 00032 #include "ffconf.h" 00033 #include "diskio.h" 00034 #include "mon.h" 00035 00036 // Definition ----------------------------------------------------------------- 00037 #define DO_DEBUG 0 00038 00039 #if DO_DEBUG 00040 #define DEBUG_LINE pc.printf("line:%d\r\n", __LINE__); 00041 #else 00042 #define DEBUG_LINE {;} 00043 #endif 00044 00045 // Com 00046 #if 1 00047 #define BAUD(x) pc.baud(x) 00048 #define GETC(x) pc.getc(x) 00049 #define PUTC(x) pc.putc(x) 00050 #define PUTS(x) pc.puts(x) 00051 #define PRINTF(...) pc.printf(__VA_ARGS__) 00052 #define READABLE(x) pc.readable(x) 00053 #else 00054 #define BAUD(x) {;} 00055 #define GETC(x) {;} 00056 #define PUTC(x) {;} 00057 #define PRINTF(...) {;} 00058 #define READABLE(x) {;} 00059 #endif 00060 00061 #define UTC_JST_OFFSET (32400) // +9 hours 00062 00063 // from ffconf.h 00064 #define _VOLUMES 1 00065 #define FF_USE_LFN 0 00066 00067 #if !defined(FF_FS_RPATH) 00068 #define FF_FS_RPATH 0 00069 #endif 00070 00071 #define DW_CHAR sizeof(char) 00072 #define DW_SHORT sizeof(short) 00073 #define DW_LONG sizeof(long) 00074 00075 /* These types must be 16-bit, 32-bit or larger integer */ 00076 typedef int INT; 00077 typedef unsigned int UINT; 00078 00079 /* These types must be 8-bit integer */ 00080 typedef char CHAR; 00081 typedef unsigned char UCHAR; 00082 typedef unsigned char BYTE; 00083 00084 /* These types must be 16-bit integer */ 00085 typedef short SHORT; 00086 typedef unsigned short USHORT; 00087 typedef unsigned short WORD; 00088 typedef unsigned short WCHAR; 00089 00090 /* These types must be 32-bit integer */ 00091 typedef long LONG; 00092 typedef unsigned long ULONG; 00093 typedef unsigned long DWORD; 00094 /* by Kenji Arai / JH1PJL September 10th, 2012 */ 00095 typedef unsigned long long DDWORD; 00096 00097 // RAM ------------------------------------------------------------------------ 00098 BYTE Buff[4096]; 00099 char Linebuf[128]; // Console input buffer 00100 FATFS Fatfs[_VOLUMES]; // File system object for each logical drive 00101 FIL File1, File2; // File objects 00102 FATFS_DIR* Dirx; 00103 FILINFO Finfo; 00104 #if FF_USE_LFN 00105 //inside of FILINFO 00106 char Lfname[512]; 00107 #endif 00108 DWORD AccSize; // Work register for fs command 00109 WORD AccFiles, AccDirs; 00110 00111 // ROM / Constant data -------------------------------------------------------- 00112 char *const monmsg0 = "Start monitor program for FatFs File System\r\n"; 00113 char *const monmsg1 = " <Please press any key to start the monitor>"; 00114 00115 static const char HelpMsg0[] = 00116 "dir <full_pass>\r\n" 00117 "type <file_name>\r\n" 00118 "vol\r\n" 00119 "ren <org_file_name> <new_file_name>\r\n" 00120 "copy <file_name> <file_name>\r\n" 00121 "mkdir <dir_name>\r\n" 00122 "cd <dir_name>\r\n" 00123 "x extend commands mode\r\n" 00124 "q Return to main\r\n" 00125 "t Show current time or Adjust time\r\n" 00126 " e.g. t 18 3 28 14 48 20 -> 2018-03-28 14:48:20\r\n" 00127 "? Help/You know the command\r\n" 00128 "\r\n"; 00129 00130 static const char HelpMsg1[] = 00131 "[File system controls]\r\n" 00132 " fi <ld#> [<mount>]- Force initialized the volume\r\n" 00133 " fs [<path>] - Show volume status\r\n" 00134 " fl [<path>] - Show a directory\r\n" 00135 " fo <mode> <file> - Open a file\r\n" 00136 " <mode> Read=1, Write=2\r\n" 00137 " fc - Close the file\r\n" 00138 " fe <ofs> - Move fp in normal seek\r\n" 00139 " fd <len> - Read and dump the file\r\n" 00140 " fr <len> - Read the file\r\n" 00141 " fw <len> <val> - Write to the file\r\n" 00142 " fn <org.name> <new.name> - Rename an object\r\n" 00143 " fu <name> - Unlink an object\r\n" 00144 " fv - Truncate the file at current fp\r\n" 00145 " fk <name> - Create a directory\r\n" 00146 " fa <atrr> <mask> <object name> - Change attribute of an object\r\n" 00147 " ft <year> <month> <day> <hour> <min> <sec> <name>" 00148 " - Change timestamp of an object\r\n" 00149 " fx <src.file> <dst.file> - Copy a file\r\n" 00150 " fg <path> - Change current directory\r\n" 00151 " fq - Show current directory\r\n" 00152 " fb <name> - Set volume label\r\n" 00153 " fm <ld#> <type> <csize> - Create file system\r\n" 00154 " fz [<len>] - Change/Show R/W length for fr/fw/fx command\r\n" 00155 "[Disk contorls]\r\n" 00156 " di <pd#> - Initialize disk\r\n" 00157 " dd [<pd#> <lba>] - Dump a secrtor\r\n" 00158 " ds <pd#> - Show disk status\r\n" 00159 "[Buffer controls]\r\n" 00160 " bd <ofs> - Dump working buffer\r\n" 00161 " be <ofs> [<data>] ... - Edit working buffer\r\n" 00162 " br <pd#> <lba> [<count>] - Read disk into working buffer\r\n" 00163 " bw <pd#> <lba> [<count>] - Write working buffer into disk\r\n" 00164 " bf <val> - Fill working buffer\r\n" 00165 "[Misc commands]\r\n" 00166 " q Return\r\n" 00167 " ? Help\r\n" 00168 "\r\n"; 00169 00170 // Function prototypes -------------------------------------------------------- 00171 #if (MBED_MAJOR_VERSION == 2) 00172 extern SDFileSystem fs; 00173 #elif (MBED_MAJOR_VERSION == 5) 00174 extern HeapBlockDevice bd; 00175 extern FATFileSystem fs; 00176 #endif 00177 00178 static void extended_mon( char *ptr ); 00179 static void v_next( char *ptr ); 00180 static void d_next( char *ptr ); 00181 static void c_next( char *ptr ); 00182 static void m_next( char *ptr ); 00183 static void r_next( char *ptr ); 00184 static void t_next( char *ptr ); 00185 static void memory_inf(char *ptr); 00186 static void disk_inf(char *ptr); 00187 00188 static void crlf( void ); 00189 static FRESULT scan_files( char* path ); 00190 static void put_rc( FRESULT rc ); 00191 static void file_inf( char *ptr ); 00192 static void put_dump( void* buff, unsigned long addr, int len, int width ); 00193 static void chk_and_set_time(char *ptr); 00194 static int xatoi ( char **str, long *res ); 00195 00196 void get_line (char *buff, int len); 00197 00198 // Object --------------------------------------------------------------------- 00199 extern Serial pc; 00200 Timer t; 00201 00202 //------------------------------------------------------------------------------ 00203 // Control Program 00204 //------------------------------------------------------------------------------ 00205 // Monitor program for File control 00206 void mon () 00207 { 00208 char *ptr; 00209 00210 Dirx = new FATFS_DIR; 00211 /* Open Uart to communicate with Host PC */ 00212 PUTS(monmsg0); 00213 PUTS(monmsg1); 00214 crlf(); 00215 #if FF_USE_LFN 00216 // no needs because FILINFO structure is changed 00217 Finfo.lfname = Lfname; 00218 Finfo.lfsize = sizeof Lfname; 00219 #endif 00220 for (;;) { 00221 DEBUG_LINE 00222 PUTC('>'); 00223 ptr = Linebuf; 00224 get_line( ptr, sizeof(Linebuf) ); 00225 switch ( *ptr++ ) { 00226 // vol 00227 case 'v' : 00228 v_next(ptr); 00229 break; 00230 // dir 00231 case 'd' : 00232 d_next(ptr); 00233 break; 00234 // cd, copy 00235 case 'c' : 00236 c_next(ptr); 00237 break; 00238 // mkdir 00239 case 'm' : 00240 m_next(ptr); 00241 break; 00242 // ren 00243 case 'r' : 00244 r_next(ptr); 00245 break; 00246 case 't' : 00247 t_next(ptr); 00248 break; 00249 case 'x' : 00250 extended_mon(ptr); 00251 break; 00252 // Help 00253 case '?' : 00254 PUTS(HelpMsg0); 00255 break; 00256 // Exit monitor (return to main()) 00257 case 'q' : 00258 PUTS("Return to main\r\n"); 00259 return; 00260 // Not a command 00261 default: 00262 PUTS("? [HELP]=?"); 00263 crlf(); 00264 break; 00265 } 00266 } 00267 } 00268 00269 uint32_t get_disk_freespace(void) 00270 { 00271 long p1; 00272 UINT s1, s2; 00273 FATFS *fs; 00274 BYTE res; 00275 00276 if (Dirx == NULL){ 00277 Dirx = new FATFS_DIR; 00278 } 00279 char p = NULL; 00280 res = f_opendir(Dirx, &p); 00281 if (res) { 00282 return 0; 00283 } 00284 p1 = s1 = s2 = 0; 00285 for(;;) { 00286 res = f_readdir(Dirx, &Finfo); 00287 if ((res != FR_OK) || !Finfo.fname[0]) break; 00288 if (Finfo.fattrib & AM_DIR) { 00289 s2++; 00290 } else { 00291 s1++; 00292 p1 += Finfo.fsize; 00293 } 00294 } 00295 res = f_getfree(&p, (DWORD*)&p1, &fs); 00296 uint32_t size = p1 * fs->csize * 512; 00297 if (res == FR_OK) { 00298 return size; 00299 } else { 00300 return 0; 00301 } 00302 } 00303 00304 static void extended_mon( char *ptr ) 00305 { 00306 PUTS(HelpMsg1); 00307 while(true) { 00308 PUTS("e>"); 00309 ptr = Linebuf; 00310 get_line( ptr, sizeof(Linebuf) ); 00311 switch ( *ptr++ ) { 00312 case 'f' : 00313 DEBUG_LINE; 00314 file_inf(ptr); 00315 break; 00316 case 'd' : 00317 DEBUG_LINE; 00318 disk_inf(ptr); 00319 break; 00320 case 'm' : 00321 DEBUG_LINE; 00322 memory_inf(ptr); 00323 break; 00324 case '?' : 00325 DEBUG_LINE; 00326 PUTS(HelpMsg1); 00327 break; 00328 case 'q' : 00329 DEBUG_LINE; 00330 return; 00331 default: 00332 PUTS( "?\r\n" ); 00333 } 00334 } 00335 } 00336 00337 //------------------------------------------------------------------------------ 00338 // General monitor functions 00339 static void v_next( char *ptr ) 00340 { 00341 switch ( *ptr++ ) { 00342 case 'o' : 00343 if (*ptr == 'l') { 00344 *ptr = 's'; 00345 file_inf(ptr); // fs [<path>] - Show volume status 00346 } 00347 break; 00348 default: 00349 PUTS( "?\r\n" ); 00350 } 00351 } 00352 00353 static void d_next(char *ptr) 00354 { 00355 switch ( *ptr++ ) { 00356 case 'i' : 00357 if (*ptr == 'r') { 00358 *ptr = 'l'; 00359 file_inf(ptr); // fl [<path>] - Directory listing 00360 } 00361 break; 00362 default: 00363 PUTS( "?\r\n" ); 00364 } 00365 } 00366 00367 static void c_next(char *ptr) 00368 { 00369 switch ( *ptr++ ) { 00370 case 'o' : 00371 if ((*ptr == 'p') && (*(ptr + 1) == 'y')) { 00372 ptr++; 00373 *ptr = 'x'; 00374 file_inf(ptr); // fx <src_name> <dst_name> - Copy file 00375 } 00376 break; 00377 case 'd' : 00378 *ptr = 'g'; 00379 file_inf(ptr); // fx <src_name> <dst_name> - Copy file 00380 break; 00381 default: 00382 PUTS( "?\r\n" ); 00383 } 00384 } 00385 00386 static void m_next(char *ptr) 00387 { 00388 switch ( *ptr++ ) { 00389 case 'k' : 00390 if ((*ptr == 'd') && (*(ptr + 1) == 'i') && (*(ptr + 2) == 'r')) { 00391 ptr += 2; 00392 *ptr = 'k'; 00393 file_inf(ptr); // fk <name> - Create a directory 00394 } 00395 break; 00396 default: 00397 PUTS("?\r\n"); 00398 } 00399 } 00400 00401 static void r_next(char *ptr) 00402 { 00403 switch (*ptr++) { 00404 case 'e' : 00405 if (*ptr == 'n') { 00406 // fn <old_name> <new_name> - Change file/dir name 00407 file_inf(ptr); 00408 } 00409 break; 00410 default: 00411 PUTS("?\r\n"); 00412 } 00413 } 00414 00415 static void t_next(char *ptr) 00416 { 00417 switch (*ptr++) { 00418 case ' ' : 00419 case 0x0d: 00420 chk_and_set_time(ptr); 00421 case 'y' : 00422 if ((*ptr == 'p') && (*(ptr + 1) == 'e')) { 00423 ptr++; 00424 *ptr = '&'; 00425 file_inf(ptr); 00426 } 00427 break; 00428 default: 00429 PUTS("?\r\n"); 00430 } 00431 } 00432 00433 static FRESULT scan_files ( 00434 char* path /* Pointer to the path name working buffer */ 00435 ) 00436 { 00437 FATFS_DIR dirs; 00438 FRESULT res; 00439 BYTE i; 00440 char *fn; 00441 00442 if ((res = f_opendir(&dirs, path)) == FR_OK) { 00443 i = strlen(path); 00444 PRINTF("path: %s, n=%u\r\n", path, i); 00445 while (((res = f_readdir(&dirs, &Finfo)) == FR_OK) && Finfo.fname[0]) { 00446 if (FF_FS_RPATH && Finfo.fname[0] == '.') { 00447 continue; 00448 } 00449 #if FF_USE_LFN 00450 //fn = *Finfo.lfname ? Finfo.lfname : Finfo.fname; 00451 if (Finfo.altname[0] == 0) { 00452 fn = Finfo.fname; 00453 } else { 00454 fn = Finfo.altname; 00455 } 00456 #else 00457 fn = Finfo.fname; 00458 #endif 00459 if (Finfo.fattrib & AM_DIR) { 00460 AccDirs++; 00461 *(path+i) = '/'; 00462 strcpy(path+i+1, fn); 00463 res = scan_files(path); 00464 *(path+i) = '\0'; 00465 if (res != FR_OK) break; 00466 } else { 00467 PRINTF("%s/%s\r\n", path, fn); 00468 AccFiles++; 00469 AccSize += Finfo.fsize; 00470 } 00471 } 00472 } 00473 return res; 00474 } 00475 00476 static void put_rc (FRESULT rc) 00477 { 00478 const char *str = 00479 "OK\0" "DISK_ERR\0" "INT_ERR\0" "NOT_READY\0" "NO_FILE\0" "NO_PATH\0" 00480 "INVALID_NAME\0" "DENIED\0" "EXIST\0" "INVALID_OBJECT\0" 00481 "WRITE_PROTECTED\0" "INVALID_DRIVE\0" "NOT_ENABLED\0" 00482 "NO_FILE_SYSTEM\0" "MKFS_ABORTED\0" "TIMEOUT\0" 00483 "LOCKED\0" "NOT_ENOUGH_CORE\0" "TOO_MANY_OPEN_FILES\0"; 00484 int i; 00485 00486 for ( i = 0; i != rc && *str; i++ ) { 00487 while ( *str++ ) { 00488 ; 00489 } 00490 } 00491 PRINTF( "rc=%u FR_%s\r\n", (UINT)rc, str ); 00492 } 00493 00494 static void file_inf(char *ptr) 00495 { 00496 long p1, p2, p3; 00497 CHAR *ptr2; 00498 BYTE f_res; 00499 UINT s1, s2, cnt, blen = sizeof Buff; 00500 FATFS *fs; 00501 static const BYTE ft[] = {0, 12, 16, 32}; 00502 BYTE res; 00503 DWORD ofs = 0; 00504 uint32_t tim; 00505 00506 switch (*ptr++) { 00507 case '&' : 00508 DEBUG_LINE; 00509 while (*ptr == ' ') ptr++; 00510 /* Open a file */ 00511 f_res = f_open(&File1, ptr, FA_READ); 00512 if ( f_res ) { 00513 put_rc((FRESULT)f_res); 00514 break; 00515 } 00516 DEBUG_LINE; 00517 /* Read all lines and display it */ 00518 while(true) { 00519 f_res = f_read(&File1, (TCHAR*)Buff, blen, &cnt); 00520 if ( f_res ) { 00521 put_rc((FRESULT)f_res); 00522 break; 00523 } 00524 for (s1 = 0; s1 < cnt; s1++) { 00525 PUTC(Buff[s1]); 00526 } 00527 if (cnt != blen) { 00528 break; 00529 } 00530 } 00531 DEBUG_LINE; 00532 /* Close the file */ 00533 f_close(&File1); 00534 break; 00535 00536 case 'i' : /* fi [<opt>]- Initialize logical drive */ 00537 if ( !xatoi(&ptr, &p1) ) { 00538 break; 00539 } 00540 if (!xatoi(&ptr, &p2)) p2 = 0; 00541 put_rc(f_mount(&Fatfs[p1], (const TCHAR*)p1, 0)); 00542 break; 00543 00544 case 's' : /* fs [<path>] - Show volume status */ 00545 f_res = f_getfree( ptr, (DWORD*)&p2, &fs ); 00546 if ( f_res ) { 00547 put_rc((FRESULT)f_res); 00548 break; 00549 } 00550 PRINTF 00551 ( 00552 "\rFAT type = FAT%u\r\nBytes/Cluster" 00553 " = %lu\r\nNumber of FATs = %u\r\n" 00554 "Root DIR entries = %u\r\n" 00555 "Sectors/FAT = %lu\r\n" 00556 "Number of clusters = %lu\r\n" 00557 "FAT start (lba) = %lu\r\n" 00558 "DIR start (lba,clustor) = %lu\r\n" 00559 "Data start (lba) = %lu\r\n", 00560 ft[fs->fs_type & 3], (DWORD)fs->csize * 512, fs->n_fats, 00561 fs->n_rootdir, fs->fsize, (DWORD)fs->n_fatent - 2, 00562 fs->fatbase, fs->dirbase, fs->database 00563 ); 00564 AccSize = AccFiles = AccDirs = 0; 00565 break; 00566 case 'l' : /* fl [<path>] - Directory listing */ 00567 while (*ptr == ' ') ptr++; 00568 res = f_opendir(Dirx, ptr); 00569 if (res) { 00570 put_rc((FRESULT)res); 00571 break; 00572 } 00573 p1 = s1 = s2 = 0; 00574 for(;;) { 00575 res = f_readdir(Dirx, &Finfo); 00576 if ((res != FR_OK) || !Finfo.fname[0]) break; 00577 if (Finfo.fattrib & AM_DIR) { 00578 s2++; 00579 } else { 00580 s1++; 00581 p1 += Finfo.fsize; 00582 } 00583 PRINTF("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %s\r\n", 00584 (Finfo.fattrib & AM_DIR) ? 'D' : '-', 00585 (Finfo.fattrib & AM_RDO) ? 'R' : '-', 00586 (Finfo.fattrib & AM_HID) ? 'H' : '-', 00587 (Finfo.fattrib & AM_SYS) ? 'S' : '-', 00588 (Finfo.fattrib & AM_ARC) ? 'A' : '-', 00589 (Finfo.fdate >> 9) + 1980, (Finfo.fdate >> 5) & 15, 00590 Finfo.fdate & 31, 00591 (Finfo.ftime >> 11), (Finfo.ftime >> 5) & 63, 00592 Finfo.fsize, Finfo.fname); 00593 } 00594 #if 0 // f_getfree cannnot count under Dir, subdirectory area 00595 PRINTF("%4u File(s),%10lu bytes total\r\n%4u Dir(s)", s1, p1, s2); 00596 res = f_getfree(ptr, (DWORD*)&p1, &fs); 00597 if (res == FR_OK) 00598 PRINTF(", %10lu bytes free\r\n", p1 * fs->csize * 512); 00599 else 00600 put_rc((FRESULT)res); 00601 #else 00602 PRINTF("%4u File(s) = %10lu bytes total, %4u Dir(s)\r\n", 00603 s1, p1, s2); 00604 #endif 00605 break; 00606 00607 case 'o' : /* fo <mode> <file> - Open a file */ 00608 if (!xatoi(&ptr, &p1)) break; 00609 while (*ptr == ' ') ptr++; 00610 put_rc(f_open(&File1, ptr, (BYTE)p1)); 00611 #if 0 00612 put_rc(f_open(&File1, "savedata.txt", 1)); 00613 PRINTF("Open savedata.txt as read mode\r\n"); 00614 #endif 00615 break; 00616 00617 case 'c' : /* fc - Close a file */ 00618 put_rc(f_close(&File1)); 00619 break; 00620 00621 case 'e' : /* fe - Seek file pointer */ 00622 if (!xatoi(&ptr, &p1)) break; 00623 res = f_lseek(&File1, p1); 00624 put_rc((FRESULT)res); 00625 if (res == FR_OK) 00626 PRINTF("fptr=%lu(0x%lX)\r\n", File1.fptr, File1.fptr); 00627 break; 00628 00629 case 'd' : /* fd <len> - read and dump file from current fp */ 00630 if (!xatoi(&ptr, &p1)) break; 00631 ofs = File1.fptr; 00632 while (p1) { 00633 if ((UINT)p1 >= 16) { 00634 cnt = 16; 00635 p1 -= 16; 00636 } else { 00637 cnt = p1; 00638 p1 = 0; 00639 } 00640 res = f_read(&File1, Buff, cnt, &cnt); 00641 if (res != FR_OK) { 00642 put_rc((FRESULT)res); 00643 break; 00644 } 00645 if (!cnt) break; 00646 put_dump(Buff, ofs, cnt, DW_CHAR); 00647 ofs += 16; 00648 } 00649 break; 00650 00651 case 'r' : /* fr <len> - read file */ 00652 if (!xatoi(&ptr, &p1)) break; 00653 p2 = 0; 00654 t.reset(); 00655 t.start(); 00656 while (p1) { 00657 if ((UINT)p1 >= blen) { 00658 cnt = blen; 00659 p1 -= blen; 00660 } else { 00661 cnt = p1; 00662 p1 = 0; 00663 } 00664 res = f_read(&File1, Buff, cnt, &s2); 00665 if (res != FR_OK) { 00666 put_rc((FRESULT)res); 00667 break; 00668 } 00669 p2 += s2; 00670 if (cnt != s2) break; 00671 } 00672 tim = t.read_ms(); 00673 PRINTF("%lu bytes read with %lu kB/sec.\r\n", 00674 p2, tim ? (p2 / tim) : 0); 00675 break; 00676 00677 case 'w' : /* fw <len> <val> - write file */ 00678 if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break; 00679 memset(Buff, (BYTE)p2, blen); 00680 p2 = 0; 00681 t.reset(); 00682 t.start(); 00683 while (p1) { 00684 if ((UINT)p1 >= blen) { 00685 cnt = blen; 00686 p1 -= blen; 00687 } else { 00688 cnt = p1; 00689 p1 = 0; 00690 } 00691 res = f_write(&File1, Buff, cnt, &s2); 00692 if (res != FR_OK) { 00693 put_rc((FRESULT)res); 00694 break; 00695 } 00696 p2 += s2; 00697 if (cnt != s2) break; 00698 } 00699 tim = t.read_ms(); 00700 PRINTF("%lu bytes written with %lu kB/sec.\r\n", 00701 p2, tim ? (p2 / tim) : 0); 00702 break; 00703 00704 case 'n' : /* fn <org.name> <new.name> - Change name of an object */ 00705 while (*ptr == ' ') ptr++; 00706 ptr2 = strchr(ptr, ' '); 00707 if (!ptr2) break; 00708 *ptr2++ = 0; 00709 while (*ptr2 == ' ') ptr2++; 00710 put_rc(f_rename(ptr, ptr2)); 00711 break; 00712 00713 case 'u' : /* fu <name> - Unlink an object */ 00714 while (*ptr == ' ') ptr++; 00715 put_rc(f_unlink(ptr)); 00716 break; 00717 00718 case 'v' : /* fv - Truncate file */ 00719 put_rc(f_truncate(&File1)); 00720 break; 00721 00722 case 'k' : /* fk <name> - Create a directory */ 00723 while (*ptr == ' ') ptr++; 00724 put_rc(f_mkdir(ptr)); 00725 break; 00726 #if 0 00727 case 'a' : /* fa <atrr> <mask> <name> - Change attribute of an object */ 00728 if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break; 00729 while (*ptr == ' ') ptr++; 00730 put_rc(f_chmod(ptr, p1, p2)); 00731 break; 00732 #endif 00733 #if 0 00734 /* ft <year> <month> <day> <hour> <min> <sec> <name> 00735 - Change timestamp of an object */ 00736 case 't' : 00737 if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) { 00738 break; 00739 } 00740 Finfo.fdate = ((p1 - 1980) << 9) | ((p2 & 15) << 5) | (p3 & 31); 00741 if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) { 00742 break; 00743 } 00744 Finfo.ftime = 00745 ((p1 & 31) << 11) | ((p2 & 63) << 5) | ((p3 >> 1) & 31); 00746 put_rc(f_utime(ptr, &Finfo)); 00747 break; 00748 #endif 00749 #if FILCPY_NOTUSE == 0 00750 case 'x' : /* fx <src_name> <dst_name> - Copy file */ 00751 while ( *ptr == ' ' ) { 00752 ptr++; 00753 } 00754 ptr2 = strchr( ptr, ' ' ); 00755 if ( !ptr2 ) { 00756 break; 00757 } 00758 *ptr2++ = 0; 00759 while ( *ptr2 == ' ' ) { 00760 ptr2++; 00761 } 00762 f_res = f_open( &File1, ptr, FA_OPEN_EXISTING | FA_READ ); 00763 PRINTF("Opening %s \r\n", ptr); 00764 if ( f_res ) { 00765 put_rc( (FRESULT)f_res ); 00766 break; 00767 } 00768 f_res = f_open( &File2, ptr2, FA_CREATE_ALWAYS | FA_WRITE ); 00769 PRINTF(" Creating %s \r\n", ptr2); 00770 if ( f_res ) { 00771 put_rc( (FRESULT)f_res ); 00772 f_close( &File1 ); 00773 break; 00774 } 00775 PRINTF("Copying file..."); 00776 p1 = 0; 00777 for ( ;; ) { 00778 f_res = f_read( &File1, Buff, blen, &s1 ); 00779 if ( f_res || s1 == 0 ) { 00780 break; /* error or eof */ 00781 } 00782 f_res = f_write( &File2, Buff, s1, &s2 ); 00783 p1 += s2; 00784 if ( f_res || s2 < s1 ) { 00785 break; /* error or disk full */ 00786 } 00787 } 00788 f_close( &File1 ); 00789 f_close( &File2 ); 00790 crlf(); 00791 break; 00792 #endif 00793 #if 0 00794 case 'x' : /* fx <src.name> <dst.name> - Copy a file */ 00795 while (*ptr == ' ') ptr++; 00796 ptr2 = strchr(ptr, ' '); 00797 if (!ptr2) break; 00798 *ptr2++ = 0; 00799 while (*ptr2 == ' ') ptr2++; 00800 PRINTF("Opening \"%s\"", ptr); 00801 res = f_open(&File1, ptr, FA_OPEN_EXISTING | FA_READ); 00802 PUTS("\r\n"); 00803 if (res) { 00804 put_rc((FRESULT)res); 00805 break; 00806 } 00807 PRINTF("Creating \"%s\"", ptr2); 00808 res = f_open(&File1, ptr2, FA_CREATE_ALWAYS | FA_WRITE); 00809 PUTS("\r\n"); 00810 if (res) { 00811 put_rc((FRESULT)res); 00812 f_close(&File1); 00813 break; 00814 } 00815 PRINTF("Copying file..."); 00816 t.reset(); 00817 t.start(); 00818 p1 = 0; 00819 for (;;) { 00820 res = f_read(&File1, Buff, blen, &s1); 00821 if (res || s1 == 0) break; /* error or eof */ 00822 res = f_write(&File2, Buff, s1, &s2); 00823 p1 += s2; 00824 if (res || s2 < s1) break; /* error or disk full */ 00825 } 00826 tim = t.read_ms(); 00827 PRINTF("\r\n%lu bytes copied with %lu kB/sec.\r\n", 00828 p1, tim ? (p1 / tim) : 0); 00829 f_close(&File1); 00830 f_close(&File2); 00831 break; 00832 #endif 00833 #if FF_FS_RPATH 00834 case 'g' : /* fg <path> - Change current directory */ 00835 while (*ptr == ' ') ptr++; 00836 put_rc(f_chdir(ptr)); 00837 break; 00838 #if FF_FS_RPATH >= 2 00839 case 'q' : /* fq - Show current dir path */ 00840 res = f_getcwd(Linebuf, sizeof Linebuf); 00841 if (res) 00842 put_rc(res); 00843 else 00844 PRINTF("%s\r\n", Linebuf); 00845 break; 00846 #endif 00847 #endif 00848 #if FF_USE_LABEL 00849 case 'b' : /* fb <name> - Set volume label */ 00850 while (*ptr == ' ') ptr++; 00851 put_rc(f_setlabel(ptr)); 00852 break; 00853 #endif /* FF_USE_LABEL */ 00854 #if FF_USE_MKFS 00855 case 'm' : /* fm <type> <csize> - Create file system */ 00856 if (!xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break; 00857 PRINTF("The volume will be formatted. Are you sure? (Y/n)="); 00858 get_line(Linebuf, sizeof Linebuf); 00859 if (Linebuf[0] == 'Y') 00860 put_rc(f_mkfs("", (BYTE)p2, (DWORD)p3, Buff, sizeof Buff)); 00861 break; 00862 #endif /* FF_USE_MKFS */ 00863 /* fz [<size>] - Change/Show R/W length for fr/fw/fx command */ 00864 case 'z' : 00865 if (xatoi(&ptr, &p1) && p1 >= 1 && p1 <= (long)sizeof Buff) 00866 blen = p1; 00867 PRINTF("blen=%u\r\n", blen); 00868 break; 00869 } 00870 } 00871 00872 static void memory_inf(char *ptr) 00873 { 00874 long p1, p2, p3; 00875 00876 switch (*ptr++) { 00877 case 'd' : /* md[b|h|w] <address> [<count>] - Dump memory */ 00878 switch (*ptr++) { 00879 case 'w': 00880 p3 = DW_LONG; 00881 break; 00882 case 'h': 00883 p3 = DW_SHORT; 00884 break; 00885 default: 00886 p3 = DW_CHAR; 00887 } 00888 if (!xatoi(&ptr, &p1)) break; 00889 if (!xatoi(&ptr, &p2)) p2 = 128 / p3; 00890 for (ptr = (char*)p1; p2 >= 16 / p3; ptr += 16, p2 -= 16 / p3) 00891 put_dump(ptr, (DWORD)ptr, 16 / p3, p3); 00892 if (p2) put_dump((BYTE*)ptr, (UINT)ptr, p2, p3); 00893 break; 00894 case 'f' : /* mf <address> <value> <count> - Fill memory */ 00895 if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) { 00896 break; 00897 } 00898 while (p3--) { 00899 *(BYTE*)p1 = (BYTE)p2; 00900 p1++; 00901 } 00902 break; 00903 case 'e' : /* me[b|h|w] <address> [<value> ...] - Edit memory */ 00904 switch (*ptr++) { /* Get data width */ 00905 case 'w': 00906 p3 = DW_LONG; 00907 break; 00908 case 'h': 00909 p3 = DW_SHORT; 00910 break; 00911 default: 00912 p3 = DW_CHAR; 00913 } 00914 if (!xatoi(&ptr, &p1)) break; /* Get start address */ 00915 if (xatoi(&ptr, &p2)) { /* 2nd parameter is given (direct mode) */ 00916 do { 00917 switch (p3) { 00918 case DW_LONG: 00919 *(DWORD*)p1 = (DWORD)p2; 00920 break; 00921 case DW_SHORT: 00922 *(WORD*)p1 = (WORD)p2; 00923 break; 00924 default: 00925 *(BYTE*)p1 = (BYTE)p2; 00926 } 00927 p1 += p3; 00928 } while (xatoi(&ptr, &p2)); /* Get next value */ 00929 break; 00930 } 00931 for (;;) { /* 2nd parameter is not given (interactive mode) */ 00932 switch (p3) { 00933 case DW_LONG: 00934 PRINTF("%08X 0x%08X-", p1, *(DWORD*)p1); 00935 break; 00936 case DW_SHORT: 00937 PRINTF("%08X 0x%04X-", p1, *(WORD*)p1); 00938 break; 00939 default: 00940 PRINTF("%08X 0x%02X-", p1, *(BYTE*)p1); 00941 } 00942 ptr = Linebuf; 00943 get_line(ptr, sizeof Linebuf); 00944 if (*ptr == '.') break; 00945 if ((BYTE)*ptr >= ' ') { 00946 if (!xatoi(&ptr, &p2)) continue; 00947 switch (p3) { 00948 case DW_LONG: 00949 *(DWORD*)p1 = (DWORD)p2; 00950 break; 00951 case DW_SHORT: 00952 *(WORD*)p1 = (WORD)p2; 00953 break; 00954 default: 00955 *(BYTE*)p1 = (BYTE)p2; 00956 } 00957 } 00958 p1 += p3; 00959 } 00960 } 00961 } 00962 00963 static void disk_inf(char *ptr) 00964 { 00965 long p1, p2; 00966 UINT s1; 00967 BYTE res, b, drv = 0; 00968 DWORD ofs = 0, sect = 0, blk[2]; 00969 00970 switch (*ptr++) { 00971 case 'd' : /* dd [<pd#> <sect>] - Dump secrtor */ 00972 if (!xatoi(&ptr, &p1)) { 00973 p1 = drv; 00974 p2 = sect; 00975 } else { 00976 if (!xatoi(&ptr, &p2)) break; 00977 } 00978 drv = (BYTE)p1; 00979 sect = p2; 00980 res = disk_read(drv, Buff, sect, 1); 00981 if (res) { 00982 PRINTF("rc=%d\r\n", (WORD)res); 00983 break; 00984 } 00985 PRINTF("PD#:%u LBA:%lu\r\n", drv, sect++); 00986 for (ptr=(char*)Buff, ofs = 0; ofs < 0x200; ptr += 16, ofs += 16) 00987 put_dump((BYTE*)ptr, ofs, 16, DW_CHAR); 00988 break; 00989 00990 case 'i' : /* di <pd#> - Initialize disk */ 00991 if (!xatoi(&ptr, &p1)) break; 00992 PRINTF("rc=%d\r\n", (WORD)disk_initialize((BYTE)p1)); 00993 break; 00994 00995 case 's' : /* ds <pd#> - Show disk status */ 00996 if (!xatoi(&ptr, &p1)) break; 00997 if (disk_ioctl((BYTE)p1, GET_SECTOR_COUNT, &p2) == RES_OK) { 00998 PRINTF("Drive size: %lu sectors\r\n", p2); 00999 } 01000 if (disk_ioctl((BYTE)p1, GET_BLOCK_SIZE, &p2) == RES_OK) { 01001 PRINTF("Block size: %lu sectors\r\n", p2); 01002 } 01003 if (disk_ioctl((BYTE)p1, MMC_GET_TYPE, &b) == RES_OK) { 01004 PRINTF("Media type: %u\r\n", b); 01005 } 01006 if (disk_ioctl((BYTE)p1, MMC_GET_CSD, Buff) == RES_OK) { 01007 PUTS("CSD:\r\n"); 01008 put_dump(Buff, 0, 16, DW_CHAR); 01009 } 01010 if (disk_ioctl((BYTE)p1, MMC_GET_CID, Buff) == RES_OK) { 01011 PUTS("CID:\r\n"); 01012 put_dump(Buff, 0, 16, DW_CHAR); 01013 } 01014 if (disk_ioctl((BYTE)p1, MMC_GET_OCR, Buff) == RES_OK) { 01015 PUTS("OCR:\r\n"); 01016 put_dump(Buff, 0, 4, DW_CHAR); 01017 } 01018 if (disk_ioctl((BYTE)p1, MMC_GET_SDSTAT, Buff) == RES_OK) { 01019 PUTS("SD Status:\r\n"); 01020 for (s1 = 0; s1 < 64; s1 += 16) { 01021 put_dump(Buff+s1, s1, 16, DW_CHAR); 01022 } 01023 } 01024 break; 01025 01026 case 'c' : /* Disk ioctl */ 01027 switch (*ptr++) { 01028 case 's' : /* dcs <pd#> - CTRL_SYNC */ 01029 if (!xatoi(&ptr, &p1)) break; 01030 PRINTF("rc=%d\r\n", disk_ioctl((BYTE)p1, CTRL_SYNC, 0)); 01031 break; 01032 case 'e' : /* dce <pd#> <s.lba> <e.lba> - CTRL_TRIM */ 01033 if (!xatoi(&ptr, &p1) || 01034 !xatoi(&ptr, (long*)&blk[0]) || 01035 !xatoi(&ptr, (long*)&blk[1])) { 01036 break; 01037 } 01038 PRINTF("rc=%d\r\n", disk_ioctl((BYTE)p1, CTRL_TRIM, blk)); 01039 break; 01040 } 01041 } 01042 } 01043 01044 void put_dump ( 01045 void* buff, /* Pointer to the array to be dumped */ 01046 unsigned long addr, /* Heading address value */ 01047 int len, /* Number of items to be dumped */ 01048 int width /* Size of the items (DW_CHAR, DW_SHORT, DW_LONG) */ 01049 ) 01050 { 01051 int i; 01052 unsigned char *bp; 01053 unsigned short *sp; 01054 unsigned long *lp; 01055 01056 PRINTF( "%08lx ", addr ); /* address */ 01057 switch ( width ) { 01058 case DW_CHAR: 01059 bp = (unsigned char *)buff; 01060 for ( i = 0; i < len; i++ ) { /* Hexdecimal dump */ 01061 PRINTF( " %02x", bp[i] ); 01062 } 01063 PUTC(' '); 01064 for ( i = 0; i < len; i++ ) { /* ASCII dump */ 01065 PUTC( (bp[i] >= ' ' && bp[i] <= '~') ? bp[i] : '.' ); 01066 } 01067 break; 01068 case DW_SHORT: 01069 sp = (unsigned short *)buff; 01070 do { /* Hexdecimal dump */ 01071 PRINTF( " %04x", *sp++ ); 01072 } while ( --len ); 01073 break; 01074 case DW_LONG: 01075 lp = (unsigned long *)buff; 01076 do { /* Hexdecimal dump */ 01077 PRINTF( " %08lx", *lp++ ); 01078 } while ( --len ); 01079 break; 01080 } 01081 PUTS( "\r\n" ); 01082 } 01083 01084 // RTC related subroutines 01085 void chk_and_set_time(char *ptr) 01086 { 01087 char buf[64]; 01088 01089 long p1; 01090 struct tm t; 01091 time_t seconds; 01092 01093 if (xatoi(&ptr, &p1)) { 01094 t.tm_year = (uint8_t)p1 + 100; 01095 pc.printf("Year:%d ",p1); 01096 xatoi( &ptr, &p1 ); 01097 t.tm_mon = (uint8_t)p1 - 1; 01098 pc.printf("Month:%d ",p1); 01099 xatoi( &ptr, &p1 ); 01100 t.tm_mday = (uint8_t)p1; 01101 pc.printf("Day:%d ",p1); 01102 xatoi( &ptr, &p1 ); 01103 t.tm_hour = (uint8_t)p1; 01104 pc.printf("Hour:%d ",p1); 01105 xatoi( &ptr, &p1 ); 01106 t.tm_min = (uint8_t)p1; 01107 pc.printf("Min:%d ",p1); 01108 xatoi( &ptr, &p1 ); 01109 t.tm_sec = (uint8_t)p1; 01110 pc.printf("Sec: %d \r\n",p1); 01111 seconds = mktime(&t); 01112 set_time(seconds); 01113 } else { 01114 seconds = time(NULL); 01115 } 01116 strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds)); 01117 pc.printf("[Time] %s", buf); 01118 } 01119 01120 // Get key input data 01121 void get_line (char *buff, int len) 01122 { 01123 char c; 01124 int idx = 0; 01125 01126 for (;;) { 01127 c = GETC(); 01128 // Added by Kenji Arai / JH1PJL May 9th, 2010 01129 if (c == '\r') { 01130 buff[idx++] = c; 01131 break; 01132 } 01133 if ((c == '\b') && idx) { 01134 idx--; 01135 PUTC(c); 01136 PUTC(' '); 01137 PUTC(c); 01138 } 01139 if (((uint8_t)c >= ' ') && (idx < len - 1)) { 01140 buff[idx++] = c; 01141 PUTC(c); 01142 } 01143 } 01144 buff[idx] = 0; 01145 PUTS("\r\n"); 01146 } 01147 01148 /* Outpur LF & CR */ 01149 void crlf( void ) 01150 { 01151 PRINTF( "\r\n" ); 01152 } 01153 01154 /* Check key input */ 01155 unsigned int check_hit_key (void) 01156 { 01157 return ( READABLE() ); 01158 } 01159 01160 /*----------------------------------------------*/ 01161 /* Get a value of the string */ 01162 /*----------------------------------------------*/ 01163 /* "123 -5 0x3ff 0b1111 0377 w " 01164 ^ 1st call returns 123 and next ptr 01165 ^ 2nd call returns -5 and next ptr 01166 ^ 3rd call returns 1023 and next ptr 01167 ^ 4th call returns 15 and next ptr 01168 ^ 5th call returns 255 and next ptr 01169 ^ 6th call fails and returns 0 01170 */ 01171 int xatoi ( /* 0:Failed, 1:Successful */ 01172 char **str, /* Pointer to pointer to the string */ 01173 long *res /* Pointer to the valiable to store the value */ 01174 ) 01175 { 01176 unsigned long val; 01177 unsigned char c, r, s = 0; 01178 01179 *res = 0; 01180 while ( (c = **str) == ' ' ) { 01181 (*str)++; /* Skip leading spaces */ 01182 } 01183 if ( c == '-' ) { /* negative? */ 01184 s = 1; 01185 c = *(++(*str)); 01186 } 01187 if ( c == '0' ) { 01188 c = *(++(*str)); 01189 switch (c) { 01190 case 'x': /* hexdecimal */ 01191 r = 16; 01192 c = *(++(*str)); 01193 break; 01194 case 'b': /* binary */ 01195 r = 2; 01196 c = *(++(*str)); 01197 break; 01198 default: 01199 if ( c <= ' ' ) return 1; /* single zero */ 01200 if ( c < '0' || c > '9' ) return 0; /* invalid char */ 01201 r = 8; /* octal */ 01202 } 01203 } else { 01204 if ( c < '0' || c > '9' ) return 0; /* EOL or invalid char */ 01205 r = 10; /* decimal */ 01206 } 01207 val = 0; 01208 while ( c > ' ' ) { 01209 if ( c >= 'a' ) { 01210 c -= 0x20; 01211 } 01212 c -= '0'; 01213 if ( c >= 17 ) { 01214 c -= 7; 01215 if ( c <= 9 ) { 01216 return 0; /* invalid char */ 01217 } 01218 } 01219 if ( c >= r ) { 01220 return 0; /* invalid char for current radix */ 01221 } 01222 val = val * r + c; 01223 c = *(++(*str)); 01224 } 01225 if (s) val = 0 - val; /* apply sign if needed */ 01226 *res = val; 01227 return 1; 01228 }
Generated on Sat Jul 16 2022 06:38:26 by 1.7.2