Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable serial input on simulated console devices #129

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 70 additions & 0 deletions simio/simio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ struct console {

/* File output */
FILE *file;

/* File input */
FILE *infile;
};

static struct simio_device *console_create(char **arg_text)
Expand Down Expand Up @@ -65,6 +68,10 @@ static void console_destroy(struct simio_device *dev)
fclose(c->file);
}

if (c->infile != NULL) {
fclose(c->infile);
}

free(c);
}

Expand All @@ -76,6 +83,10 @@ static void console_reset(struct simio_device *dev)
if (c->file != NULL) {
rewind(c->file);
}

if (c->infile != NULL) {
rewind(c->infile);
}
}

static int config_addr(address_t *addr, char **arg_text)
Expand Down Expand Up @@ -118,6 +129,29 @@ static int config_output(FILE **file, char **arg_text)
return 0;
}

static int config_input(FILE **file, char **arg_text)
{
char *path = get_arg(arg_text);

if (path == NULL) {
printc_err("console: config: expected path\n");
return -1;
}

// don't leak the descriptor if configured multiple times
if ((*file != NULL) && (*file != stdin)) {
fclose(*file);
}

*file = fopen(path, "r");
if (*file == NULL) {
printc_err("console: can't open %s for reading\n", path);
return -1;
}

return 0;
}

static int console_config(struct simio_device *dev,
const char *param, char **arg_text)
{
Expand All @@ -129,6 +163,9 @@ static int console_config(struct simio_device *dev,
else if (!strcasecmp(param, "output")) {
return config_output(&c->file, arg_text);
}
else if (!strcasecmp(param, "input")) {
return config_input(&c->infile, arg_text);
}

printc_err("console: config: unknown parameter: %s\n", param);
return -1;
Expand Down Expand Up @@ -177,6 +214,36 @@ static int console_write_b(struct simio_device *dev,

return 1;
}
static int console_read_b(struct simio_device *dev,
address_t addr, uint8_t *datap)
{
struct console *c = (struct console *)dev;

if (addr != c->base_addr) {
return 1;
}

// read either from file or buffer
if (c->infile != NULL)
{
size_t nbytes = sizeof(*datap);
if (fread(datap, nbytes, 1, c->infile) != nbytes) {
printc_err("console: read error\n");
return -1;
}
// printc_err("got %c\n", *datap);
}
else // buffer
{
*datap = c->buffer[c->buffer_offset++];
if (*datap == '\n' || c->buffer_offset == sizeof c->buffer)
{
c->buffer_offset = 0;
}
}

return 1;
}

const struct simio_class simio_console = {
.name = "console",
Expand All @@ -188,6 +255,8 @@ const struct simio_class simio_console = {
" Set the peripheral base address. Defaults to 0x00FF\n"
" output <path>\n"
" Print to file instead of a buffer.\n"
" input <path>\n"
" Read from file instead of a buffer.\n"
"\n",

.create = console_create,
Expand All @@ -196,4 +265,5 @@ const struct simio_class simio_console = {
.config = console_config,
.info = console_info,
.write_b = console_write_b,
.read_b = console_read_b,
};