diff --git a/errors/errno.fugu b/errors/errno.fugu index fcf10dc..005c0ad 100755 --- a/errors/errno.fugu +++ b/errors/errno.fugu @@ -1433,3 +1433,8 @@ errors sdhc SDHCD_ERR_ { failure BULK_FRAME_SET "Bulk frame already set", failure BULK_FRAME_NOT_SET "Bulk frame not set", }; + +errors shelly SHELLY_ERR_ { + failure BUFFER_OVERFLOW "Buffer limits reached", + failure WRITE "String write failed", +}; \ No newline at end of file diff --git a/usr/shelly/shelly.c b/usr/shelly/shelly.c index 78da716..0c738dd 100644 --- a/usr/shelly/shelly.c +++ b/usr/shelly/shelly.c @@ -24,6 +24,35 @@ static struct shelly_st_global * global_state; #include "shelly_cmd.c" +//prints a null terminated string +errval_t shelly_write_str(char * str) { + errval_t err; + for (size_t i = 0; str[i] != '\0'; ++i) { + err = lpuart_putchar(global_state->uart_s, str[i]); + if (err_is_fail(err)) return err_push(err, SHELLY_ERR_WRITE); + } + err = lpuart_putchar(global_state->uart_s, '\0'); + if (err_is_fail(err)) return err_push(err, SHELLY_ERR_WRITE); + return SYS_ERR_OK; +} + +void shelly_reset_buffer(void) { + global_state->buffer_i = 0; + global_state->buf[0] = '\0'; +} + +errval_t shelly_buffer_append(char c) { + global_state->buf[global_state->buffer_i] = c; + global_state->buffer_i += 1; + + if (global_state->buffer_i == SHELLY_BUF_SIZE) { + shelly_reset_buffer(); + return SHELLY_ERR_BUFFER_OVERFLOW; + } + + return SYS_ERR_OK; +} + __attribute__((__used__)) static void handle_lpuart_interrupt(void * arg) { errval_t err; @@ -31,32 +60,38 @@ static void handle_lpuart_interrupt(void * arg) { assert(global_state); char input_char; - err = lpuart_getchar(global_state->uart_s, &input_char); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to get character"); + while (true) { + err = lpuart_getchar(global_state->uart_s, &input_char); + if (err == LPUART_ERR_NO_DATA) { + break; + } else if (err_is_fail(err)) { + USER_PANIC_ERR(err, "while trying to get character"); + } - err = lpuart_putchar(global_state->uart_s, input_char); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - - if (input_char == ASCII_NL || input_char == ASCII_EOF || input_char == ASCII_CR) { - err = lpuart_putchar(global_state->uart_s, '\n'); + err = lpuart_putchar(global_state->uart_s, input_char); if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - global_state->buf[global_state->buffer_i] = '\0'; - global_state->buffer_i += 1; + if (input_char == ASCII_NL || input_char == ASCII_EOF || input_char == ASCII_CR) { + err = lpuart_putchar(global_state->uart_s, '\n'); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - err = handle_shelly_cmd(global_state->buf, global_state->buffer_i); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while running command"); + global_state->buf[global_state->buffer_i] = '\0'; + global_state->buffer_i += 1; - global_state->buffer_i = 0; + err = handle_shelly_cmd(global_state->buf, global_state->buffer_i); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while running command"); - err = lpuart_putchar(global_state->uart_s, ASCII_EOT); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - err = lpuart_putchar(global_state->uart_s, '>'); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - } else { - global_state->buf[global_state->buffer_i] = input_char; - global_state->buffer_i += 1; - global_state->buffer_i %= SHELLY_BUF_SIZE; + shelly_reset_buffer(); + + err = shelly_write_str("\x3>"); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write string"); + } else { + err = shelly_buffer_append(input_char); + if (err_is_fail(err)) { + err = shelly_write_str("shelly buffer full! resetting...\n"); + if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to write string"); + } + } } SHELLY_DEBUG("[handle_lpuart_interrupt] done\n"); } diff --git a/usr/shelly/shelly.h b/usr/shelly/shelly.h index 039b823..6f3a40f 100644 --- a/usr/shelly/shelly.h +++ b/usr/shelly/shelly.h @@ -50,4 +50,8 @@ struct shelly_st_local { struct ump_send_chan * send_chan; }; +errval_t shelly_write_str(char * str); +void shelly_reset_buffer(void); +errval_t shelly_buffer_append(char c); + #endif // ndef SHELLY_H_ diff --git a/usr/shelly/shelly_cmd.c b/usr/shelly/shelly_cmd.c index d2cc1e6..593f995 100644 --- a/usr/shelly/shelly_cmd.c +++ b/usr/shelly/shelly_cmd.c @@ -15,14 +15,8 @@ static void parse_cmd_line(char * line, int * argc, char ** argv) { static errval_t shelly_cmd_echo(char * line) { errval_t err; SHELLY_DEBUG("[shelly_cmd_echo] argc=%d\n", argc); - - for (int i = 0; line[i] != '\0'; ++i) { - err = lpuart_putchar(global_state->uart_s, line[i]); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - } - err = lpuart_putchar(global_state->uart_s, '\0'); - if (err_is_fail(err)) USER_PANIC_ERR(err, "while trying to put character"); - + err = shelly_write_str(line); + if (err_is_fail(err)) return err; return SYS_ERR_OK; } @@ -74,7 +68,9 @@ static errval_t handle_shelly_cmd(char* line, size_t len) { } else if (strcmp(cmd, "run") == 0) { return shelly_cmd_run(remaining_line); } else { - SHELLY_DEBUG("unknown command %s\n", argv[0]); + char buf[256]; + snprintf(buf, 256, "unknown command %s\n", cmd); + shelly_write_str(buf); } return SYS_ERR_OK;