#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,"");
void fatfs_rename(const char* old_name, const char* new_name,int(*printf)(const char* format, ...)) {
FRESULT res = f_rename(old_name, new_name);
switch (res) {
case FR_OK:
printf("重命名成功: %s -> %s\r\n", old_name, new_name);
break;
case FR_NO_FILE:
printf("错误: 原文件/目录不存在\r\n");
break;
case FR_EXIST:
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);
}
}
static char new_path[sizeof(pwd)]={0};
static int renameCMD(CmdObj obj,char *str,int len)
{
char *p[2];
if(ParamGet(str,p,2)==2)
{
int temp;
{
int i=0;
for(i=0;i<pwdCount;i++)
{
new_path[i]=pwd[i];
}
}
temp=pwdCount;
pwdCount+=sprintf(&pwd[pwdCount],"/%s",p[0]);
sprintf(&new_path[temp],"/%s",p[1]);
// obj->printf("\r\n%s",pwd);
// obj->printf("\r\n%s",new_path);
fatfs_rename(pwd,new_path,obj->printf);
{
int i;
for(i=pwdCount;i>0;i--)
{
if(pwd[i]=='/')
{
pwd[i]=0;
pwdCount=i;
break;
}
}
}
// obj->printf("\r\n%s",p[0]);
// obj->printf("\r\n%s",p[1]);
}
return 1;
}
CmdDef(rename,0,renameCMD,"");
XCOSnTh-fatfsShell
于 2025-05-22 13:06:45 首次发布