This commit is contained in:
sc committed 2026-02-14 19:03:02 +08:00
commit da43152a7e
3380 files changed
+1128754

No files matched your search

+97
View File
@@ -0,0 +1,97 @@
menuconfig RT_USING_MSH
bool "MSH: command shell"
default n if RT_USING_NANO
default y
select RT_USING_SEMAPHORE
if RT_USING_MSH
config RT_USING_FINSH
bool
default y
config FINSH_USING_MSH
bool
default y
config FINSH_THREAD_NAME
string "The msh thread name"
default "tshell"
config FINSH_THREAD_PRIORITY
int "The priority level value of thread"
default 20
config FINSH_THREAD_STACK_SIZE
int "The stack size for thread"
default 4096
config FINSH_USING_HISTORY
bool "Enable command history feature"
default y
if FINSH_USING_HISTORY
config FINSH_HISTORY_LINES
int "The command history line number"
default 5
endif
config FINSH_USING_WORD_OPERATION
bool "Enable word-based cursor operations"
default n
help
Enable Ctrl+Backspace to delete words and Ctrl+Arrow to move cursor by word
config FINSH_USING_FUNC_EXT
bool "Enable function extension home end ins del"
default n
help
Enable function extension home end ins del.
config FINSH_USING_SYMTAB
bool "Using symbol table for commands"
default y
config FINSH_CMD_SIZE
int "The command line size for shell"
default 80
config MSH_USING_BUILT_IN_COMMANDS
bool "Enable built-in commands, such as list_thread"
default y
config FINSH_USING_DESCRIPTION
bool "Keeping description in symbol table"
default y
config FINSH_ECHO_DISABLE_DEFAULT
bool "Disable the echo mode in default"
default n
config FINSH_USING_AUTH
bool "shell support authentication"
default n
if FINSH_USING_AUTH
config FINSH_DEFAULT_PASSWORD
string "The default password for shell authentication"
default "rtthread"
config FINSH_PASSWORD_MIN
int "The password min length"
default 6
config FINSH_PASSWORD_MAX
int "The password max length"
default RT_NAME_MAX
endif
config FINSH_ARG_MAX
int "The number of arguments for a shell command"
default 10
config FINSH_USING_OPTION_COMPLETION
bool "command option completion enable"
default y
endif
@@ -0,0 +1,26 @@
from building import *
from gcc import GetGCCLikePLATFORM
cwd = GetCurrentDir()
src = Split('''
shell.c
msh.c
msh_parse.c
''')
CPPPATH = [cwd]
LOCAL_CFLAGS = ''
if rtconfig.PLATFORM in ['gcc']: # only for GCC
LOCAL_CFLAGS += ' -Wstack-usage=' + str(GetConfigValue('FINSH_THREAD_STACK_SIZE')) # check finsh thread stack size
if GetDepend('MSH_USING_BUILT_IN_COMMANDS'):
src += ['cmd.c']
if GetDepend('DFS_USING_POSIX'):
src += ['msh_file.c']
group = DefineGroup('Finsh', src, depend = ['RT_USING_FINSH'], CPPPATH = CPPPATH,
LOCAL_CFLAGS = LOCAL_CFLAGS)
Return('group')
File diff suppressed because it is too large. Load diff
+276
View File
@@ -0,0 +1,276 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_H__
#define __FINSH_H__
#include <rtdef.h>
#ifdef _MSC_VER
#pragma section("FSymTab$f",read)
#endif /* _MSC_VER */
#ifdef FINSH_USING_OPTION_COMPLETION
#define FINSH_COND(opt) opt,
#else
#define FINSH_COND(opt)
#endif
#ifdef FINSH_USING_DESCRIPTION
#define FINSH_DESC(cmd, desc) __fsym_##cmd##_desc,
#else
#define FINSH_DESC(cmd, desc)
#endif
typedef long (*syscall_func)(void);
#ifdef FINSH_USING_SYMTAB
#ifdef __TI_COMPILER_VERSION__
#define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
#endif /* __TI_COMPILER_VERSION__ */
/**
* @brief Macro to export a command along with its name, description, and options to the symbol table in MSVC.
*
* @param[in] name The function name associated with the command.
* @param[in] cmd The command name.
* @param[in] desc The description of the command.
* @param[in] opt The options associated with the command, used for option completion.
*/
#ifdef _MSC_VER
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
FINSH_DESC(cmd, desc) \
FINSH_COND(opt) \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#elif defined(__TI_COMPILER_VERSION__)
#ifdef __TMS320C28XX__
#define RT_NOBLOCKED __attribute__((noblocked))
#else
#define RT_NOBLOCKED
#endif
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
rt_used RT_NOBLOCKED const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
FINSH_DESC(cmd, desc) \
FINSH_COND(opt) \
(syscall_func)&name \
};
#else
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \
const char __fsym_##cmd##_name[] rt_section(".rodata.name") = #cmd; \
const char __fsym_##cmd##_desc[] rt_section(".rodata.name") = #desc; \
rt_used const struct finsh_syscall __fsym_##cmd rt_section("FSymTab")= \
{ \
__fsym_##cmd##_name, \
FINSH_DESC(cmd, desc) \
FINSH_COND(opt) \
(syscall_func)&name \
};
#endif /* _MSC_VER */
#else
#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt)
#endif /* FINSH_USING_SYMTAB */
/**
* @brief Macro definitions to simplify the declaration of exported functions or commands.
*/
#define __MSH_GET_MACRO(_1, _2, _3, _FUN, ...) _FUN
#define __MSH_GET_EXPORT_MACRO(_1, _2, _3, _4, _FUN, ...) _FUN
#define _MSH_FUNCTION_CMD2(a0, a1) \
MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, 0)
#define _MSH_FUNCTION_CMD2_OPT(a0, a1, a2) \
MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, a0##_msh_options)
#define _MSH_FUNCTION_EXPORT_CMD3(a0, a1, a2) \
MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, 0)
#define _MSH_FUNCTION_EXPORT_CMD3_OPT(a0, a1, a2, a3) \
MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, a0##_msh_options)
/**
* @ingroup group_finsh
*
* @brief This macro exports a system function to finsh shell.
*
* @param[in] name Name of function.
* @param[in] desc Description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT(name, desc)
/**
* @ingroup group_finsh
*
* @brief Exports a system function with an alias name to finsh shell.
*
* @param[in] name Name of function.
* @param[in] alias Alias name of function.
* @param[in] desc Description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc)
/**
* @ingroup group_finsh
*
* @brief Exports a command to module shell.
*
* @b Parameters
*
* <tt>[in]</tt> @b command Name of the command.
*
* <tt>[in]</tt> @b desc Description of the command, which will show in help list.
*
* <tt>[in]</tt> @b opt This is an option, enter any content to enable option completion
*
* @note This macro can be used in two ways:
* @code MSH_CMD_EXPORT(command, desc) @endcode
* or
* @code MSH_CMD_EXPORT(command, desc, opt) @endcode
*/
#define MSH_CMD_EXPORT(...) \
__MSH_GET_MACRO(__VA_ARGS__, _MSH_FUNCTION_CMD2_OPT, \
_MSH_FUNCTION_CMD2)(__VA_ARGS__)
/**
* @ingroup group_finsh
*
* @brief Exports a command with alias to module shell.
*
* @b Parameters
*
* <tt>[in]</tt> @b command Name of the command.
*
* <tt>[in]</tt> @b alias Alias of the command.
*
* <tt>[in]</tt> @b desc Description of the command, which will show in help list.
*
* <tt>[in]</tt> @b opt An option, enter any content to enable option completion.
*
* @note This macro can be used in two ways:
* @code #define MSH_CMD_EXPORT_ALIAS(command, alias, desc) @endcode
* or
* @code #define MSH_CMD_EXPORT_ALIAS(command, alias, desc, opt) @endcode
*/
#define MSH_CMD_EXPORT_ALIAS(...) \
__MSH_GET_EXPORT_MACRO(__VA_ARGS__, _MSH_FUNCTION_EXPORT_CMD3_OPT, \
_MSH_FUNCTION_EXPORT_CMD3)(__VA_ARGS__)
/* system call table */
struct finsh_syscall
{
const char *name; /* the name of system call */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char *desc; /* description of system call */
#endif
#ifdef FINSH_USING_OPTION_COMPLETION
struct msh_cmd_opt *opt;
#endif
syscall_func func; /* the function address of system call */
};
/* system call item */
struct finsh_syscall_item
{
struct finsh_syscall_item *next; /* next item */
struct finsh_syscall syscall; /* syscall */
};
#ifdef FINSH_USING_OPTION_COMPLETION
typedef struct msh_cmd_opt
{
rt_uint32_t id;
const char *name;
const char *des;
} msh_cmd_opt_t;
/* Command options declaration and definition macros */
/**
* @brief Declares a static array of command options for a specific command.
*
* @param[in] command The command associated with these options.
*/
#ifdef _MSC_VER
#define CMD_OPTIONS_STATEMENT(command) static struct msh_cmd_opt command##_msh_options[16];
#else
#define CMD_OPTIONS_STATEMENT(command) static struct msh_cmd_opt command##_msh_options[];
#endif
/**
* @brief Starts the definition of command options for a specific command.
*
* @param[in] command The command these options are associated with.
*/
#ifdef _MSC_VER
#define CMD_OPTIONS_NODE_START(command) static struct msh_cmd_opt command##_msh_options[16] = {
#else
#define CMD_OPTIONS_NODE_START(command) static struct msh_cmd_opt command##_msh_options[] = {
#endif
/**
* @brief Defines a single command option.
*
* @param[in] _id Unique identifier for the option.
* @param[in] _name The name of the option.
* @param[in] _des Description of the option.
*/
#define CMD_OPTIONS_NODE(_id, _name, _des) {.id = _id, .name = #_name, .des = #_des},
/**
* Marks the end of command options definition.
*/
#define CMD_OPTIONS_NODE_END {0},};
void msh_opt_list_dump(void *options);
int msh_cmd_opt_id_get(int argc, char *argv[], void *options);
#define MSH_OPT_ID_GET(fun) msh_cmd_opt_id_get(argc, argv, (void*) fun##_msh_options)
#define MSH_OPT_DUMP(fun) msh_opt_list_dump((void*) fun##_msh_options)
#else
#define CMD_OPTIONS_STATEMENT(command)
#define CMD_OPTIONS_NODE_START(command)
#define CMD_OPTIONS_NODE(_id, _name, _des)
#define CMD_OPTIONS_NODE_END
#define MSH_OPT_ID_GET(fun) ((int)(-1UL))
#define MSH_OPT_DUMP(fun) do{}while(0)
#endif
extern struct finsh_syscall_item *global_syscall_list;
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
struct finsh_syscall *finsh_syscall_next(struct finsh_syscall *call);
#define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index)
#else
#define FINSH_NEXT_SYSCALL(index) index++
#endif
#if !defined(RT_USING_POSIX_STDIO) && defined(RT_USING_DEVICE)
void finsh_set_device(const char *device_name);
#endif
#endif
File diff suppressed because it is too large. Load diff
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2013-03-30 Bernard the first verion for FinSH
*/
#ifndef __M_SHELL__
#define __M_SHELL__
#include <rtthread.h>
int msh_exec(char *cmd, rt_size_t length);
void msh_auto_complete(char *prefix);
int msh_exec_module(const char *cmd_line, int size);
int msh_exec_script(const char *cmd_line, int size);
#ifdef FINSH_USING_OPTION_COMPLETION
void msh_opt_auto_complete(char *prefix);
#endif /* FINSH_USING_OPTION_COMPLETION */
#endif
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-05-25 WangQiang the first verion for msh parse
*/
#include <rtthread.h>
#include <ctype.h>
#define forstrloop(str) for (; '\0' != *(str); (str)++)
/**
* This function will check integer.
*
* @param strvalue string
*
* @return true or false
*/
rt_bool_t msh_isint(char *strvalue)
{
if ((RT_NULL == strvalue) || ('\0' == strvalue[0]))
{
return RT_FALSE;
}
if (('+' == *strvalue) || ('-' == *strvalue))
{
strvalue++;
}
forstrloop(strvalue)
{
if (!isdigit((int)(*strvalue)))
{
return RT_FALSE;
}
}
return RT_TRUE;
}
/**
* This function will check hex.
*
* @param strvalue string
*
* @return true or false
*/
rt_bool_t msh_ishex(char *strvalue)
{
int c;
if ((RT_NULL == strvalue) || ('\0' == strvalue[0]))
{
return RT_FALSE;
}
if ('0' != *(strvalue++))
{
return RT_FALSE;
}
if ('x' != *(strvalue++))
{
return RT_FALSE;
}
forstrloop(strvalue)
{
c = tolower(*strvalue);
if (!isxdigit(c))
{
return RT_FALSE;
}
}
return RT_TRUE;
}
/**
* This function will transform for string to hex.
*
* @param strvalue string
*
* @return integer transformed from string
*/
int msh_strtohex(char *strvalue)
{
char c = 0;
int value = 0;
strvalue += 2;
forstrloop(strvalue)
{
value *= 16;
c = tolower(*strvalue);
value += isdigit(c) ? c - '0' : c - 'a' + 10;
}
return value;
}
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-05-25 WangQiang the first verion for msh parse
*/
#ifndef MSH_PARSE_H
#define MSH_PARSE_H
#include <rtdef.h>
rt_bool_t msh_isint(char *strvalue);
rt_bool_t msh_ishex(char *strvalue);
int msh_strtohex(char *strvalue);
#endif /* MSH_PARSE_H */
File diff suppressed because it is too large. Load diff
+110
View File
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-06-02 Bernard Add finsh_get_prompt function declaration
*/
#ifndef __SHELL_H__
#define __SHELL_H__
#include <rtthread.h>
#include "finsh.h"
#ifndef FINSH_THREAD_PRIORITY
#define FINSH_THREAD_PRIORITY 20
#endif
#ifndef FINSH_THREAD_STACK_SIZE
#define FINSH_THREAD_STACK_SIZE 2048
#endif
#ifndef FINSH_CMD_SIZE
#define FINSH_CMD_SIZE 80
#endif
#define FINSH_OPTION_ECHO 0x01
#define FINSH_PROMPT finsh_get_prompt()
const char *finsh_get_prompt(void);
int finsh_set_prompt(const char *prompt);
#ifdef FINSH_USING_HISTORY
#ifndef FINSH_HISTORY_LINES
#define FINSH_HISTORY_LINES 5
#endif
#endif
#ifdef FINSH_USING_AUTH
#ifndef FINSH_PASSWORD_MAX
#define FINSH_PASSWORD_MAX RT_NAME_MAX
#endif
#ifndef FINSH_PASSWORD_MIN
#define FINSH_PASSWORD_MIN 6
#endif
#ifndef FINSH_DEFAULT_PASSWORD
#define FINSH_DEFAULT_PASSWORD "rtthread"
#endif
#endif /* FINSH_USING_AUTH */
#ifndef FINSH_THREAD_NAME
#define FINSH_THREAD_NAME "tshell"
#endif
enum input_stat
{
WAIT_NORMAL,
WAIT_SPEC_KEY,
WAIT_FUNC_KEY,
WAIT_EXT_KEY,
};
struct finsh_shell
{
struct rt_semaphore rx_sem;
enum input_stat stat;
rt_uint8_t echo_mode: 1;
rt_uint8_t prompt_mode: 1;
rt_uint8_t overwrite_mode: 1;
#ifdef FINSH_USING_HISTORY
rt_uint16_t current_history;
rt_uint16_t history_count;
char cmd_history[FINSH_HISTORY_LINES][FINSH_CMD_SIZE];
#endif
char line[FINSH_CMD_SIZE + 1];
rt_uint16_t line_position;
rt_uint16_t line_curpos;
#if !defined(RT_USING_POSIX_STDIO) && defined(RT_USING_DEVICE)
rt_device_t device;
#endif
#ifdef FINSH_USING_AUTH
char password[FINSH_PASSWORD_MAX];
#endif
};
void finsh_set_echo(rt_uint32_t echo);
rt_uint32_t finsh_get_echo(void);
int finsh_system_init(void);
const char *finsh_get_device(void);
int finsh_getchar(void);
rt_uint32_t finsh_get_prompt_mode(void);
void finsh_set_prompt_mode(rt_uint32_t prompt_mode);
#ifdef FINSH_USING_AUTH
rt_err_t finsh_set_password(const char *password);
const char *finsh_get_password(void);
#endif
#ifdef RT_USING_HOOK
void finsh_thread_entry_sethook(void (*hook)(void));
#endif /* RT_USING_HOOK */
#endif