Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ rvdb_SOURCES = \
cli.c cli.h data.c data.h \
debug.c debug.h file_io.c file_io.h \
main.c serial.c serial.h types.h \
util.c util.h
util.c util.h pollLib.c pollLib.h
101 changes: 68 additions & 33 deletions src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
#include "debug.h"
#include "types.h"
#include "util.h"
#include "pollLib.h"
#include "serial.h"
#include <pwd.h>
#include <readline/history.h>
#include <readline/readline.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>

// DESCRIPTION: takes the command as a string, and applies it to the serial port
// RETURNS: 0 for success, non-zero for error
Expand Down Expand Up @@ -305,10 +306,33 @@ int parse_cmd(char *line, target_t *tg) {
return EXIT_FAILURE;
}

void receive_otter_input(int serial_port) {
char buffer[MAX_RECEIVE_LEN];

if (read_string(serial_port, buffer) != 0) {
return;
}

printf("OTTER: %s\n", buffer);
}

void readFromStdin(char *buffer) {
int len;

if (fgets(buffer, MAX_INPUT_LEN, stdin) == NULL) {
perror("fgets");
exit(-1);
}

// remove \n
len = strlen(buffer);
buffer[len-1] = '\0';
}

// DESCRIPTION: launches a debugger command line interface (a la GDB)
// on the device at the designated serial port
void debug_cli(char *path, int serial_port) {
char *line;
char line[MAX_INPUT_LEN];
int err = 0;

// create and populate a hash table of variables
Expand Down Expand Up @@ -346,9 +370,14 @@ void debug_cli(char *path, int serial_port) {
tg.bp_cap = MAX_BREAK_PTS;
tg.pipe = 0;

printf("\n" CYAN "UART Debugger\n" RESET);
printf("\n" CYAN "UART Debugger/Receiver\n" RESET);
printf("Enter 'h' for usage details.\n");

// create a pollset to poll stdin and the serial port
setupPollSet();
addToPollSet(STDIN_FILENO);
addToPollSet(serial_port);

// run until EOD is read
while (1) {
// prompt
Expand All @@ -357,39 +386,45 @@ void debug_cli(char *path, int serial_port) {
printf(" (paused)\n");
else
printf("\n");
line = (err) ? readline(RED "$ " RESET) : readline(GREEN "$ " RESET);

if (line[0] == '!') {
err = 0;
system(line + 1);
}
if (err)
printf(RED "$ " RESET);
else
printf(GREEN "$ " RESET);
fflush(stdout); // flush stdout to display the prompt
memset(line, 0, MAX_INPUT_LEN);

// help message
else if (match_strs(line, "h")) {
HELP_MSG;
err = 0;
}
if (pollCall(-1) == STDIN_FILENO) {
// User has entered input
readFromStdin(line);

if (line[0] == '!') {
err = 0;
system(line + 1);
}

// quit/exit
else if (match_strs(line, "q")) {
free(line);
ht_destroy(vars_ht, keys, vc);
return;
} else if (match_strs(line, "exit")) {
free(line);
ht_destroy(vars_ht, keys, vc);
return;
} else if (!line) {
free(line);
ht_destroy(vars_ht, keys, vc);
return;
} else if (*line) {
add_history(line);
err = parse_cmd(line, &tg);
// help message
else if (match_strs(line, "h")) {
HELP_MSG;
err = 0;
}

// quit/exit
else if (match_strs(line, "q")) {
ht_destroy(vars_ht, keys, vc);
return;
} else if (match_strs(line, "exit")) {
ht_destroy(vars_ht, keys, vc);
return;
} else {
err = parse_cmd(line, &tg);
}

} else {
// Otter is talking
receive_otter_input(serial_port);
}

// don't forget to free!
free(line);
line = (char *)NULL;

}
}
4 changes: 4 additions & 0 deletions src/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
#define MAX_BREAK_PTS 8
#define MAX_VAR_COUNT 256

#define MAX_RECEIVE_LEN 1024

#define MAX_INPUT_LEN 1024

#define REL_CONFIG_PATH "/.config/rvdb/config"

#define CTEST_TOKEN "t"
Expand Down
119 changes: 119 additions & 0 deletions src/pollLib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
//
// Written Hugh Smith, Updated: April 2020
// Use at your own risk. Feel free to copy, just leave my name in it.
//

#include <poll.h>
#include <stdlib.h>
#include <stdio.h>

#include "pollLib.h"


// Poll global variables
static struct pollfd * pollFileDescriptors;
static int maxFileDescriptor = 0;
static int currentPollSetSize = 0;

static void growPollSet(int newSetSize);

// Poll functions (setup, add, remove, call)
void setupPollSet()
{
currentPollSetSize = POLL_SET_SIZE;
pollFileDescriptors = (struct pollfd *) calloc(POLL_SET_SIZE, sizeof(struct pollfd));
}


void addToPollSet(int socketNumber)
{

if (socketNumber >= currentPollSetSize)
{
// needs to increase off of the biggest socket number since
// the file desc. may grow with files open or sockets
// so socketNumber could be much bigger than currentPollSetSize
growPollSet(socketNumber + POLL_SET_SIZE);
}

if (socketNumber + 1 >= maxFileDescriptor)
{
maxFileDescriptor = socketNumber + 1;
}

pollFileDescriptors[socketNumber].fd = socketNumber;
pollFileDescriptors[socketNumber].events = POLLIN;
}

void removeFromPollSet(int socketNumber)
{
pollFileDescriptors[socketNumber].fd = 0;
pollFileDescriptors[socketNumber].events = 0;
}

int pollCall(int timeInMilliSeconds)
{
// returns the socket number if one is ready for read
// returns -1 if timeout occurred
// if timeInMilliSeconds == -1 blocks forever (until a socket ready)
// (this -1 is a feature of poll)

int i = 0;
int returnValue = -1;
int pollValue = 0;

if ((pollValue = poll(pollFileDescriptors, maxFileDescriptor, timeInMilliSeconds)) < 0)
{
perror("pollCall");
exit(-1);
}

// check to see if timeout occurred (poll returned 0)
if (pollValue > 0)
{
// see which socket is ready
for (i = 0; i < maxFileDescriptor; i++)
{
//if(pollFileDescriptors[i].revents & (POLLIN|POLLHUP|POLLNVAL))
//Could just check for some revents, but want to catch any of them
//Otherwise, this could mask an error (eat the error condition)
if(pollFileDescriptors[i].revents > 0)
{
//printf("for socket %d poll revents: %d\n", i, pollFileDescriptors[i].revents);
returnValue = i;
break;
}
}

}

// Ready socket # or -1 if timeout/none
return returnValue;
}
static void growPollSet(int newSetSize)
{
int i = 0;

// just check to see if someone screwed up
if (newSetSize <= currentPollSetSize)
{
printf("Error - current poll set size: %d newSetSize is not greater: %d\n",
currentPollSetSize, newSetSize);
exit(-1);
}

printf("Increasing poll set from: %d to %d\n", currentPollSetSize, newSetSize);
pollFileDescriptors = realloc(pollFileDescriptors, newSetSize * sizeof(struct pollfd));

// zero out the new poll set elements
for (i = currentPollSetSize; i < newSetSize; i++)
{
pollFileDescriptors[i].fd = 0;
pollFileDescriptors[i].events = 0;
}

currentPollSetSize = newSetSize;
}



21 changes: 21 additions & 0 deletions src/pollLib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Writen by Hugh Smith, April 2020
//
// Provides an interface to the poll() library. Allows for
// adding a file descriptor to the set, removing one and calling poll.
// Feel free to copy, just leave my name in it, use at your own risk.
//


#ifndef __POLLLIB_H__
#define __POLLLIB_H__

#define POLL_SET_SIZE 10
#define POLL_WAIT_FOREVER -1

void setupPollSet();
void addToPollSet(int socketNumber);
void removeFromPollSet(int socketNumber);
int pollCall(int timeInMilliSeconds);

#endif
35 changes: 35 additions & 0 deletions src/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,23 @@ int send_word(int serial_port, word_t w) {
return 0;
}

// read a byte from thhe device and return 0 if successful
int recv_byte(int serial_port, byte_t *byte) {
ssize_t br;

br = read(serial_port, byte, 1);

if (br == -1) {
perror("read(serial_port)");
exit(-1);
}
if (br == 0) {
fprintf(stderr, "Error: read 0 bytes from serial_port\n");
return 1;
}
return 0;
}

// read a word from the device and return 0 if successful
int recv_word(int serial_port, word_t *word) {
word_t w;
Expand Down Expand Up @@ -162,3 +179,21 @@ int read_word(int serial_port, word_t *word) {
}
return 1;
}

// reads bytes from the serial port until it reaches a null terminator
// this depends on the otter programmer sending a 0 to not get stuck, could be improved to timeout
// returns 0 on success
int read_string(int serial_port, char *data) {
int i;
byte_t byte;
i = 0;

do {
if (recv_byte(serial_port, &byte) != 0) {
return 1;
}
data[i++] = (char)byte;
} while(byte != '\0');

return 0;
}
1 change: 1 addition & 0 deletions src/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ typedef struct termios term_sa;
int open_serial(char *path, int *serial_port);
int send_word(int serial_port, word_t w);
int read_word(int serial_port, word_t *w);
int read_string(int serial_port, char *data);

#endif