#include #include #include #include #include "atmel_start.h" #include "command.h" struct cmd_state { const char *prompt; char buf[128]; unsigned int buf_idx; const struct command_fn *cmd[32]; unsigned int cmd_idx; }; static struct cmd_state g_cmds; int command_register(const struct command_fn *cmd) { if (g_cmds.cmd_idx >= ARRAY_SIZE(g_cmds.cmd)) return -1; g_cmds.cmd[g_cmds.cmd_idx++] = cmd; return 0; } DEFUN(help, help_cmd, "help", "Print command reference") { unsigned int i; printf("Help:\r\n"); printf(" Command Help\r\n"); printf(" ---------------- ----\r\n"); for (i = 0; i < g_cmds.cmd_idx; i++) printf(" %-16s %s\r\n", g_cmds.cmd[i]->command, g_cmds.cmd[i]->help); } static void cmd_execute() { char *argv[16]; unsigned int i; int argc = 0; char *cur; printf("\r\n"); memset(argv, 0, sizeof(argv)); for (cur = strtok(g_cmds.buf, " "); cur; cur = strtok(NULL, " ")) { if (argc >= ARRAY_SIZE(argv)) break; argv[argc++] = cur; } for (i = 0; i < g_cmds.cmd_idx; i++) { if (!strcmp(g_cmds.cmd[i]->command, argv[0])) { g_cmds.cmd[i]->fn(argc, argv); return; } } printf("Unknown command: '%s'\r\n", argv[0]); } static void cmd_buf_reset(void) { memset(g_cmds.buf, 0, sizeof(g_cmds.buf)); g_cmds.buf_idx = 0; } static void cmd_buf_append(char c) { g_cmds.buf[g_cmds.buf_idx++] = c; } void command_try_recv(void) { unsigned int i = 0; /* yield CPU after maximum of 10 received characters */ while (usart_sync_is_rx_not_empty(&UART_debug) && (i < 10)) { int c = getchar(); if (c < 0) return; putchar(c); if (c == '\r' || c == '\n' || g_cmds.buf_idx >= sizeof(g_cmds.buf)-1) { cmd_execute(); cmd_buf_reset(); printf(g_cmds.prompt); return; } /* append character */ cmd_buf_append(c); i++; } } void command_init(const char *prompt) { g_cmds.prompt = prompt; command_register(&help_cmd); }