diff --git a/demo/x86-gcc/makefile b/demo/x86-gcc/makefile index 73ac3e3..e30b42a 100644 --- a/demo/x86-gcc/makefile +++ b/demo/x86-gcc/makefile @@ -1,13 +1,15 @@ all : mkdir out -out : main.o shell_port.o shell.o shell_ext.o shell_cmd_list.o - gcc -o build/out -T shell.lds build/main.o build/shell_port.o build/shell.o build/shell_ext.o build/shell_cmd_list.o +out : main.o shell_port.o shell.o shell_ext.o shell_cmd_list.o shell_companion.o shell_fs.o + gcc -o build/out -T shell.lds build/main.o build/shell_port.o \ + build/shell.o build/shell_ext.o build/shell_cmd_list.o \ + build/shell_companion.o build/shell_fs.o main.o : main.c shell_port.h gcc -c main.c -I ./ -I ../../src -o build/main.o -shell_port.o : shell_port.c ../../src/shell.h - gcc -c shell_port.c -I ./ -I ../../src -o build/shell_port.o +shell_port.o : shell_port.c ../../src/shell.h ../../extensions/fs_support/shell_fs.h + gcc -c shell_port.c -I ./ -I ../../src -I ../../extensions/fs_support -o build/shell_port.o shell.o : ../../src/shell.c ../../src/shell.h shell_cfg.h gcc -c ../../src/shell.c -I ./ -I ../../src -o build/shell.o @@ -18,6 +20,12 @@ shell_ext.o : ../../src/shell_ext.c ../../src/shell_ext.h ../../src/shell.h shel shell_cmd_list.o : ../../src/shell_cmd_list.c ../../src/shell.h shell_cfg.h gcc -c ../../src/shell_cmd_list.c -I ./ -I ../../src -o build/shell_cmd_list.o +shell_companion.o : ../../src/shell_companion.c ../../src/shell.h shell_cfg.h + gcc -c ../../src/shell_companion.c -I ./ -I ../../src -o build/shell_companion.o + +shell_fs.o : ../../extensions/fs_support/shell_fs.c ../../extensions/fs_support/shell_fs.h shell_cfg.h ../../src/shell.h + gcc -c ../../extensions/fs_support/shell_fs.c -I ./ -I ../../src -I ../../extensions/fs_support -o build/shell_fs.o + .PHONY : all clean mkdir clean : -rm -r build diff --git a/demo/x86-gcc/shell_cfg.h b/demo/x86-gcc/shell_cfg.h index 8f8b446..d500d2c 100644 --- a/demo/x86-gcc/shell_cfg.h +++ b/demo/x86-gcc/shell_cfg.h @@ -12,6 +12,7 @@ #ifndef __SHELL_CFG_H__ #define __SHELL_CFG_H__ +#include "stdlib.h" /** * @brief 是否使用默认shell任务while循环,使能宏`SHELL_USING_TASK`后此宏有意义 @@ -27,6 +28,17 @@ */ #define SHELL_USING_CMD_EXPORT 1 +/** + * @brief 是否使用shell伴生对象 + * 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象 + */ +#define SHELL_USING_COMPANION 1 + +/** + * @brief 支持shell尾行模式 + */ +#define SHELL_SUPPORT_END_LINE 0 + /** * @brief 是否在输出命令列表中列出用户 */ @@ -107,6 +119,18 @@ */ #define SHELL_GET_TICK() 0 +/** + * @brief shell内存分配 + * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 + */ +#define SHELL_MALLOC(size) malloc(size) + +/** + * @brief shell内存释放 + * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 + */ +#define SHELL_FREE(obj) free(obj) + /** * @brief 是否显示shell信息 */ diff --git a/demo/x86-gcc/shell_port.c b/demo/x86-gcc/shell_port.c index a82ef58..c994889 100644 --- a/demo/x86-gcc/shell_port.c +++ b/demo/x86-gcc/shell_port.c @@ -10,10 +10,17 @@ */ #include "shell.h" -#include "stdio.h" +#include "shell_fs.h" +#include +#include +#include +#include +#include Shell shell; char shellBuffer[512]; +ShellFs shellFs; +char shellPathBuffer[512] = "/"; /** * @brief 用户shell写 @@ -41,13 +48,44 @@ signed char userShellRead(char *data) return 0; } +/** + * @brief 列出文件 + * + * @param path 路径 + * @param buffer 结果缓冲 + * @param maxLen 最大缓冲长度 + * @return size_t 0 + */ +size_t userShellListDir(char *path, char *buffer, size_t maxLen) +{ + DIR *dir; + struct dirent *ptr; + int i; + dir = opendir(path); + memset(buffer, 0, maxLen); + while((ptr = readdir(dir)) != NULL) + { + strcat(buffer, ptr->d_name); + strcat(buffer, "\t"); + } + closedir(dir); + return 0; +} + /** * @brief 用户shell初始化 * */ void userShellInit(void) { + shellFs.getcwd = getcwd; + shellFs.chdir = chdir; + shellFs.listdir = userShellListDir; + shellFsInit(&shellFs, shellPathBuffer, 512); + shell.write = userShellWrite; shell.read = userShellRead; + shellSetPath(&shell, shellPathBuffer); shellInit(&shell, shellBuffer, 512); + shellCompanionAdd(&shell, SHELL_COMPANION_ID_FS, &shellFs); } diff --git a/doc/img/fs_support_preview.gif b/doc/img/fs_support_preview.gif new file mode 100644 index 0000000..df00a47 Binary files /dev/null and b/doc/img/fs_support_preview.gif differ diff --git a/extensions/fs_support/readme.md b/extensions/fs_support/readme.md new file mode 100644 index 0000000..9ceacc6 --- /dev/null +++ b/extensions/fs_support/readme.md @@ -0,0 +1,52 @@ +# letter shell file system support + +![version](https://img.shields.io/badge/version-1.0.0-brightgreen.svg) +![standard](https://img.shields.io/badge/standard-c99-brightgreen.svg) +![build](https://img.shields.io/badge/build-2020.08.16-brightgreen.svg) +![license](https://img.shields.io/badge/license-MIT-brightgreen.svg) + +letter shell文件系统支持 + +![preview](../../doc/img/fs_support_preview.gif) + +- [letter shell file system support](#letter-shell-file-system-support) + - [简介](#简介) + - [使用](#使用) + +## 简介 + +fs_support作为letter shell的插件,用于实现letter shell对常见文件系统操作的支持,比如说cd,ls等命令,fs_support依赖于letter shell的伴生对象功能,并且使用到了内存分配和内存释放,所以请确认已经配置好了letter shell + +fs_support并非一个完全实现的letter shell插件,由于文件系统的接口和操作系统以及具体使用的文件系统相关,所以fs_support仅仅通过接入几个基本的接口以实现`cd`,`ls`命令,具体使用时,可能需要根据使用的文件系统接口修改fs_support,letter shell的[demo/x86-gcc](demo/x86-gcc)下有针对linux平台的移植,可以及进行参考 + +## 使用 + +1. 声明`ShellFs`对象并申请当前路径数据缓冲区 + + ```c + ShellFs shellFs; + char shellPathBuffer[512] = "/"; + ``` + +2. 实现`getcwd`,`chdir`,`listdir`函数 + + 根据文件系统不同,这些函数会有不同的实现,请根据具体使用的环境进行修改 + +3. 初始化`ShellFs`对象 + + ```c + shellFs.getcwd = getcwd; + shellFs.chdir = chdir; + shellFs.listdir = userShellListDir; + shellFsInit(&shellFs, shellPathBuffer, 512); + ``` + +4. 初始化`Shell`对象 + + 设置shell当前路径缓冲,初始化shell,并添加伴生对象 + + ```C + shellSetPath(&shell, shellPathBuffer); + shellInit(&shell, shellBuffer, 512); + shellCompanionAdd(&shell, SHELL_COMPANION_ID_FS, &shellFs); + ``` diff --git a/extensions/fs_support/shell_fs.c b/extensions/fs_support/shell_fs.c new file mode 100644 index 0000000..432cc95 --- /dev/null +++ b/extensions/fs_support/shell_fs.c @@ -0,0 +1,74 @@ +/** + * @file shell_fs.c + * @author Letter (nevermindzzt@gmail.com) + * @brief shell file system support + * @version 0.1 + * @date 2020-07-22 + * + * @copyright (c) 2020 Letter + * + */ +#include "shell_fs.h" +#include "shell.h" +#include "stdio.h" + +/** + * @brief 改变当前路径(shell调用) + * + * @param dir 路径 + */ +void shellCD(char *dir) +{ + Shell *shell = shellGetCurrent(); + ShellFs *shellFs = shellCompanionGet(shell, SHELL_COMPANION_ID_FS); + SHELL_ASSERT(shellFs, return); + if (shellFs->chdir(dir) != 0) + { + shellWriteString(shell, "error: "); + shellWriteString(shell, dir); + shellWriteString(shell, " is not a directory\r\n"); + } + shellFs->getcwd(shellFs->info.path, shellFs->info.pathLen); +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +cd, shellCD, change dir); + +/** + * @brief 列出文件(shell调用) + * + */ +void shellLS(void) +{ + size_t count; + char *buffer; + + Shell *shell = shellGetCurrent(); + ShellFs *shellFs = shellCompanionGet(shell, SHELL_COMPANION_ID_FS); + SHELL_ASSERT(shellFs, return); + + buffer = SHELL_MALLOC(SHELL_FS_LIST_FILE_BUFFER_MAX); + SHELL_ASSERT(buffer, return); + count = shellFs->listdir(shellGetPath(shell), buffer, SHELL_FS_LIST_FILE_BUFFER_MAX); + + shellWriteString(shell, buffer); + + SHELL_FREE(buffer); +} +SHELL_EXPORT_CMD( +SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN, +ls, shellLS, list all files); + +/** + * @brief 初始化shell文件系统支持 + * + * @param shellFs shell文件系统对象 + * @param pathBuffer shell路径缓冲 + * @param pathLen 路径缓冲区大小 + */ +void shellFsInit(ShellFs *shellFs, char *pathBuffer, size_t pathLen) +{ + shellFs->info.path = pathBuffer; + shellFs->info.pathLen = pathLen; + shellFs->getcwd(shellFs->info.path, pathLen); +} diff --git a/extensions/fs_support/shell_fs.h b/extensions/fs_support/shell_fs.h new file mode 100644 index 0000000..522f50e --- /dev/null +++ b/extensions/fs_support/shell_fs.h @@ -0,0 +1,41 @@ +/** + * @file shell_fs.h + * @author Letter (nevermindzzt@gmail.com) + * @brief shell file system support + * @version 0.1 + * @date 2020-07-22 + * + * @copyright (c) 2020 Letter + * + */ +#ifndef __SHELL_FS_H__ +#define __SHELL_FS_H__ + +#include "stddef.h" +#include "shell.h" + +#define SHELL_FS_VERSION "1.0.0" + +#define SHELL_COMPANION_ID_FS -1 + +#define SHELL_FS_LIST_FILE_BUFFER_MAX 4096 + +/** + * @brief shell文件系统支持结构体 + * + */ +typedef struct shell_fs +{ + size_t (*getcwd)(char *, size_t); + size_t (*chdir)(char *); + size_t (*listdir)(char *dir, char *buffer, size_t maxLen); + + struct { + char *path; + size_t pathLen; + } info; +} ShellFs; + +void shellFsInit(ShellFs *shellFs, char *pathBuffer, size_t pathLen); + +#endif