1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2024-11-13 17:30:52 +01:00

Ignore '\0' input in CLI

This commit is contained in:
whowechina 2024-04-27 14:41:19 +08:00
parent 4a2e975580
commit 9f8a3860c1

View File

@ -1,194 +1,197 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <fcntl.h> #include <fcntl.h>
#include <ctype.h> #include <ctype.h>
#include "pico/stdio.h" #include "pico/stdio.h"
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "pico/bootrom.h" #include "pico/bootrom.h"
#include "cli.h" #include "cli.h"
#include "save.h" #include "save.h"
#define MAX_COMMANDS 32 #define MAX_COMMANDS 32
#define MAX_PARAMETERS 6 #define MAX_PARAMETERS 6
#define MAX_PARAMETER_LENGTH 20 #define MAX_PARAMETER_LENGTH 20
const char *cli_prompt = "cli>"; const char *cli_prompt = "cli>";
const char *cli_logo = "CLI"; const char *cli_logo = "CLI";
static const char *commands[MAX_COMMANDS]; static const char *commands[MAX_COMMANDS];
static const char *helps[MAX_COMMANDS]; static const char *helps[MAX_COMMANDS];
static cmd_handler_t handlers[MAX_COMMANDS]; static cmd_handler_t handlers[MAX_COMMANDS];
static int max_cmd_len = 0; static int max_cmd_len = 0;
static int num_commands = 0; static int num_commands = 0;
void cli_register(const char *cmd, cmd_handler_t handler, const char *help) void cli_register(const char *cmd, cmd_handler_t handler, const char *help)
{ {
if (num_commands < MAX_COMMANDS) { if (num_commands < MAX_COMMANDS) {
commands[num_commands] = cmd; commands[num_commands] = cmd;
handlers[num_commands] = handler; handlers[num_commands] = handler;
helps[num_commands] = help; helps[num_commands] = help;
num_commands++; num_commands++;
if (strlen(cmd) > max_cmd_len) { if (strlen(cmd) > max_cmd_len) {
max_cmd_len = strlen(cmd); max_cmd_len = strlen(cmd);
} }
} }
} }
// return -1 if not matched, return -2 if ambiguous // return -1 if not matched, return -2 if ambiguous
int cli_match_prefix(const char *str[], int num, const char *prefix) int cli_match_prefix(const char *str[], int num, const char *prefix)
{ {
int match = -1; int match = -1;
bool found = false; bool found = false;
for (int i = 0; (i < num) && str[i]; i++) { for (int i = 0; (i < num) && str[i]; i++) {
if (strncasecmp(str[i], prefix, strlen(prefix)) == 0) { if (strncasecmp(str[i], prefix, strlen(prefix)) == 0) {
if (found) { if (found) {
return -2; return -2;
} }
found = true; found = true;
match = i; match = i;
} }
} }
return match; return match;
} }
static void handle_help(int argc, char *argv[]) static void handle_help(int argc, char *argv[])
{ {
printf("%s", cli_logo); printf("%s", cli_logo);
printf("\tSN: %016llx\n\n", board_id_64()); printf("\tSN: %016llx\n\n", board_id_64());
printf("Available commands:\n"); printf("Available commands:\n");
for (int i = 0; i < num_commands; i++) { for (int i = 0; i < num_commands; i++) {
printf("%*s: %s\n", max_cmd_len + 2, commands[i], helps[i]); printf("%*s: %s\n", max_cmd_len + 2, commands[i], helps[i]);
} }
} }
static int fps[2]; static int fps[2];
void cli_fps_count(int core) void cli_fps_count(int core)
{ {
static uint32_t last[2] = {0}; static uint32_t last[2] = {0};
static int counter[2] = {0}; static int counter[2] = {0};
counter[core]++; counter[core]++;
uint32_t now = time_us_32(); uint32_t now = time_us_32();
if (now - last[core] < 1000000) { if (now - last[core] < 1000000) {
return; return;
} }
last[core] = now; last[core] = now;
fps[core] = counter[core]; fps[core] = counter[core];
counter[core] = 0; counter[core] = 0;
} }
static void handle_fps(int argc, char *argv[]) static void handle_fps(int argc, char *argv[])
{ {
printf("FPS: core 0: %d, core 1: %d\n", fps[0], fps[1]); printf("FPS: core 0: %d, core 1: %d\n", fps[0], fps[1]);
} }
static void handle_update(int argc, char *argv[]) static void handle_update(int argc, char *argv[])
{ {
printf("Boot into update mode.\n"); printf("Boot into update mode.\n");
fflush(stdout); fflush(stdout);
sleep_ms(100); sleep_ms(100);
reset_usb_boot(0, 2); reset_usb_boot(0, 2);
} }
int cli_extract_non_neg_int(const char *param, int len) int cli_extract_non_neg_int(const char *param, int len)
{ {
if (len == 0) { if (len == 0) {
len = strlen(param); len = strlen(param);
} }
int result = 0; int result = 0;
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (!isdigit((uint8_t)param[i])) { if (!isdigit((uint8_t)param[i])) {
return -1; return -1;
} }
result = result * 10 + param[i] - '0'; result = result * 10 + param[i] - '0';
} }
return result; return result;
} }
static char cmd_buf[256]; static char cmd_buf[256];
static int cmd_len = 0; static int cmd_len = 0;
static void process_cmd() static void process_cmd()
{ {
char *argv[MAX_PARAMETERS]; char *argv[MAX_PARAMETERS];
int argc; int argc;
char *cmd = strtok(cmd_buf, " \n"); char *cmd = strtok(cmd_buf, " \n");
if (strlen(cmd) == 0) { if (strlen(cmd) == 0) {
return; return;
} }
argc = 0; argc = 0;
while ((argc < MAX_PARAMETERS) && while ((argc < MAX_PARAMETERS) &&
(argv[argc] = strtok(NULL, " ,\n")) != NULL) { (argv[argc] = strtok(NULL, " ,\n")) != NULL) {
argc++; argc++;
} }
int match = cli_match_prefix(commands, num_commands, cmd); int match = cli_match_prefix(commands, num_commands, cmd);
if (match == -2) { if (match == -2) {
printf("Ambiguous command.\n"); printf("Ambiguous command.\n");
return; return;
} else if (match == -1) { } else if (match == -1) {
printf("Unknown command.\n"); printf("Unknown command.\n");
handle_help(0, NULL); handle_help(0, NULL);
return; return;
} }
handlers[match](argc, argv); handlers[match](argc, argv);
} }
void cli_run() void cli_run()
{ {
int c = getchar_timeout_us(0); int c = getchar_timeout_us(0);
if (c == EOF) { if (c == EOF) {
return; return;
} }
if (c == 0) {
if (c == '\b' || c == 127) { // both backspace and delete return;
if (cmd_len > 0) { }
cmd_len--;
printf("\b \b"); if (c == '\b' || c == 127) { // both backspace and delete
} if (cmd_len > 0) {
return; cmd_len--;
} printf("\b \b");
}
if ((c != '\n') && (c != '\r')) { return;
}
if (cmd_len < sizeof(cmd_buf) - 2) {
cmd_buf[cmd_len] = c; if ((c != '\n') && (c != '\r')) {
printf("%c", c);
cmd_len++; if (cmd_len < sizeof(cmd_buf) - 2) {
} cmd_buf[cmd_len] = c;
return; printf("%c", c);
} cmd_len++;
}
cmd_buf[cmd_len] = '\0'; return;
cmd_len = 0; }
printf("\n"); cmd_buf[cmd_len] = '\0';
cmd_len = 0;
process_cmd();
printf("\n");
printf(cli_prompt);
} process_cmd();
void cli_init(const char *prompt, const char *logo) printf(cli_prompt);
{ }
if (prompt) {
cli_prompt = prompt; void cli_init(const char *prompt, const char *logo)
} {
if (logo) { if (prompt) {
cli_logo = logo; cli_prompt = prompt;
} }
if (logo) {
cli_register("?", handle_help, "Display this help message."); cli_logo = logo;
cli_register("fps", handle_fps, "Display FPS."); }
cli_register("update", handle_update, "Update firmware.");
} cli_register("?", handle_help, "Display this help message.");
cli_register("fps", handle_fps, "Display FPS.");
cli_register("update", handle_update, "Update firmware.");
}