35#ifdef RT_USING_POSIX_STDIO
37#include <posix/stdio.h>
49#ifdef FINSH_USING_SYMTAB
55static char *finsh_prompt_custom =
RT_NULL;
57#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
61 ptr = (
unsigned int *)(call + 1);
73 if (finsh_prompt_custom)
82 finsh_prompt_custom = (
char *)
rt_malloc(strlen(prompt) + 1);
83 if (finsh_prompt_custom)
85 strcpy(finsh_prompt_custom, prompt);
93#define _MSH_PROMPT "msh "
97 static char finsh_prompt[RT_CONSOLEBUF_SIZE + 1] = {0};
100 if (!
shell->prompt_mode)
102 finsh_prompt[0] =
'\0';
106 if (finsh_prompt_custom)
108 strncpy(finsh_prompt, finsh_prompt_custom,
sizeof(finsh_prompt) - 1);
115#if defined(DFS_USING_POSIX) && defined(DFS_USING_WORKDIR)
117 getcwd(&finsh_prompt[rt_strlen(finsh_prompt)], RT_CONSOLEBUF_SIZE - rt_strlen(finsh_prompt));
120 if (rt_strlen(finsh_prompt) + 2 < RT_CONSOLEBUF_SIZE)
122 finsh_prompt[rt_strlen(finsh_prompt)] =
'>';
123 finsh_prompt[rt_strlen(finsh_prompt) + 1] =
'\0';
139 return shell->prompt_mode;
154 shell->prompt_mode = prompt_mode;
159#ifdef RT_USING_DEVICE
161#ifdef RT_USING_POSIX_STDIO
162 if(
read(rt_posix_stdio_get_console(), &ch, 1) > 0)
175 device =
shell->device;
184 if (
shell->device != device)
186 device =
shell->device;
196 extern char rt_hw_console_getchar(
void);
197 return rt_hw_console_getchar();
201#if !defined(RT_USING_POSIX_STDIO) && defined(RT_USING_DEVICE)
227 rt_kprintf(
"finsh: can not find device: %s\n", device_name);
232 if (dev ==
shell->device)
return;
245 rt_memset(
shell->line, 0,
sizeof(
shell->line));
246 shell->line_curpos =
shell->line_position = 0;
263 return shell->device->parent.name;
293 return shell->echo_mode;
296#ifdef FINSH_USING_AUTH
305rt_err_t finsh_set_password(
const char *password)
310 if (pw_len < FINSH_PASSWORD_MIN || pw_len > FINSH_PASSWORD_MAX)
314 rt_strncpy(
shell->password, password, FINSH_PASSWORD_MAX);
325const char *finsh_get_password(
void)
327 return shell->password;
330static void finsh_wait_auth(
void)
334 char password[FINSH_PASSWORD_MAX] = { 0 };
337 if (rt_strlen(finsh_get_password()) == 0)
return;
342 while (!input_finish)
353 if (ch >=
' ' && ch <=
'~' && cur_pos < FINSH_PASSWORD_MAX)
357 password[cur_pos++] = ch;
359 else if (ch ==
'\b' && cur_pos > 0)
363 password[cur_pos] =
'\0';
366 else if (ch ==
'\r' || ch ==
'\n')
374 if (!rt_strncmp(
shell->password, password, FINSH_PASSWORD_MAX))
return;
382 rt_memset(password,
'\0', FINSH_PASSWORD_MAX);
388static void shell_auto_complete(
char *prefix)
393#ifdef FINSH_USING_OPTION_COMPLETION
394 msh_opt_auto_complete(prefix);
400#ifdef FINSH_USING_HISTORY
407 for (i = 0; i <= 60; i++)
420 if (
shell->line_position != 0)
423 if (
shell->history_count >= FINSH_HISTORY_LINES)
430 for (index = 0; index < FINSH_HISTORY_LINES - 1; index ++)
432 rt_memcpy(&
shell->cmd_history[index][0],
436 rt_memcpy(&
shell->cmd_history[index][0],
shell->line,
shell->line_position);
439 shell->history_count = FINSH_HISTORY_LINES;
447 shell->current_history =
shell->history_count;
452 shell->history_count ++;
456 shell->current_history =
shell->history_count;
461static void (*_finsh_thread_entry_hook)(void);
472 _finsh_thread_entry_hook = hook;
476static void finsh_thread_entry(
void *parameter)
483#ifndef FINSH_ECHO_DISABLE_DEFAULT
484 shell->echo_mode = 1;
486 shell->echo_mode = 0;
489#if !defined(RT_USING_POSIX_STDIO) && defined(RT_USING_DEVICE)
501#ifdef FINSH_USING_AUTH
503 if (rt_strlen(finsh_get_password()) == 0)
505 if (finsh_set_password(FINSH_DEFAULT_PASSWORD) != RT_EOK)
552#ifdef FINSH_USING_HISTORY
554 if (
shell->current_history > 0)
555 shell->current_history --;
558 shell->current_history = 0;
566 shell_handle_history(
shell);
572#ifdef FINSH_USING_HISTORY
574 if (
shell->current_history <
shell->history_count - 1)
575 shell->current_history ++;
579 if (
shell->history_count != 0)
580 shell->current_history =
shell->history_count - 1;
588 shell_handle_history(
shell);
594 if (
shell->line_curpos)
597 shell->line_curpos --;
604 if (
shell->line_curpos <
shell->line_position)
607 shell->line_curpos ++;
615 if (ch ==
'\0' || ch == 0xFF)
continue;
621 for (i = 0; i <
shell->line_curpos; i++)
625 shell_auto_complete(&
shell->line[0]);
632 else if (ch == 0x7f || ch == 0x08)
635 if (
shell->line_curpos == 0)
638 shell->line_position--;
639 shell->line_curpos--;
641 if (
shell->line_position >
shell->line_curpos)
653 for (i =
shell->line_curpos; i <= shell->line_position; i++)
666 if (ch ==
'\r' || ch ==
'\n')
668#ifdef FINSH_USING_HISTORY
669 shell_push_history(
shell);
671 if (
shell->echo_mode)
676 rt_memset(
shell->line, 0,
sizeof(
shell->line));
677 shell->line_curpos =
shell->line_position = 0;
683 shell->line_position = 0;
686 if (
shell->line_curpos <
shell->line_position)
690 rt_memmove(&
shell->line[
shell->line_curpos + 1],
694 if (
shell->echo_mode)
698 for (i =
shell->line_curpos; i < shell->line_position; i++)
704 if (
shell->echo_mode)
709 shell->line_position ++;
710 shell->line_curpos++;
714 shell->line_position = 0;
715 shell->line_curpos = 0;
720static void finsh_system_function_init(
const void *begin,
const void *end)
726#if defined(__ICCARM__) || defined(__ICCRX__)
727#ifdef FINSH_USING_SYMTAB
728 #pragma section="FSymTab"
730#elif defined(__ADSPBLACKFIN__)
731#ifdef FINSH_USING_SYMTAB
732 extern "asm" int __fsymtab_start;
733 extern "asm" int __fsymtab_end;
735#elif defined(_MSC_VER)
736#pragma section("FSymTab$a", read)
737const char __fsym_begin_name[] =
"__start";
738const char __fsym_begin_desc[] =
"begin of finsh";
739__declspec(allocate(
"FSymTab$a")) const struct
finsh_syscall __fsym_begin =
746#pragma section("FSymTab$z", read)
747const char __fsym_end_name[] =
"__end";
748const char __fsym_end_desc[] =
"end of finsh";
749__declspec(allocate(
"FSymTab$z")) const struct
finsh_syscall __fsym_end =
767#ifdef FINSH_USING_SYMTAB
768#ifdef __ARMCC_VERSION
769 extern const int FSymTab$$Base;
770 extern const int FSymTab$$Limit;
771 finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);
772#elif defined (__ICCARM__) || defined(__ICCRX__)
773 finsh_system_function_init(__section_begin(
"FSymTab"),
774 __section_end(
"FSymTab"));
775#elif defined (__GNUC__) || defined(__TI_COMPILER_VERSION__) || defined(__TASKING__)
777 extern const int __fsymtab_start;
778 extern const int __fsymtab_end;
779 finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
780#elif defined(__ADSPBLACKFIN__)
781 finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
782#elif defined(_MSC_VER)
783 unsigned int *ptr_begin, *ptr_end;
791 ptr_begin = (
unsigned int *)&__fsym_begin;
792 ptr_begin += (
sizeof(
struct finsh_syscall) / sizeof(unsigned int));
793 while (*ptr_begin == 0) ptr_begin ++;
795 ptr_end = (
unsigned int *) &__fsym_end;
797 while (*ptr_end == 0) ptr_end --;
799 finsh_system_function_init(ptr_begin, ptr_end);
820 &finsh_thread_stack[0],
sizeof(finsh_thread_stack),
827 if (tid != NULL && result == RT_EOK)
struct finsh_syscall * _syscall_table_end
struct finsh_syscall * _syscall_table_begin
rt_err_t rt_device_set_rx_indicate(rt_device_t dev, rt_err_t(*rx_ind)(rt_device_t dev, rt_size_t size))
#define RT_DEVICE_FLAG_INT_RX
#define RT_DEVICE_FLAG_STREAM
rt_ssize_t rt_device_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
rt_device_t rt_device_find(const char *name)
struct rt_device * rt_device_t
rt_err_t rt_device_close(rt_device_t dev)
rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflag)
#define RT_DEVICE_OFLAG_RDWR
ssize_t read(int fd, void *buf, size_t len)
char * getcwd(char *buf, size_t size)
#define RT_WAITING_FOREVER
#define RT_OBJECT_HOOK_CALL(func, argv)
rt_weak void * rt_calloc(rt_size_t count, rt_size_t size)
This function will contiguously allocate enough space for count objects that are size bytes of memory...
rt_weak void rt_free(void *ptr)
This function will release the previously allocated memory block by rt_malloc. The released memory bl...
rt_weak void * rt_malloc(rt_size_t size)
Allocate a block of memory with a minimum of 'size' bytes.
rt_err_t rt_thread_startup(rt_thread_t thread)
This function will start a thread and put it to system ready queue.
rt_err_t rt_thread_delay(rt_tick_t tick)
This function will let current thread delay for some ticks.
rt_thread_t rt_thread_create(const char *name, void(*entry)(void *parameter), void *parameter, rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick)
This function will create a thread object and allocate thread object memory. and stack.
rt_err_t rt_thread_init(struct rt_thread *thread, const char *name, void(*entry)(void *parameter), void *parameter, void *stack_start, rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick)
This function will initialize a thread. It's used to initialize a static thread object.
struct rt_thread * rt_thread_t
void finsh_set_device(const char *device_name)
void finsh_thread_entry_sethook(void(*hook)(void))
This function set a hook function at the entry of finsh thread
rt_uint32_t finsh_get_echo()
rt_uint32_t finsh_get_prompt_mode(void)
void finsh_set_prompt_mode(rt_uint32_t prompt_mode)
void finsh_set_echo(rt_uint32_t echo)
const char * finsh_get_device()
rt_err_t rt_sem_init(rt_sem_t sem, const char *name, rt_uint32_t value, rt_uint8_t flag)
This function will initialize a static semaphore object.
rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time)
rt_err_t rt_sem_release(rt_sem_t sem)
This function will release a semaphore. If there is thread suspended on the semaphore,...
rt_align(RT_ALIGN_SIZE)
This function sets a hook function to idle thread loop. When the system performs idle loop,...
int msh_exec(char *cmd, rt_size_t length)
void msh_auto_complete(char *prefix)
#define INIT_APP_EXPORT(fn)
void rt_hw_interrupt_enable(rt_base_t level)
rt_base_t rt_hw_interrupt_disable(void)
unsigned short rt_uint16_t
int finsh_system_init(void)
const char * finsh_get_prompt(void)
int finsh_set_prompt(const char *prompt)
struct finsh_shell * shell
#define FINSH_THREAD_NAME
#define FINSH_THREAD_PRIORITY
#define FINSH_THREAD_STACK_SIZE