-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CLI for Controller Board via UART Rx (#278)
* tmp * Validated UART Rx - MCU can receive UART data and echo back to terminal * Command Line Interface for Controller Board via UART Rx * Updated formatting of UART CLI * Formatted and linted UART CLI * Formatted UART smoke file * Fixed issues with UART CLI resulting from lint * Fixed build error for UART CLI * Cleaned up parse functionality * Improved CLI help message * Reorganized private functions and added main file * Improved behaviour when cmd_buffer is filled * Added comments for other members adding peripherals to cli * Added comment for NOLINT and other minor changes * Fixed formatting error
- Loading branch information
Showing
12 changed files
with
474 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"libs": [ | ||
"FreeRTOS", | ||
"ms-common" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#pragma once | ||
#include <stdio.h> | ||
|
||
/* | ||
For new peripherals: | ||
- Create a new C and header file titled "*peripheral*_cli.c" and "*peripheral*_cli.h" | ||
- Peripheral files should include a general help message for the peripheral and a help message for | ||
each function | ||
- Refer to gpio_cli.c for help message formatting | ||
- Create private functions within each peripheral file to process parameters after calling | ||
tok_cmd | ||
- Create a CmdStruct lookup table to store functions for the peripheral - this structure maps | ||
the keyword for an action to the corresponding prv function | ||
- Add a CmdStruct object to cmd_lookup for the peripheral | ||
- Add the necessary init function for the peripheral | ||
*/ | ||
|
||
#include "gpio_cli.h" | ||
|
||
void cli_init(); | ||
void cli_run(); | ||
char *get_cmd(); | ||
void cmd_parse(char *cmd); | ||
void print_help(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#pragma once | ||
|
||
#define MAX_CMD_LEN 50 | ||
|
||
typedef struct CmdStruct { | ||
const char *cmd_name; | ||
void (*cmd_func)(char *input); | ||
} CmdStruct; | ||
|
||
// Separates first token from rest of string | ||
// Token stored in tok_out, remaining string stored in cmd_in | ||
void tok_cmd(char *cmd_in, char *tok_out); | ||
|
||
// Strips whitespace before a string | ||
void strip_ws(char *str); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#pragma once | ||
#include <stdbool.h> | ||
|
||
#include "cli_base.h" | ||
|
||
void gpio_cmd(char *input); | ||
|
||
bool valid_addr(char *port); | ||
bool valid_state(char *state); | ||
int valid_pin_mode(char *pin_mode); | ||
bool state_to_int(char *state); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#include "cli.h" | ||
|
||
#include <stdio.h> | ||
|
||
#include "ctype.h" | ||
#include "interrupt.h" | ||
#include "log.h" | ||
#include "string.h" | ||
#include "tasks.h" | ||
#include "uart.h" | ||
|
||
static const char cli_help[] = | ||
"MSXV Controller Board CLI. Usage: \n\r" | ||
"<peripheral> <action> <parameters> \n\r\n" | ||
"Enter \"help\" after any argument for detailed reference. \n\r\n" | ||
"List of Peripherals: gpio"; | ||
|
||
static char cmd_buffer[MAX_CMD_LEN + 1]; | ||
// Add additional peripherals to lookup array | ||
static const CmdStruct cmd_lookup[] = { { .cmd_name = "gpio", .cmd_func = &gpio_cmd } }; | ||
|
||
void cli_init() { | ||
// Add peripheral init calls here | ||
gpio_init(); | ||
setbuf(stdout, NULL); | ||
printf("\n\rCLI Launched\n\r"); | ||
} | ||
|
||
void cli_run() { | ||
printf("\n\r> "); | ||
char *input = get_cmd(); | ||
if (input != NULL) { | ||
cmd_parse(input); | ||
} | ||
} | ||
|
||
char *get_cmd() { | ||
size_t idx = 0; | ||
memset(cmd_buffer, 0, sizeof(cmd_buffer)); | ||
|
||
while (true) { | ||
size_t len = 1; | ||
uint8_t data = 0; | ||
StatusCode status = STATUS_CODE_EMPTY; | ||
while (status != STATUS_CODE_OK) { | ||
len = 1; | ||
status = uart_rx(UART_PORT_1, &data, &len); | ||
} | ||
|
||
if (idx == MAX_CMD_LEN && (data != '\r' && data != '\b')) { | ||
continue; | ||
} | ||
|
||
if (data == '\r') { | ||
if (idx == 0) { | ||
return NULL; | ||
} | ||
printf("\n\r"); | ||
return cmd_buffer; | ||
} else if (data == '\b') { | ||
if (idx == 0) { | ||
continue; | ||
} | ||
--idx; | ||
cmd_buffer[idx % MAX_CMD_LEN] = 0; | ||
printf("\b \b"); | ||
} else { | ||
cmd_buffer[idx % MAX_CMD_LEN] = data; | ||
++idx; | ||
printf("%c", data); | ||
} | ||
} | ||
} | ||
|
||
void cmd_parse(char *cmd) { | ||
for (size_t i = 0; i < MAX_CMD_LEN; ++i) { | ||
cmd[i] = tolower(cmd[i]); | ||
} | ||
char peripheral[MAX_CMD_LEN + 1] = { 0 }; | ||
tok_cmd(cmd, peripheral); | ||
|
||
if (strcmp(peripheral, "help") == 0 || strcmp(peripheral, "h") == 0) { | ||
print_help(); | ||
return; | ||
} | ||
|
||
for (size_t i = 0; i < SIZEOF_ARRAY(cmd_lookup); ++i) { | ||
if (strcmp(peripheral, cmd_lookup[i].cmd_name) == 0) { | ||
cmd_lookup[i].cmd_func(cmd); | ||
return; | ||
} | ||
} | ||
|
||
// ERROR: Invalid peripheral | ||
printf("Invalid peripheral\n\r"); | ||
print_help(); | ||
} | ||
|
||
void print_help() { | ||
printf("\r%s", cli_help); | ||
for (size_t i = 1; i < SIZEOF_ARRAY(cmd_lookup); ++i) { | ||
printf(", %s", cmd_lookup[i].cmd_name); | ||
} | ||
printf("\n\r"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#include "cli_base.h" | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
void tok_cmd(char *cmd_in, char *tok_out) { | ||
char tmp[MAX_CMD_LEN + 1] = { 0 }; | ||
const char delim[2] = " "; | ||
strip_ws(cmd_in); | ||
strncpy(tmp, cmd_in, sizeof(tmp) - 1); | ||
char *tmp_tok; | ||
// Linter rejects strtok and suggests strtok_r, but compiler gives implicit-function-declaration | ||
// error for strtok_r strtok and strtok_r perform the same functionality but strtok_r is | ||
// thread-safe | ||
tmp_tok = strtok(tmp, delim); // NOLINT | ||
|
||
if (tmp_tok != NULL) { | ||
snprintf(tok_out, MAX_CMD_LEN + 1, "%s", tmp_tok); | ||
snprintf(cmd_in, MAX_CMD_LEN + 1, "%s", cmd_in + strlen(tmp_tok)); | ||
strip_ws(cmd_in); | ||
} else { | ||
tok_out[0] = '\0'; | ||
} | ||
} | ||
|
||
void strip_ws(char *str) { | ||
char *start = str; | ||
while (*start == ' ') { | ||
start++; | ||
} | ||
memmove(str, start, strlen(start) + 1); | ||
} |
Oops, something went wrong.