Skip to content

Commit

Permalink
Added basic CLI. command history still not implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
danieldegrasse committed Aug 6, 2020
1 parent 7aeccc6 commit 2d81255
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 78 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.obj
*.map
sd_logger
.vscode
113 changes: 113 additions & 0 deletions cli.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* @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.
*/

#include <string.h>

#include "cli.h"

/**
* Initializes memory for a CLI context.
* @param context: CLI context to init.
* @param read_fxn: read function.
* @param write_fxn: write function.
*/
void cli_context_init(CLIContext *context, int (*read_fxn)(char *, int),
int (*write_fxn)(char *, int)) {
context->cursor = NULL;
memset(context->line_buffer, 0, CLI_MAX_LINE);
context->cli_read = read_fxn;
context->cli_write = write_fxn;
}

/**
* Runs the embedded CLI for this program. The provided context exposes read
* and write functions for a communication interface.
* @param context: CLI context for I/O.
*/
void start_cli(CLIContext *context) {
char input, esc_buf[2], *line_buf;
char prompt[] = "-> ";
/*
* CLI loop, reads a line of data then handles it according to
* avaliable targets.
*/
while (1) {
// Print prompt.
context->cli_write(prompt, sizeof(prompt));
// Initialize cursor location to start of buffer.
context->cursor = line_buf = context->line_buffer;
// Zero out line buffer.
memset(line_buf, 0, CLI_MAX_LINE);
// Read data until a LF is found.
do {
context->cli_read(&input, 1);
switch (input) {
case '\r': // CR, or enter on most consoles.
context->cli_write("\r\n", 2);
// TODO: handle command.
context->cli_write("Got Data:", 9);
context->cli_write(line_buf, strlen(line_buf));
context->cli_write("\r\n", 2);
break;
case '\b':
/**
* Backspace: send backspace and space to clear
* character. Edit the value in the command buffer as well.
*/
if (context->cursor != line_buf) {
context->cli_write("\b\x20\b", 3);
// Move cursor back, and clear the character there.
context->cursor--;
*(context->cursor) = '\0';
}
break;
case '\x1b':
/**
* Escape sequence. Read more characters from the
* input to see if we can handle it.
*/
context->cli_read(esc_buf, 2);
if (esc_buf[0] != '[') {
// Not an escape sequence we understand, ignore it.
break;
}
/*
* If the escape sequence starts with '\x33]',
* switch on next char.
*/
switch (esc_buf[1]) {
case 'C': // Right arrow
if (*(context->cursor) != '\0') {
// Move cursor and print the forward control seq.
(context->cursor)++;
context->cli_write(&input, 1);
context->cli_write(esc_buf, 2);
}
break;
case 'D': // Left arrow
if (context->cursor != line_buf) {
// Move cursor and print the backward control seq.
(context->cursor)--;
context->cli_write(&input, 1);
context->cli_write(esc_buf, 2);
}
default:
// Ignore other escape sequences.
break;
}
break;
default:
// Simply echo character, and set in buffer
context->cli_write(&input, 1);
*(context->cursor) = input;
// Move to next location in buffer
(context->cursor)++;
break;
}
} while (input != '\r' && context->cursor - line_buf < CLI_MAX_LINE);
}
}
40 changes: 40 additions & 0 deletions cli.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* @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.
*/
#ifndef CLI_H
#define CLI_H

/** CLI configuration parameters */
#define CLI_MAX_LINE 80

typedef struct {
/*! read bytes into the buffer. Returns the number of bytes read. */
int (*cli_read)(char *, int);
/*! write data for output on the CLI. Returns number of bytes written. */
int (*cli_write)(char *, int);
/*! current pointer location */
char *cursor;
/*! line buffer */
char line_buffer[CLI_MAX_LINE];
} CLIContext;

