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);
		}
	}
}
Example #3
0
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();
		}
	}
}