/* * Copyright (c) 2015 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include #include #include LOG_MODULE_REGISTER(app); extern void foo(void); void timer_expired_handler(struct k_timer *timer) { LOG_INF("Timer expired."); /* Call another module to present logging from multiple sources. */ foo(); } K_TIMER_DEFINE(log_timer, timer_expired_handler, NULL); static int cmd_log_test_start(const struct shell *shell, size_t argc, char **argv, uint32_t period) { ARG_UNUSED(argv); k_timer_start(&log_timer, K_MSEC(period), K_MSEC(period)); shell_print(shell, "Log test started\n"); return 0; } static int cmd_log_test_start_demo(const struct shell *shell, size_t argc, char **argv) { return cmd_log_test_start(shell, argc, argv, 200); } static int cmd_log_test_start_flood(const struct shell *shell, size_t argc, char **argv) { return cmd_log_test_start(shell, argc, argv, 10); } static int cmd_log_test_stop(const struct shell *shell, size_t argc, char **argv) { ARG_UNUSED(argc); ARG_UNUSED(argv); k_timer_stop(&log_timer); shell_print(shell, "Log test stopped"); return 0; } SHELL_STATIC_SUBCMD_SET_CREATE(sub_log_test_start, SHELL_CMD_ARG(demo, NULL, "Start log timer which generates log message every 200ms.", cmd_log_test_start_demo, 1, 0), SHELL_CMD_ARG(flood, NULL, "Start log timer which generates log message every 10ms.", cmd_log_test_start_flood, 1, 0), SHELL_SUBCMD_SET_END /* Array terminated. */ ); SHELL_STATIC_SUBCMD_SET_CREATE(sub_log_test, SHELL_CMD_ARG(start, &sub_log_test_start, "Start log test", NULL, 2, 0), SHELL_CMD_ARG(stop, NULL, "Stop log test.", cmd_log_test_stop, 1, 0), SHELL_SUBCMD_SET_END /* Array terminated. */ ); SHELL_CMD_REGISTER(log_test, &sub_log_test, "Log test", NULL); static int cmd_demo_ping(const struct shell *shell, size_t argc, char **argv) { ARG_UNUSED(argc); ARG_UNUSED(argv); shell_print(shell, "pong"); return 0; } #if defined CONFIG_SHELL_GETOPT static int cmd_demo_getopt(const struct shell *shell, size_t argc, char **argv) { struct getopt_state *state; char *cvalue = NULL; int aflag = 0; int bflag = 0; int c; while ((c = shell_getopt(shell, argc, argv, "abhc:")) != -1) { state = shell_getopt_state_get(shell); switch (c) { case 'a': aflag = 1; break; case 'b': bflag = 1; break; case 'c': cvalue = state->optarg; break; case 'h': /* When getopt is active shell is not parsing * command handler to print help message. It must * be done explicitly. */ shell_help(shell); return SHELL_CMD_HELP_PRINTED; case '?': if (state->optopt == 'c') { shell_print(shell, "Option -%c requires an argument.", state->optopt); } else if (isprint(state->optopt)) { shell_print(shell, "Unknown option `-%c'.", state->optopt); } else { shell_print(shell, "Unknown option character `\\x%x'.", state->optopt); } return 1; default: break; } } shell_print(shell, "aflag = %d, bflag = %d", aflag, bflag); return 0; } #endif static int cmd_demo_params(const struct shell *shell, size_t argc, char **argv) { shell_print(shell, "argc = %d", argc); for (size_t cnt = 0; cnt < argc; cnt++) { shell_print(shell, " argv[%d] = %s", cnt, argv[cnt]); } return 0; } static int cmd_demo_hexdump(const struct shell *shell, size_t argc, char **argv) { shell_print(shell, "argc = %d", argc); for (size_t cnt = 0; cnt < argc; cnt++) { shell_print(shell, "argv[%d]", cnt); shell_hexdump(shell, argv[cnt], strlen(argv[cnt])); } return 0; } static int cmd_version(const struct shell *shell, size_t argc, char **argv) { ARG_UNUSED(argc); ARG_UNUSED(argv); shell_print(shell, "Zephyr version %s", KERNEL_VERSION_STRING); return 0; } #define DEFAULT_PASSWORD "zephyr" static void login_init(void) { printk("Shell Login Demo\nHint: password = %s\n", DEFAULT_PASSWORD); if (!CONFIG_SHELL_CMD_ROOT[0]) { shell_set_root_cmd("login"); } } static int check_passwd(char *passwd) { /* example only -- not recommended for production use */ return strcmp(passwd, DEFAULT_PASSWORD); } static int cmd_login(const struct shell *shell, size_t argc, char **argv) { static uint32_t attempts; if (check_passwd(argv[1]) != 0) { shell_error(shell, "Incorrect password!"); attempts++; if (attempts > 3) { k_sleep(K_SECONDS(attempts)); } return -EINVAL; } /* clear history so password not visible there */ z_shell_history_purge(shell->history); shell_obscure_set(shell, false); shell_set_root_cmd(NULL); shell_prompt_change(shell, "uart:~$ "); shell_print(shell, "Shell Login Demo\n"); shell_print(shell, "Hit tab for help.\n"); attempts = 0; return 0; } static int cmd_logout(const struct shell *shell, size_t argc, char **argv) { shell_set_root_cmd("login"); shell_obscure_set(shell, true); shell_prompt_change(shell, "login: "); shell_print(shell, "\n"); return 0; } static int set_bypass(const struct shell *sh, shell_bypass_cb_t bypass) { static bool in_use; if (bypass && in_use) { shell_error(sh, "Sample supports setting bypass on single instance."); return -EBUSY; } in_use = !in_use; if (in_use) { shell_print(sh, "Bypass started, press ctrl-x ctrl-q to escape"); in_use = true; } shell_set_bypass(sh, bypass); return 0; } #define CHAR_1 0x18 #define CHAR_2 0x11 static void bypass_cb(const struct shell *sh, uint8_t *data, size_t len) { static uint8_t tail; bool escape = false; /* Check if escape criteria is met. */ if (tail == CHAR_1 && data[0] == CHAR_2) { escape = true; } else { for (int i = 0; i < (len - 1); i++) { if (data[i] == CHAR_1 && data[i + 1] == CHAR_2) { escape = true; break; } } } if (escape) { shell_print(sh, "Exit bypass"); set_bypass(sh, NULL); tail = 0; return; } /* Store last byte for escape sequence detection */ tail = data[len - 1]; /* Do the data processing. */ for (int i = 0; i < len; i++) { shell_fprintf(sh, SHELL_INFO, "%02x ", data[i]); } shell_fprintf(sh, SHELL_INFO, "| "); for (int i = 0; i < len; i++) { shell_fprintf(sh, SHELL_INFO, "%c", data[i]); } shell_fprintf(sh, SHELL_INFO, "\n"); } static int cmd_bypass(const struct shell *sh, size_t argc, char **argv) { return set_bypass(sh, bypass_cb); } static int cmd_dict(const struct shell *shell, size_t argc, char **argv, void *data) { int val = (intptr_t)data; shell_print(shell, "(syntax, value) : (%s, %d)", argv[0], val); return 0; } SHELL_SUBCMD_DICT_SET_CREATE(sub_dict_cmds, cmd_dict, (value_0, 0), (value_1, 1), (value_2, 2), (value_3, 3) ); SHELL_STATIC_SUBCMD_SET_CREATE(sub_demo, SHELL_CMD(dictionary, &sub_dict_cmds, "Dictionary commands", NULL), SHELL_CMD(hexdump, NULL, "Hexdump params command.", cmd_demo_hexdump), SHELL_CMD(params, NULL, "Print params command.", cmd_demo_params), SHELL_CMD(ping, NULL, "Ping command.", cmd_demo_ping), #if defined CONFIG_SHELL_GETOPT SHELL_CMD(getopt, NULL, "Cammand using getopt, looking for: \"abhc:\".", cmd_demo_getopt), #endif SHELL_SUBCMD_SET_END /* Array terminated. */ ); SHELL_CMD_REGISTER(demo, &sub_demo, "Demo commands", NULL); SHELL_CMD_ARG_REGISTER(version, NULL, "Show kernel version", cmd_version, 1, 0); SHELL_CMD_ARG_REGISTER(bypass, NULL, "Bypass shell", cmd_bypass, 1, 0); SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_START_OBSCURED, login, NULL, "", cmd_login, 2, 0); SHELL_COND_CMD_REGISTER(CONFIG_SHELL_START_OBSCURED, logout, NULL, "Log out.", cmd_logout); void main(void) { if (IS_ENABLED(CONFIG_SHELL_START_OBSCURED)) { login_init(); } #if defined(CONFIG_USB_UART_CONSOLE) const struct device *dev; uint32_t dtr = 0; dev = device_get_binding(CONFIG_UART_SHELL_ON_DEV_NAME); if (dev == NULL || usb_enable(NULL)) { return; } while (!dtr) { uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr); k_sleep(K_MSEC(100)); } #endif }