/**
* Initializes memory for a CLI context.
* @param context: CLI context to init.
* @param read_fxn: read function.
* @param write_fxn: write function.
*/
void cli_context_init(CLIContext *context, int (*read_fxn)(char *, int),
int (*write_fxn)(char *, int));

/**
* Runs the embedded CLI for this program. The provided context exposes read
* and write functions for a communication interface.
* @param context: CLI context for I/O.
*/
void start_cli(CLIContext *context);

#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 = /usr
CODEGEN_INSTALL_DIR = /home/danieldegrasse/Downloads/gcc-arm-none-eabi-4_7-2012q4

CC = "$(CODEGEN_INSTALL_DIR)/bin/arm-none-eabi-gcc"
LNK = "$(CODEGEN_INSTALL_DIR)/bin/arm-none-eabi-gcc"
Expand Down
15 changes: 2 additions & 13 deletions sd_logger.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@
/* Board Header file */
#include "Board.h"

#define TASKSTACKSIZE 512

Task_Struct task0Struct;
Char task0Stack[TASKSTACKSIZE];
#include "uart_console.h"

/*
* ======== heartBeatFxn ========
Expand All @@ -41,7 +38,6 @@ Void heartBeatFxn(UArg arg0, UArg arg1)
*/
int main(void)
{
Task_Params taskParams;

/* Call board init functions */
Board_initGeneral();
Expand All @@ -53,14 +49,7 @@ int main(void)
// Board_initUSB(Board_USBDEVICE);
// Board_initWatchdog();
// Board_initWiFi();

/* Construct heartBeat Task thread */
Task_Params_init(&taskParams);
taskParams.arg0 = 1000;
taskParams.stackSize = TASKSTACKSIZE;
taskParams.stack = &task0Stack;
Task_construct(&task0Struct, (Task_FuncPtr)heartBeatFxn, &taskParams, NULL);

uart_prebios();
/* Turn on user LED */
GPIO_write(Board_LED0, Board_LED_ON);

Expand Down
60 changes: 9 additions & 51 deletions sd_logger.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,6 @@ BIOS.runtimeCreatesEnabled = true;
*/
//BIOS.logsEnabled = true;
BIOS.logsEnabled = false;



/* ================ Memory configuration ================ */
var Memory = xdc.useModule('xdc.runtime.Memory');
/*
* The Memory module itself simply provides a common interface for any
* variety of system and application specific memory management policies
Expand All @@ -296,7 +291,7 @@ if (!Program.build.target.$name.match(/iar/)) {
* Reducing the system stack size (used by ISRs and Swis) to reduce
* RAM usage.
*/
Program.stack = 768;
Program.stack = 512;
}


