]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/cmd_fat.c
2 * (C) Copyright 2014,2016,2018 Leo C. <erbl259-lmu@yahoo.de>
4 * SPDX-License-Identifier: GPL-2.0
8 * FAT filesystem commands
14 uint32_t fat_time(const struct tm
* timeptr
);
19 #include "con-utils.h"
20 #include "print-utils.h"
24 #include "getopt-min.h"
26 #define DEBUG_LS 0 /* set to 1 to debug */
27 #define DEBUG_RM 0 /* set to 1 to debug */
28 #define DEBUG_CP 0 /* set to 1 to debug */
30 #define debug_ls(fmt, args...) \
31 debug_cond(DEBUG_LS, fmt, ##args)
32 #define debug_rm(fmt, args...) \
33 debug_cond(DEBUG_RM, fmt, ##args)
34 #define debug_cp(fmt, args...) \
35 debug_cond(DEBUG_CP, fmt, ##args)
38 /* TODO: use memory size test function (z80_memsize_detect() ) */
39 #define MAX_MEMORY CONFIG_SYS_RAMSIZE_MAX
40 #define BUFFER_SIZE FF_MAX_SS
41 #define CPY_BUF_SIZE (2*FF_MAX_SS)
42 #define PATH_MAX CONFIG_SYS_MAX_PATHLEN
46 * Multible (fat) partitions per physical drive are not supported,
47 * but we have up to 2 sdcard slots.
52 void setup_fatfs(void)
54 f_mount(&FatFs0
, "0:", 0);
55 f_mount(&FatFs1
, "1:", 0);
58 DWORD
get_fattime (void)
64 gmtime_r(&timer
, &tm_timer
);
66 return fat_time(&tm_timer
);
71 bool check_abort(void)
76 printf_P(PSTR("Abort\n"));
82 static const FLASH
char * const FLASH rc_strings
[] = {
85 FSTR("Internal error"),
92 FSTR("Invalid object"),
93 FSTR("Write protected"),
94 FSTR("Invalid drive"),
96 FSTR("No file system"),
100 FSTR("Not enough core"),
101 FSTR("Too many open files"),
102 FSTR("Invalid parameter")
106 const FLASH
char * fat_rctostr(FRESULT rc
)
108 return rc
< ARRAY_SIZE(rc_strings
) ? rc_strings
[rc
] : PSTR(" Unknown Error");
114 static const FLASH
char swirlchar
[] = { '-','\\','|','/' };
115 static uint_fast8_t cnt
;
116 static uint32_t tstamp
;
118 if (get_timer(0) > tstamp
) {
119 tstamp
= get_timer(0) + 250;
122 putchar(swirlchar
[cnt
]);
127 void print_dirent(FILINFO
*f
)
129 printf_P(PSTR("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %s\n"),
130 (f
->fattrib
& AM_DIR
) ? 'D' : '-',
131 (f
->fattrib
& AM_RDO
) ? 'R' : '-',
132 (f
->fattrib
& AM_HID
) ? 'H' : '-',
133 (f
->fattrib
& AM_SYS
) ? 'S' : '-',
134 (f
->fattrib
& AM_ARC
) ? 'A' : '-',
135 (f
->fdate
>> 9) + 1980, (f
->fdate
>> 5) & 15, f
->fdate
& 31,
136 (f
->ftime
>> 11), (f
->ftime
>> 5) & 63,
141 char *path_split(char *p
)
143 if (isdigit(p
[0]) && (p
[1] == ':'))
146 char *ps
= strrchr(p
, '/');
150 memmove(ps
+1, ps
, strlen(ps
)+1);
159 typedef void (*fatfunc_t
)(const TCHAR
* path_old
, const TCHAR
* path_new
);
161 command_ret_t exit_val
;
163 #define I_FLAG (1<<1) // prompt before overwrite (overrides a previous -n option)
164 #define N_FLAG (1<<2) // do not overwrite an existing file (overrides a previous -i option)
165 #define F_FLAG (1<<3) // overwrite existing file ignoring write protection
166 #define P_FLAG (1<<4) // preserve attributes and timestamps
167 #define V_FLAG (1<<5) // explain what is being done
174 FRESULT
copy_file(const TCHAR
* src
, const TCHAR
* dst
)
179 /* File copy buffer */
180 uint8_t *buffer
= (uint8_t *) malloc(CPY_BUF_SIZE
);
181 if (buffer
== NULL
) {
182 res
= (FRESULT
) ENOMEM
;
185 /* Open source file */
186 res
= f_open(&fsrc
, src
, FA_READ
);
189 /* Create destination file */
190 res
= f_open(&fdst
, dst
, FA_WRITE
| FA_CREATE_NEW
);
192 UINT br
, bw
; /* File read/write count */
194 /* Copy source to destination */
196 res
= f_read(&fsrc
, buffer
, CPY_BUF_SIZE
, &br
); /* Read a chunk of source file */
198 break; /* error or eof */
199 res
= f_write(&fdst
, buffer
, br
, &bw
); /* Write it to the destination file */
203 res
= (FRESULT
) EFULL
; /* disk full */
221 void ff_remove(const TCHAR
*file
, const TCHAR
*dest UNUSED
)
225 debug_rm("==== ff_remove: '%s'\n", file
);
227 if (!(cmd_flags
& N_FLAG
)) {
228 if ((res
= f_unlink(file
)) == FR_OK
) {
229 if (cmd_flags
& V_FLAG
)
230 printf_P(PSTR("removed: '%s'\n"), file
);
232 cmd_error(0, res
, PSTR("cannot remove '%s'"), file
);
235 printf_P(PSTR("not removed: '%s'\n"), file
);
238 exit_val
= (res
!= FR_OK
);
243 void ff_copy(const TCHAR
* path_old
, const TCHAR
* path_new
)
247 debug_cp("==== ff_copy: '%s' --> '%s'\n", path_old
, path_new
);
249 if (cmd_flags
& V_FLAG
)
250 printf_P(PSTR("'%s' -> '%s'\n"), path_old
, path_new
);
251 if ((res
= copy_file(path_old
, path_new
)) != FR_OK
)
252 cmd_error(0, res
, PSTR("error copying '%s' to '%s'"), path_old
, path_new
);
254 exit_val
= (res
!= FR_OK
);
259 void ff_move(const TCHAR
* path_old
, const TCHAR
* path_new
)
263 if (cmd_flags
& V_FLAG
)
264 printf_P(PSTR("'%s' -> '%s'\n"), path_old
, path_new
);
265 if ((res
= f_rename(path_old
, path_new
)) != FR_OK
)
266 cmd_error(0, res
, PSTR("error copying '%s' to '%s'"), path_old
, path_new
);
268 exit_val
= (res
!= FR_OK
);
273 void ff_iterate(fatfunc_t fatfunc
, int count
, char* const file
[], char* dest
)
278 char srcpath
[PATH_MAX
], destpath
[PATH_MAX
];
279 uint8_t dest_is_dir
= 0;
282 if (f_opendir(&dir
, dest
) == FR_OK
) {
285 } else if (f_stat(dest
, &finfo
) == FR_OK
&& finfo
.fattrib
& AM_DIR
)
289 for (uint8_t i
= 0; i
< count
; i
++) {
290 char* pattern
= NULL
;
291 strcpy(srcpath
, file
[i
]);
292 char* p1
= path_split(srcpath
);
295 pattern
= (char *) malloc(strlen(p1
)+1);
298 if (pattern
!= NULL
) {
299 res
= f_findfirst(&dir
, &finfo
, srcpath
, pattern
);
300 p1
= srcpath
+strlen(srcpath
)-1;
304 res
= f_findfirst(&dir
, &finfo
, ".", file
[i
]);
307 if ((res
!= FR_OK
) || (finfo
.fname
[0] == 0)) {
308 cmd_error(0, res
, PSTR("'%s': no such file or directory"), file
[i
]);
309 exit_val
= CMD_RET_FAILURE
;
312 while (res
== FR_OK
&& finfo
.fname
[0] != 0) {
313 strcpy(p1
, finfo
.fname
);
315 strcpy(destpath
, dest
);
317 if (destpath
[strlen(destpath
) - 1] != '/')
318 strcat_P(destpath
, PSTR("/"));
319 strcat(destpath
, finfo
.fname
);
322 fatfunc(srcpath
, destpath
);
323 res
= f_findnext(&dir
, &finfo
);
326 cmd_error(CMD_RET_FAILURE
, res
, PSTR("error enumerating files"));
334 * pwd - Print current directory of the current drive.
337 command_ret_t
do_pwd(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc UNUSED
, char * const argv
[] UNUSED
)
342 res
= f_getcwd(buf
, PATH_MAX
); /* Get current directory path */
345 cmd_error(CMD_RET_FAILURE
, res
, NULL
);
349 return CMD_RET_SUCCESS
;
354 * cd - Change the current/working directory.
357 command_ret_t
do_cd(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
363 path
= getenv_str(PSTR(ENV_HOME
));
365 cmd_error(CMD_RET_FAILURE
, 0, PSTR("\"%S\" not set"), PSTR(ENV_HOME
));
370 if (strlen(path
) > 1 && path
[1] == ':')
371 res
= f_chdrive(path
);
377 cmd_error(CMD_RET_FAILURE
, res
, NULL
);
379 return CMD_RET_SUCCESS
;
383 command_ret_t
do_mkdir(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
385 int ret
= CMD_RET_SUCCESS
;
389 return CMD_RET_USAGE
;
391 for (uint8_t i
= 1; i
< argc
; i
++) {
392 if ((res
= f_mkdir(argv
[i
])) != FR_OK
) {
393 ret
= CMD_RET_FAILURE
;
394 cmd_error(0, res
, PSTR("cannot create directory '%s'"), argv
[i
]);
401 * ls path - Directory listing
404 command_ret_t
do_ls(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
407 DIR dir
; /* Directory object */
417 memset(buf
, 0, PATH_MAX
);
421 strncpy(path
, argv
[1], PATH_MAX
-1);
423 pattern
= path_split(path
);
424 debug_ls("### path, pattern: '%s', '%s'\n", path
[0] ? path
: "<NULL>", pattern
? pattern
: "<NULL>");
426 if (pattern
== NULL
) {
427 res
= f_opendir(&dir
, path
);
428 if (res
== FR_NO_PATH
|| res
== FR_INVALID_NAME
) {
431 } else if (res
!= FR_OK
) {
432 cmd_error(CMD_RET_FAILURE
, res
, PSTR("'%s'"), path
);
435 debug_ls("### path, pattern: '%s', '%s'\n", path
, pattern
? pattern
: "<NULL>");
437 if (pattern
== NULL
|| *pattern
== '\0')
440 debug_ls("### path, pattern: '%s', '%s'\n", path
, pattern
? pattern
: "<NULL>");
442 res
= f_findfirst(&dir
, &finfo
, path
, pattern
);
447 cmd_error(CMD_RET_FAILURE
, res
, NULL
);
450 if (finfo
.fattrib
& AM_DIR
) {
453 s1
++; p1
+= finfo
.fsize
;
455 print_dirent(&finfo
);
458 res
= f_findnext(&dir
, &finfo
);
462 printf_P(PSTR("%4u File(s),%10lu bytes total\n%4u Dir(s)"), s1
, p1
, s2
);
463 if (f_getfree(path
, (DWORD
*)&p1
, &fs
) == FR_OK
)
464 printf_P(PSTR(", %10luK bytes free\n"), p1
* fs
->csize
/ 2);
468 cmd_error(CMD_RET_FAILURE
, res
, NULL
);
470 return CMD_RET_SUCCESS
;
473 command_ret_t
do_rm(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
475 exit_val
= CMD_RET_SUCCESS
;
479 while ((opt
= getopt(argc
, argv
, PSTR("nv"))) != -1) {
488 return CMD_RET_USAGE
;
495 debug_rm("==== do_rm: argc, argv[0]: %d, '%s'\n", argc
, argv
[0]);
498 return CMD_RET_USAGE
;
500 ff_iterate(ff_remove
, argc
, argv
, NULL
);
505 command_ret_t
do_cp_or_mv(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
507 exit_val
= CMD_RET_SUCCESS
;
509 fatfunc_t func
= (argv
[0][0] == 'c') ? ff_copy
: ff_move
;
512 while ((opt
= getopt(argc
, argv
, PSTR("v"))) != -1) {
518 return CMD_RET_USAGE
;
525 debug_cp("==== do_rm: argc, argv[0]: %d, '%s'\n", argc
, argv
[0]);
528 return CMD_RET_USAGE
;
530 ff_iterate(func
, argc
- 1, argv
, argv
[argc
- 1]);
535 /* Work register for fs command */
538 WORD AccFiles
, AccDirs
;
544 char *path
, /* Pointer to the working buffer with start path */
545 struct stat_dat_s
*statp
553 res
= f_opendir(&dirs
, path
);
557 while (((res
= f_readdir(&dirs
, &statp
->finfo
)) == FR_OK
) &&
558 statp
->finfo
.fname
[0]) {
559 if (FF_FS_RPATH
&& statp
->finfo
.fname
[0] == '.')
561 fn
= statp
->finfo
.fname
;
562 if (statp
->finfo
.fattrib
& AM_DIR
) {
565 strcpy(path
+i
+1, fn
);
566 res
= scan_files(path
, statp
);
571 //printf_P(PSTR("%s/%s\n"), path, fn);
573 statp
->AccSize
+= statp
->finfo
.fsize
;
587 * fatstat path - Show logical drive status
590 command_ret_t
do_stat(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
597 struct stat_dat_s statp
;
599 buf
= (char *) malloc(PATH_MAX
);
601 cmd_error(CMD_RET_FAILURE
, ENOMEM
, NULL
);
605 res
= f_getfree(path
, &nfreeclst
, &fs
);
609 "Bytes/Cluster: %lu\n"
610 "Number of FATs: %u\n"
611 "Root DIR entries: %u\n"
613 "Number of clusters: %lu\n"
614 "FAT start (lba): %lu\n"
615 "DIR start (lba,cluster): %lu\n"
616 "Data start (lba): %lu\n"),
617 fs
->fs_type
, (DWORD
)fs
->csize
* 512, fs
->n_fats
,
618 fs
->n_rootdir
, fs
->fsize
, fs
->n_fatent
- 2,
619 fs
->fatbase
, fs
->dirbase
, fs
->database
);
623 res
= f_getlabel(path
, buf
, &serial
);
627 "Volume S/N: %04X-%04X\n"),
628 buf
, (WORD
)(serial
>> 16), (WORD
)(serial
& 0xFFFF));
632 statp
.AccSize
= statp
.AccFiles
= statp
.AccDirs
= 0;
635 my_puts_P(PSTR("\nCounting... "));
636 res
= scan_files(buf
, &statp
);
640 printf_P(PSTR("%u files, %lu bytes.\n%u folders.\n"
641 "%lu KB total disk space.\n%lu KB available.\n"),
642 statp
.AccFiles
, statp
.AccSize
, statp
.AccDirs
,
643 (fs
->n_fatent
- 2) * (fs
->csize
/ 2), nfreeclst
* (fs
->csize
/ 2)
650 cmd_error(CMD_RET_FAILURE
, res
, NULL
);
652 return CMD_RET_SUCCESS
;
656 * tst path - for debugging: test access with different functions
659 command_ret_t
do_tst(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
661 DIR Dir
; /* Directory object */
664 char buf
[BUFFER_SIZE
];
668 printf_P(PSTR("sizeof DIR: %u, sizeof FIL: %u\n"), sizeof (DIR), sizeof (FILINFO
));
670 res
= f_getcwd(buf
, BUFFER_SIZE
); /* Get current directory path */
672 printf_P(PSTR("cwd: '%s', --> res: %d, %S\n"), buf
, res
, fat_rctostr(res
));
678 printf_P(PSTR("arg: '%s' '%s'\n"), path
, pattern
);
680 res
= f_stat(path
, &finfo
);
681 printf_P(PSTR("f_stat: --> res: %d, %S\n"), res
, fat_rctostr(res
));
682 if (res
== FR_OK
) print_dirent(&finfo
);
684 res
= f_opendir(&Dir
, path
);
685 printf_P(PSTR("f_opendir: --> res: %d, %S\n"), res
, fat_rctostr(res
));
688 res
= f_findfirst(&Dir
, &finfo
, path
, pattern
);
689 printf_P(PSTR("f_findfirst: --> res: %d, %S\n"), res
, fat_rctostr(res
));
690 if (res
== FR_OK
) print_dirent(&finfo
);
693 return CMD_RET_SUCCESS
;
697 * fatread/write - load binary file to/from a dos filesystem
698 * read <d:/path/filename> <addr> [bytes [pos]]
699 * write <d:/path/filename> <addr> <bytes>
701 command_ret_t
do_rw(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
707 unsigned long bytes_rw
;
709 bool dowrite
= (argv
[0][0] == 'w');
715 if (argc
< (dowrite
? 4 : 3))
716 return CMD_RET_USAGE
;
718 addr
= eval_arg(argv
[2], NULL
);
719 if (addr
>= MAX_MEMORY
)
720 cmd_error(CMD_RET_FAILURE
, 0, PSTR("Address too high: %#lx"), addr
);
723 bytes
= eval_arg(argv
[3], NULL
);
727 pos
= eval_arg(argv
[4], NULL
);
731 if (addr
+ bytes
> MAX_MEMORY
)
732 bytes
= MAX_MEMORY
- addr
;
734 buffer
= (uint8_t *) malloc(BUFFER_SIZE
);
736 cmd_error(CMD_RET_FAILURE
, ENOMEM
, NULL
);
738 res
= f_open(&File
, argv
[1], dowrite
? FA_WRITE
| FA_CREATE_ALWAYS
742 res
= f_lseek(&File
, pos
);
745 timer
= get_timer(0);
747 unsigned int cnt
, br
;
749 if (bytes
>= BUFFER_SIZE
) {
751 bytes
-= BUFFER_SIZE
;
753 cnt
= bytes
; bytes
= 0;
756 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
)) {
760 z80_read_block(buffer
, addr
, cnt
);
761 z80_bus_cmd(Release
);
762 res
= f_write(&File
, buffer
, cnt
, &br
);
766 res
= f_read(&File
, buffer
, cnt
, &br
);
769 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
)) {
773 z80_write_block(buffer
, addr
, br
);
774 z80_bus_cmd(Release
);
781 printf_P(PSTR("Disk full?\n"));
788 FRESULT fr
= f_close(&File
);
791 timer
= get_timer(timer
);
792 printf_P(PSTR("%lu (%#lx) bytes read/written with %lu bytes/sec.\n"),
793 bytes_rw
, bytes_rw
, timer
? (bytes_rw
* 1000 / timer
) : 0);
800 cmd_error(CMD_RET_FAILURE
, res
, PSTR("'%s'"), argv
[1]);
802 cmd_error(CMD_RET_FAILURE
, EBUSTO
, NULL
);
804 return CMD_RET_SUCCESS
;
807 command_ret_t
do_dump(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
813 return CMD_RET_USAGE
;
815 bool hexdump
= argv
[0][0] == 'x';
817 uint8_t *buffer
= (uint8_t *) malloc(BUFFER_SIZE
);
819 cmd_error(CMD_RET_FAILURE
, ENOMEM
, NULL
);
821 res
= f_open(&File
, argv
[1], FA_READ
);
824 uint32_t filepos
= 0;
829 res
= f_read(&File
, buffer
, BUFFER_SIZE
, &br
);
831 /* Print the lines. */
833 dump_ram(buffer
, filepos
, br
, NULL
);
835 for (unsigned int i
= 0; i
< br
; ++i
) {
836 putchar(ch
= buffer
[i
]);
841 if (!hexdump
&& (ch
!= '\n'))
849 cmd_error(CMD_RET_FAILURE
, res
, PSTR("'%s'"), argv
[1]);
851 return CMD_RET_SUCCESS
;
855 * command table for fat subcommands
858 cmd_tbl_t cmd_tbl_fat
[] = {
860 status
, 2, CTBL_RPT
, do_stat
,
861 "Show logical drive status",
865 pwd
, 2, CTBL_RPT
|CTBL_SUBCMDAUTO
, do_pwd
,
866 "Print name of current/working directory",
870 cd
, 2, 0|CTBL_SUBCMDAUTO
, do_cd
,
871 "Change the current/working directory.",
875 mkdir
, CONFIG_SYS_MAXARGS
, 0, do_mkdir
,
876 "Create the DIRECTORY(ies), if they do not already exist.",
880 mkdir
, CONFIG_SYS_MAXARGS
, 0|CTBL_SUBCMDAUTO
, do_mkdir
,
881 "Create the DIRECTORY(ies), if they do not already exist.",
885 ls
, 2, CTBL_RPT
|CTBL_SUBCMDAUTO
, do_ls
,
890 rm
, CONFIG_SYS_MAXARGS
, 0, do_rm
,
891 "Remove FILE(s) or empty DIRECTORY(ies)",
892 "[OPTION]... [FILE]...\n"
893 //" -i prompt before removal\n"
894 " -n do not remove\n"
895 " -v explain what is being done"
898 rm
, CONFIG_SYS_MAXARGS
, 0|CTBL_SUBCMDAUTO
, do_rm
,
899 "Remove FILE(s) or empty DIRECTORY(ies)",
900 "[OPTION]... [FILE]...\n"
901 //" -i prompt before removal\n"
902 " -n do not remove\n"
903 " -v explain what is being done"
906 cp
, CONFIG_SYS_MAXARGS
, 0, do_cp_or_mv
,
907 "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.",
908 "[OPTION]... SOURCE... DEST\n"
909 // " -f overwrite existing file ignoring write protection\n"
910 // " this option is ignored when the -n option is also used\n"
911 // " -i prompt before overwrite (overrides a previous -n option)\n"
912 // " -n do not overwrite an existing file (overrides a previous -i option)\n"
913 // " -p preserve attributes and timestamps\n"
914 " -v explain what is being done"
917 cp
, CONFIG_SYS_MAXARGS
, 0|CTBL_SUBCMDAUTO
, do_cp_or_mv
,
918 "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.",
919 "[OPTION]... SOURCE... DEST\n"
920 // " -f overwrite existing file ignoring write protection\n"
921 // " this option is ignored when the -n option is also used\n"
922 // " -i prompt before overwrite (overrides a previous -n option)\n"
923 // " -n do not overwrite an existing file (overrides a previous -i option)\n"
924 // " -p preserve attributes and timestamps\n"
925 " -v explain what is being done"
928 mv
, CONFIG_SYS_MAXARGS
, 0, do_cp_or_mv
,
929 "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.",
930 "[OPTION]... SOURCE DEST\n"
931 " -v explain what is being done"
934 mv
, CONFIG_SYS_MAXARGS
, 0|CTBL_SUBCMDAUTO
, do_cp_or_mv
,
935 "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.",
936 "[OPTION]... SOURCE DEST\n"
937 " -v explain what is being done"
940 tst
, 3, CTBL_DBG
|CTBL_RPT
, do_tst
,
941 "FatFS test function",
946 "load binary file from a dos filesystem",
947 "<d:/path/filename> <addr> [bytes [pos]]\n"
948 " - Load binary file 'path/filename' on logical drive 'd'\n"
949 " to address 'addr' from dos filesystem.\n"
950 " 'pos' gives the file position to start loading from.\n"
951 " If 'pos' is omitted, 0 is used. 'pos' requires 'bytes'.\n"
952 " 'bytes' gives the size to load. If 'bytes' is 0 or omitted,\n"
953 " the load stops on end of file."
957 "write file into a dos filesystem",
958 "<d:/path/filename> <addr> <bytes>\n"
959 " - Write file to 'path/filename' on logical drive 'd' from RAM\n"
960 " starting at address 'addr'.\n"
963 xxd
, 2, 1|CTBL_SUBCMDAUTO
, do_dump
,
964 "print file as hexdump",
965 "<d:/path/filename>\n"
968 type
, 2, 1|CTBL_SUBCMDAUTO
, do_dump
,
970 "<d:/path/filename>\n"
974 help
, CONFIG_SYS_MAXARGS
, CTBL_RPT
, do_help
,
975 "Print sub command description/usage",
977 " - print brief description of all sub commands\n"
978 "fat help command ...\n"
979 " - print detailed usage of sub cmd 'command'"
982 /* This does not use the CMD_TBL_ITEM macro as ? can't be used in symbol names */
983 {FSTR("?"), CONFIG_SYS_MAXARGS
, 1, do_help
,
985 #ifdef CONFIG_SYS_LONGHELP
987 #endif /* CONFIG_SYS_LONGHELP */
989 #ifdef CONFIG_AUTO_COMPLETE
993 /* Mark end of table */
994 CMD_TBL_END(cmd_tbl_fat
)
998 command_ret_t
do_fat(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc UNUSED
, char * const argv
[] UNUSED
)
1000 puts_P(PSTR("Huch?"));
1002 return CMD_RET_USAGE
;