Skip to content

Commit

Permalink
Working on printf implementation. Appears to require memory allocatio…
Browse files Browse the repository at this point in the history
…n for va_args
  • Loading branch information
danieldegrasse committed Aug 9, 2020
1 parent 413c520 commit d145c5a
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 28 deletions.
63 changes: 41 additions & 22 deletions cli.c
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
/**
* @file cli.c
* Implements console command handling for the SD logger program.
* Interface-specific handling should be done in another file, this file
* abstracts it.
* Implements a generic console that can read command strings. Command
* strings are not handled in this file.
* Interface-specific (UART, SPI, etc...) handling should be done in
* another file, this file abstracts it.
*
* This code assumes that the connected terminal emulates a VT-100.
*/

#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

#include "cli.h"
#include "commands.h"

#define CLI_EMPTY_LINELEN -1 // Signifies an "unused" history buffer.
#define CLI_PROMPT "-> "

// Static functions to handle sub cases for the CLI.
// functions to handle sub cases for the CLI.
static void cli_handle_return(CLIContext *context);
static void cli_handle_esc(CLIContext *context);
static void cli_handle_backspace(CLIContext *context);
Expand All @@ -29,13 +33,30 @@ static void move_line_index(CLIContext *context, bool forwards);
void cli_context_init(CLIContext *context) {
int i;
context->cursor = NULL;
context->current_line = 0;
context->line_idx = 0;
for (i = 0; i < CLI_BUFCNT; i++) {
// Set the line length
context->lines[i].len = CLI_EMPTY_LINELEN;
}
}

/**
* CLI Printf function. Same syntax as printf.
* @param context CLI context to print to
* @param format printf style format string
*/
void cli_printf(CLIContext *context, const char *format, ...) {
va_list args;
int num_print;
char output_buf[PRINT_BUFLEN];
// Init variable args list.
va_start(args, format);
// Print to buffer and destroy varargs list.
num_print = vsnprintf(output_buf, PRINT_BUFLEN, format, args);
va_end(args);
context->cli_write(output_buf, num_print);
}

