?
#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,"");