simio: console can print to file

This is usefull for `tail -f`.
This commit is contained in:
Hose wie Jacke 2018-06-26 10:09:08 +02:00
parent 1cb2e5664b
commit 8ce536556a
1 changed files with 64 additions and 4 deletions

View File

@ -16,6 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -32,6 +33,9 @@ struct console {
address_t base_addr; address_t base_addr;
char buffer[256]; char buffer[256];
unsigned buffer_offset; unsigned buffer_offset;
/* File output */
FILE *file;
}; };
static struct simio_device *console_create(char **arg_text) static struct simio_device *console_create(char **arg_text)
@ -56,6 +60,11 @@ static struct simio_device *console_create(char **arg_text)
static void console_destroy(struct simio_device *dev) static void console_destroy(struct simio_device *dev)
{ {
struct console *c = (struct console *)dev; struct console *c = (struct console *)dev;
if (c->file != NULL) {
fclose(c->file);
}
free(c); free(c);
} }
@ -63,6 +72,10 @@ static void console_reset(struct simio_device *dev)
{ {
struct console *c = (struct console *)dev; struct console *c = (struct console *)dev;
c->buffer_offset = 0; c->buffer_offset = 0;
if (c->file != NULL) {
rewind(c->file);
}
} }
static int config_addr(address_t *addr, char **arg_text) static int config_addr(address_t *addr, char **arg_text)
@ -82,15 +95,40 @@ static int config_addr(address_t *addr, char **arg_text)
return 0; return 0;
} }
static int config_output(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 != stdout)) {
fclose(*file);
}
*file = fopen(path, "w");
if (*file == NULL) {
printc_err("console: can't open %s for writing\n", path);
return -1;
}
return 0;
}
static int console_config(struct simio_device *dev, static int console_config(struct simio_device *dev,
const char *param, char **arg_text) const char *param, char **arg_text)
{ {
struct console *c = (struct console *)dev; struct console *c = (struct console *)dev;
if (!strcasecmp(param, "base")) if (!strcasecmp(param, "base")) {
{
return config_addr(&c->base_addr, arg_text); return config_addr(&c->base_addr, arg_text);
} }
else if (!strcasecmp(param, "output")) {
return config_output(&c->file, arg_text);
}
printc_err("console: config: unknown parameter: %s\n", param); printc_err("console: config: unknown parameter: %s\n", param);
return -1; return -1;
@ -108,7 +146,26 @@ static int console_write_b(struct simio_device *dev,
address_t addr, uint8_t data) address_t addr, uint8_t data)
{ {
struct console *c = (struct console *)dev; struct console *c = (struct console *)dev;
if (addr == c->base_addr)
if (addr != c->base_addr) {
return 1;
}
// write either to file or buffer
if (c->file != NULL)
{
size_t nbytes = sizeof(data);
if (fwrite(&data, nbytes, 1, c->file) != nbytes) {
printc_err("console: write error\n");
return -1;
}
// for tail -f
if (data == '\n') {
fflush(c->file);
}
}
else // buffer
{ {
c->buffer[c->buffer_offset++] = data; c->buffer[c->buffer_offset++] = data;
if (data == '\n' || c->buffer_offset == sizeof c->buffer) if (data == '\n' || c->buffer_offset == sizeof c->buffer)
@ -117,17 +174,20 @@ static int console_write_b(struct simio_device *dev,
c->buffer_offset = 0; c->buffer_offset = 0;
} }
} }
return 1; return 1;
} }
const struct simio_class simio_console = { const struct simio_class simio_console = {
.name = "console", .name = "console",
.help = .help =
"This peripheral prints to stdout every byte written to base address\n" "This peripheral prints to buffer or file every byte written to base address\n"
"\n" "\n"
"Config arguments are:\n" "Config arguments are:\n"
" base <address>\n" " base <address>\n"
" Set the peripheral base address. Defaults to 0x00FF\n" " Set the peripheral base address. Defaults to 0x00FF\n"
" output <path>\n"
" Print to file instead of a buffer.\n"
"\n", "\n",
.create = console_create, .create = console_create,