/**
* Runs the embedded CLI for this program. The provided context exposes read
* and write functions for a communication interface.
Expand All @@ -51,7 +72,7 @@ void start_cli(CLIContext *context) {
while (1) {
// Print prompt.
context->cli_write(CLI_PROMPT, sizeof(CLI_PROMPT) - 1);
current_line = &(context->lines[context->current_line]);
current_line = &(context->lines[context->line_idx]);
// Initialize cursor location to start of buffer.
context->cursor = current_line->line_buf;
// Zero length of buffer.
Expand All @@ -62,7 +83,7 @@ void start_cli(CLIContext *context) {
* we actually use.
*/
move_line_index(context, true);
context->lines[context->current_line].len = CLI_EMPTY_LINELEN;
context->lines[context->line_idx].len = CLI_EMPTY_LINELEN;
// Revert change to current line idx.
move_line_index(context, false);
// Read data until a LF is found.
Expand Down Expand Up @@ -110,7 +131,7 @@ void start_cli(CLIContext *context) {
* @param context: CLI context to use for this command.
*/
static void cli_handle_return(CLIContext *context) {
CLI_Line *current_line = &context->lines[context->current_line];
CLI_Line *current_line = &context->lines[context->line_idx];
// Write a newline and carriage return to the console.
context->cli_write("\r\n", 2);
// Null terminate the command.
Expand All @@ -125,10 +146,8 @@ static void cli_handle_return(CLIContext *context) {
return;
}
move_line_index(context, true);
// TODO: handle command.
context->cli_write("Got Data:", 9);
context->cli_write(current_line->line_buf, current_line->len);
context->cli_write("\r\n", 2);
// handle command.
handle_command(context, current_line->line_buf);
}

/**
Expand All @@ -139,7 +158,7 @@ static void cli_handle_return(CLIContext *context) {
* @param context: CLI context to use
*/
static void cli_handle_backspace(CLIContext *context) {
CLI_Line *current_line = &context->lines[context->current_line];
CLI_Line *current_line = &context->lines[context->line_idx];
/*
* Backspace: send backspace and space to clear
* character. Edit the value in the command buffer as well.
Expand Down Expand Up @@ -167,7 +186,7 @@ static void cli_handle_backspace(CLIContext *context) {
* @param context: Context escape character recieved on.
*/
static void cli_handle_esc(CLIContext *context) {
CLI_Line *current_line = &context->lines[context->current_line];
CLI_Line *current_line = &context->lines[context->line_idx];
char esc_buf[2];
/**
* Escape sequence. Read more characters from the
Expand All @@ -193,9 +212,9 @@ static void cli_handle_esc(CLIContext *context) {
* to the prior command.
*/
move_line_index(context, false);
if (context->lines[context->current_line].len != CLI_EMPTY_LINELEN) {
if (context->lines[context->line_idx].len != CLI_EMPTY_LINELEN) {
// Update the line buffer and current line.
current_line = &(context->lines[context->current_line]);
current_line = &(context->lines[context->line_idx]);
// Set cursor to end of line buffer.
context->cursor = &current_line->line_buf[current_line->len];
// Clear line of console and write line from history.
Expand All @@ -215,9 +234,9 @@ static void cli_handle_esc(CLIContext *context) {
* to the next command.
*/
move_line_index(context, true);
if (context->lines[context->current_line].len != CLI_EMPTY_LINELEN) {
if (context->lines[context->line_idx].len != CLI_EMPTY_LINELEN) {
// Update the line buffer, cursor, and current line.
current_line = &(context->lines[context->current_line]);
current_line = &(context->lines[context->line_idx]);
// Set cursor to end of line buffer.
context->cursor = &current_line->line_buf[current_line->len];
// Clear line of console and write line from history.
Expand Down Expand Up @@ -266,14 +285,14 @@ static void move_line_index(CLIContext *context, bool forwards) {
* forwards or back we are moving the index, and our modulo is constant.
*/
if (forwards) {
new_idx = context->current_line + 1;
new_idx = context->line_idx + 1;
if (new_idx == CLI_BUFCNT)
new_idx = 0;
context->current_line = new_idx;
context->line_idx = new_idx;
} else {
new_idx = context->current_line - 1;
new_idx = context->line_idx - 1;
if (new_idx < 0)
new_idx = CLI_BUFCNT - 1;
context->current_line = new_idx;
context->line_idx = new_idx;
}
}
22 changes: 17 additions & 5 deletions cli.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
/**
* @file cli.h
* Implements console command handling for the SD logger program.
* Interface-specific handling should be done in another file, this file
* abstracts it.
* Implements a generic console that can read command strings. Command
* strings are not handled in this file.
* Interface-specific (UART, SPI, etc...) handling should be done in
* another file, this file abstracts it.
*
* This code assumes that the connected terminal emulates a VT-100.
*/

#ifndef CLI_H
#define CLI_H

/** CLI configuration parameters */
#define CLI_MAX_LINE 80 // max command length
#define CLI_HISTORY 3 // max number of past commands to store
#define CLI_HISTORY 3 // max number of past commands to store
#define PRINT_BUFLEN 80 // size of printf buffer to use.

#define CLI_BUFCNT CLI_HISTORY + 2 // Used internally for CLI buffer length

Expand All @@ -30,9 +35,16 @@ typedef struct {
/*! line buffers */
CLI_Line lines[CLI_BUFCNT];
/*! Index of current line buffer */
int current_line;
int line_idx;
} CLIContext;

/**
* CLI Printf function. Same syntax as printf.
* @param context CLI context to print to
* @param format printf style format string
*/
void cli_printf(CLIContext *context, const char *format, ...);

/**
* Initializes memory for a CLI context.
* @param context: CLI context to init.
Expand Down
74 changes: 74 additions & 0 deletions commands.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* @file commands.c
* Implements CLI command handlers.
*/
#include "cli.h"

typedef struct {
char *cmd_name;
int (*cmd_fxn)(CLIContext *, char**, int);
char *cmd_help;
} CmdEntry;

#include <string.h>

/*
* Maximum number of arguments that the parser will handle.
* Includes command name.
*/
#define MAX_ARGV 8


static int help(CLIContext *cxt, char **argv, int argc);

/**
* Declaration of commands. Syntax is as follows:
* {"NAME_OF_COMMAND", command_function, "HELP_STRING"}
* The command function follows the signature of "main", but with a
* Context Parameter, ex:
* int command_function(CLIContext *ctx, char** argv, int argc)
* A return value of zero indicates success, anything else indicates failure.
*/

const CmdEntry COMMANDS[] = {
{"help", help, "Prints help for this commandline"},
// Add more entries here.
{NULL, NULL, NULL}
};



/**
* Handles a command, as given by the null terminated string "cmd"
* @param ctx: CLI context to print to.
* @param cmd: command string to handle.
* @return 0 on successful handling, or another value on failure.
*/
int handle_command(CLIContext *ctx, char *cmd) {
char *arguments[MAX_ARGV];
// The parser interprets a space as a delimeter between arguments.
(void)arguments;
ctx->cli_write("This will work\r\n", 16);
cli_printf(ctx, "Hello there");
return 0;
}


/**
* Help function. Prints avaliable commandline targets.
* @param argv: list of all string arguments given (first will be "help")
* @param argc: length of the argv array.
*/
static int help(CLIContext *ctx, char **argv, int argc) {
CmdEntry *entry;
if (argc == 1) {
cli_printf(ctx, "Test\n");
entry = (CmdEntry*)&COMMANDS[0];
while (entry->cmd_name != NULL) {
// Write command name and newline
cli_printf(ctx, "%s\n", entry->cmd_name);
entry++;
}
}
return 0;
}
17 changes: 17 additions & 0 deletions commands.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @file commands.h
* Implements CLI command handlers.
*/

#ifndef COMMANDS_H
#define COMMANDS_H

/**
* Handles a command, as given by the null terminated string "cmd"
* @param ctx: CLI context to print to.
* @param cmd: command string to handle.
* @return 0 on successful handling, or another value on failure.
*/
int handle_command(CLIContext *ctx, char *cmd);

#endif
2 changes: 1 addition & 1 deletion makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
###### CHANGE LOCATION TO YOUR CODEGEN TOOLS INSTALL DIR. UNIX PATH (no backslashes) #######
CODEGEN_INSTALL_DIR = /home/danieldegrasse/Downloads/gcc-arm-none-eabi-4_7-2012q4
CODEGEN_INSTALL_DIR = /usr

CC = "$(CODEGEN_INSTALL_DIR)/bin/arm-none-eabi-gcc"
LNK = "$(CODEGEN_INSTALL_DIR)/bin/arm-none-eabi-gcc"
Expand Down

0 comments on commit d145c5a

Please sign in to comment.