Expand All @@ -307,37 +302,6 @@ if (!Program.build.target.$name.match(/iar/)) {
if (Program.build.target.$name.match(/gnu/)) {
var SemiHost = xdc.useModule('ti.sysbios.rts.gnu.SemiHostSupport');
}
/* ================ Semaphore configuration ================ */
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
/*
* Enables global support for Task priority pend queuing.
*
* Pick one:
* - true (default)
* This allows pending tasks to be serviced based on their task priority.
* - false
* Pending tasks are services based on first in, first out basis.
*
* When using BIOS in ROM:
* This option must be set to false.
*/
//Semaphore.supportsPriority = true;
Semaphore.supportsPriority = false;

/*
* Allows for the implicit posting of events through the semaphore,
* disable for additional code saving.
*
* Pick one:
* - true
* This allows the Semaphore module to post semaphores and events
* simultaneously.
* - false (default)
* Events must be explicitly posted to unblock tasks.
*
*/
//Semaphore.supportsEvents = true;
Semaphore.supportsEvents = false;



Expand Down Expand Up @@ -483,19 +447,6 @@ Task.idleTaskStackSize = 512;
Task.numPriorities = 16;


/* ================ Task creation ================ */
/*
* Create all statically allocated tasks in this project.
*/
var Task = xdc.useModule('ti.sysbios.knl.Task');
/*
* Add all required tasks for this program.
*/
var uartTaskParams = new Task.Params();
uartTaskParams.stackSize = 512;
uartTaskParams.instance.name = "uartTask";
Program.global.uart_task = Task.create('&uartTaskEntry', uartTaskParams);


/* ================ Text configuration ================ */
var Text = xdc.useModule('xdc.runtime.Text');
Expand Down Expand Up @@ -549,4 +500,11 @@ driversConfig.libType = driversConfig.LibType_NonInstrumented;
/* ================ Application Specific Instances ================ */
/* ================ Task creation ================ */
var task0Params = new Task.Params();
task0Params.instance.name = "heartbeat";
task0Params.arg0 = 1000;
Program.global.heartbeat = Task.create("&heartBeatFxn", task0Params);
var task1Params = new Task.Params();
task1Params.instance.name = "uartconsole";
Program.global.uartconsole = Task.create("&uart_task_entry", task1Params);
55 changes: 42 additions & 13 deletions uart_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@
/* Board-specific functions */
#include "Board.h"

#include "cli.h"

// UART configuration.
#define BAUD_RATE 115200
#define UART_DEV Board_UART0

UART_Handle uart;
UART_Params params;
static UART_Handle uart;
static UART_Params params;

static int uart_read(char* in, int n);
static int uart_write(char* out, int n);

/*
* PreOS Task for UART console. Sets up uart instance for data transmission,
Expand All @@ -34,21 +39,24 @@ UART_Params params;
*/
void uart_prebios(void)
{
Board_initGPIO();
Board_initUART();
System_printf("Setup UART Device\n");
System_flush();
/*
* UART defaults to text mode, echo back characters, and return from read
* after newline. Default 8 bits, one stop bit, no parity.
*/
UART_Params_init(&params);
params.baudRate = BAUD_RATE;
params.readReturnMode = UART_RETURN_FULL;
// Do not do text manipulation on the data. CLI will handle this.
params.readDataMode = UART_DATA_BINARY;
params.writeDataMode = UART_DATA_BINARY;
// Block reads until newline received.
params.readReturnMode = UART_RETURN_NEWLINE;
// Echo all read characters back
params.readEcho = UART_ECHO_ON;
params.baudRate = BAUD_RATE;
params.readEcho = UART_ECHO_OFF;
uart = UART_open(UART_DEV, &params);
if (uart == NULL) {
System_abort("Error opening the UART device");
}
System_printf("Setup UART Device\n");
System_flush();
}


Expand All @@ -58,9 +66,30 @@ void uart_prebios(void)
* @param arg0 unused
* @param arg1 unused
*/
void uartTaskEntry(UArg arg0, UArg arg1)
void uart_task_entry(UArg arg0, UArg arg1)
{
System_printf("UART task starting\n");
System_flush();
CLIContext uart_context;
cli_context_init(&uart_context, uart_read, uart_write);
start_cli(&uart_context); // Does not return.
}


/**
* Write data to the UART device.
* @param out buffer of data to write to UART device
* @param n length of out in bytes.
* @return number of byte written to UART.
*/
static int uart_write(char* out, int n) {
return UART_write(uart, out, n);
}

/**
* Read data from the UART device.
* @param in buffer to read data into. Must be "n" bytes or larger.
* @param n number of bytes to read.
* @return number of bytes read.
*/
static int uart_read(char* in, int n) {
return UART_read(uart, in, n);
}
14 changes: 14 additions & 0 deletions uart_console.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* @file uart_console.h
* Exposes UART prebios function, and any other required functions from the
* UART Console task
*/

/*
* PreOS Task for UART console. Sets up uart instance for data transmission,
* and creates UART console task.
* UART device on linux will be ttyACM0.
* This code MUST be called before the BIOS is started.
*/
void uart_prebios(void);

0 comments on commit 2d81255

Please sign in to comment.