#include "XCOSnTh.h"
#include "ff.h"
#include "stdio.h"
static char pwd[1024]="1:";
static char pwdCount=2;
FRESULT lsExe(char *path,int(*printf)(const char* format, ...))
{FRESULT res;DIR dir;FILINFO fno;// 打开根目录res = f_opendir(&dir, path);if (res != FR_OK) {// 处理错误,比如未找到目录printf("\r\nerror %d",res);return res;}// 循环读取目录条目for (;;) {res = f_readdir(&dir, &fno);if (res != FR_OK || fno.fname[0] == 0) {break; // 错误或遍历完成}// 忽略 "." 和 ".." 条目(根据系统配置可能存在)if (fno.fname[0] == '.') continue;// 判断是文件还是目录if (fno.fattrib & AM_DIR) {// 目录:显示时加标记,比如 [D] 文件夹名printf("[D] %s\r\n", fno.fname);} else {// 文件:直接显示文件名printf("[F] %s\r\n", fno.fname);}}// 关闭目录(某些版本 FatFs 可省略)f_closedir(&dir);return FR_OK;
}
static int lsCMD(CmdObj obj,char *str,int len)
{lsExe(pwd,obj->printf);return 1;
}
CmdDef(ls,0,lsCMD,"");
static int pwdCMD(CmdObj obj,char *str,int len)
{obj->printf("\r\n%s",pwd);return 1;
}
CmdDef(pwd,0,pwdCMD,"");
static int cdCMD(CmdObj obj,char *str,int len)
{str[len]=0;if(str[0]=='.'){if(str[1]=='.'){int i;for(i=pwdCount;i>0;i--){if(pwd[i]=='/'){pwd[i]=0;pwdCount=i;break;}}}}else{pwdCount+=sprintf(&pwd[pwdCount],"/%s",str);}obj->printf("%s\r\n",pwd);if(lsExe(pwd,obj->printf)!=FR_OK){int i;for(i=pwdCount;i>0;i--){if(pwd[i]=='/'){pwd[i]=0;pwdCount=i;break;}}obj->printf("\r\n%s",pwd);}return 1;
}
CmdDef(cd,0,cdCMD,"");static int mkdirCMD(CmdObj obj,char *str,int len)
{pwdCount+=sprintf(&pwd[pwdCount],"/%s",str);f_mkdir(pwd);{int i;for(i=pwdCount;i>0;i--){if(pwd[i]=='/'){pwd[i]=0;pwdCount=i;break;}}}lsExe(pwd,obj->printf);return 1;
}
CmdDef(mkdir,0,mkdirCMD,"");void delete_directory(char *path) {FRESULT res;// 确保文件系统已挂载(如 f_mount(&fs, "", 1))// 删除空目录res = f_unlink(path);// 错误处理switch (res) {case FR_OK:printf("目录删除成功!\r\n");break;case FR_NO_FILE:case FR_NO_PATH:printf("目录不存在!\r\n");break;case FR_DENIED:printf("目录非空或权限不足!\r\n");break;case FR_INVALID_NAME:printf("路径格式错误!\r\n");break;default:printf("错误代码:%d\r\n", res);}
}
void delete_directory_recursive(const TCHAR* path) {//递归删除DIR dir;FILINFO fno;FRESULT res;res = f_opendir(&dir, path);if (res != FR_OK) return;while (1) {res = f_readdir(&dir, &fno);if (res != FR_OK || fno.fname[0] == 0) break;if (fno.fname[0] == '.') continue; // 忽略 "." 和 ".."TCHAR sub_path[256];sprintf(sub_path, "%s/%s", path, fno.fname);if (fno.fattrib & AM_DIR) {delete_directory_recursive(sub_path); // 递归删除子目录} else {f_unlink(sub_path); // 删除文件}}f_closedir(&dir);f_unlink(path); // 删除空目录
}
static int rmCMD(CmdObj obj,char *str,int len)
{str[len]=0;if((str[0]=='-')&&(str[1]=='r')){pwdCount+=sprintf(&pwd[pwdCount],"/%s",&str[3]);delete_directory_recursive(pwd);}else{pwdCount+=sprintf(&pwd[pwdCount],"/%s",str);delete_directory(pwd);}{int i;for(i=pwdCount;i>0;i--){if(pwd[i]=='/'){pwd[i]=0;pwdCount=i;break;}}}lsExe(pwd,obj->printf);return 1;
}
CmdDef(rm,0,rmCMD,"");void create_file(char *path,int(*printf)(const char* format, ...)) {FRESULT res;FIL fil; // 文件对象// 确保文件系统已挂载(如 f_mount(&fs, "", 1))// 创建文件(若存在则覆盖)res = f_open(&fil, path, FA_CREATE_ALWAYS | FA_WRITE);// 错误处理if (res == FR_OK) {printf("文件创建成功!\r\n");// 可选:写入初始内容(例如空文件则无需写入)// UINT bytes_written;// f_write(&fil, "Hello", 5, &bytes_written);f_close(&fil); // 必须关闭文件!} else {switch (res) {case FR_EXIST:printf("文件已存在(若使用 FA_CREATE_NEW)!\r\n");break;case FR_INVALID_NAME:printf("路径格式错误!\r\n");break;case FR_DENIED:printf("磁盘已满或写保护!\r\n");break;default:printf("错误代码:%d\r\n", res);}}
}
static int touchCMD(CmdObj obj,char *str,int len)
{pwdCount+=sprintf(&pwd[pwdCount],"/%s",str);create_file(pwd,obj->printf);{int i;for(i=pwdCount;i>0;i--){if(pwd[i]=='/'){pwd[i]=0;pwdCount=i;break;}}}lsExe(pwd,obj->printf);return 1;
}
CmdDef(touch,0,touchCMD,"");void check_file_status(char *path,int(*printf)(const char* format, ...)) {FRESULT res;FILINFO fno;// 确保文件系统已挂载(如 f_mount(&fs, "", 1))// 获取文件状态res = f_stat(path, &fno);// 处理结果if (res == FR_OK) {printf("文件状态信息:\r\n");printf("- 文件名: %s\r\n", fno.fname);printf("- 大小: %ld 字节\r\n", fno.fsize);printf("- 属性: %s%s\r\n",(fno.fattrib & AM_DIR) ? "[目录]" : "[文件]",(fno.fattrib & AM_RDO) ? " (只读)" : "");// 解析日期和时间(FAT 格式)uint16_t fdate = fno.fdate;uint16_t ftime = fno.ftime;printf("- 修改日期: %04d-%02d-%02d\r\n",(1980 + (fdate >> 9)), // 年(fdate >> 5) & 0x0F, // 月fdate & 0x1F); // 日printf("- 修改时间: %02d:%02d:%02d\r\n",(ftime >> 11), // 小时(ftime >> 5) & 0x3F, // 分钟(ftime & 0x1F) * 2); // 秒(精度为2秒)} else {switch (res) {case FR_NO_FILE:printf("文件不存在!\r\n");break;case FR_INVALID_NAME:printf("路径格式错误!\r\n");break;default:printf("错误代码:%d\r\n", res);}}
}static int statCMD(CmdObj obj,char *str,int len)
{pwdCount+=sprintf(&pwd[pwdCount],"/%s",str);check_file_status(pwd,obj->printf);{int i;for(i=pwdCount;i>0;i--){if(pwd[i]=='/'){pwd[i]=0;pwdCount=i;break;}}}return 1;
}
CmdDef(stat,0,statCMD,"");