void shell_restore_lastcmd(unsigned char down) { if (down == 1) { if (shell_lastcmd_ptr > 0) { shell_lastcmd_ptr--; } } if (shell_lastcmd[shell_lastcmd_ptr][0] != 0) { int i = 0; unsigned char chars = shell_wptr; // Remove old chars by sending backspaces for (i = 0; i < chars; i++) { shell_process_char(127); } // "Type" last command chars = strlen((char*)shell_lastcmd[shell_lastcmd_ptr]); for (i = 0; i < chars; i++) { shell_process_char(shell_lastcmd[shell_lastcmd_ptr][i]); } //memset(shell_lastcmd[0], 0, sizeof(shell_lastcmd[0])); if (shell_lastcmd_ptr < SHELL_MAX_LASTCOMMANDS - 1 && down == 0) { if (shell_lastcmd[shell_lastcmd_ptr + 1][0] != 0) { shell_lastcmd_ptr++; } } } }
void Shell_Main(void) { shell_flush_buf(); shell_cmd_prompt(); shell_escape_state = 0; while (1) { char c = 0; while (dbgu_char_available()) { // read one byte from serial port c = dbgu_get_char(); shell_process_char(c); } } }
LOCAL void ICACHE_FLASH_ATTR shell_task(void *pvParameters) { os_event_t e; char ch; for (;;) { if (xQueueReceive(xQueueUart, (void *)&e, (portTickType)portMAX_DELAY)) { switch (e.event) { case UART_EVENT_RX_CHAR: ch = (char)e.param; shell_process_char(ch); break; default: break; } } } vTaskDelete(NULL); }
void shell_process_char(char c) { // if the first byte is ' ' or '\n', ignore it if ((0 == shell_wptr) && (' ' == c || '\r' == c)) { shell_cmd_prompt(); return; } // if '\n' is read, execute the command if ('\r' == c) { shell_cmd_execute(); } // if ' ' is read, record the parameter ptr else if (' ' == c) { dbgu_print_char(c); // damping the space if (shell_buf[shell_wptr - 1]) { // replace it with NULL shell_buf[shell_wptr] = 0; shell_wptr++; // record the parameter address int i = 0; for (i = 0; i < SHELL_PARA_CNT_MAX; i++) { if (!shell_para_ptr[i]) { shell_para_ptr[i] = (char*) (&shell_buf[shell_wptr]); break; } } if (SHELL_PARA_CNT_MAX == i) { shell_cmd_execute(); return; } } } else if (127 == c || 8 == c) { // Backspace if (shell_wptr > 0) { dbgu_printf("\b \b"); shell_wptr--; if (shell_buf[shell_wptr] == '\0') { // Delete last parameter int i = 0; for (i = SHELL_PARA_CNT_MAX - 1; i >= 0; --i) { if (shell_para_ptr[i]) { shell_para_ptr[i] = 0; break; } } } shell_buf[shell_wptr] = 0; } } else if (27 == c) { // Escape char shell_escape_state = 1; } else if (0xe0 == (c & 0xFF)) { // Escape char shell_escape_state = 2; } else if (shell_escape_state == 1) { if (c == 91) { shell_escape_state = 2; } else { shell_escape_state = 0; } } else if (shell_escape_state == 2) { shell_escape_state = 0; if (c == 65 || c == 0x48) { // Up key shell_restore_lastcmd(0); } else if (c == 66 || c == 0x50) { // Down key shell_restore_lastcmd(1); } } else if (c == 9) { // Tab if (shell_para_ptr[0] == 0) { // Only allow completion when entering command, not parameters unsigned char i = 0; unsigned char match = 0xFF; unsigned char matchcnt = 0; unsigned char matchlen = 0; while (0 != (shell_cmd_set[i].name)) { if (!strncmp((char*)shell_buf, shell_cmd_set[i].name, shell_wptr)) { matchcnt++; if (matchcnt == 1) { match = i; matchlen = strlen(shell_cmd_set[i].name); } else { // More than one match, so list if (matchcnt == 2) { // Print last match dbgu_printf("\r\n%s ", shell_cmd_set[match].name); } dbgu_printf("%s ", shell_cmd_set[i].name); // Find how many chars are the same if (matchlen > strlen(shell_cmd_set[i].name)) { matchlen = strlen(shell_cmd_set[i].name); } for (unsigned char j = matchlen; j > 0; --j) { if (shell_cmd_set[i].name[j] != shell_cmd_set[match].name[j]) { matchlen = j; } } } } i++; } if (matchcnt == 1) { unsigned char len = strlen(shell_cmd_set[match].name); for (i = shell_wptr; i < len; ++i) { shell_process_char(shell_cmd_set[match].name[i]); } shell_process_char(' '); } else if (matchcnt > 1) { if (matchlen > shell_wptr) { for (i = shell_wptr; i < matchlen; ++i) { shell_buf[shell_wptr] = shell_cmd_set[match].name[i]; shell_wptr++; if (shell_wptr == SHELL_CMD_LENGH_MAX) { shell_cmd_execute(); } } } dbgu_printf("\r\n"); shell_cmd_prompt(); for (i = 0; i < shell_wptr; ++i) { dbgu_print_char(shell_buf[i]); } } } } // other characters, just record it else { dbgu_print_char(c); shell_buf[shell_wptr] = c; shell_wptr++; if (shell_wptr == SHELL_CMD_LENGH_MAX) { shell_cmd_execute(); } } }