A traditional embedded systems trick is to log messages to a circular buffer in core. This has the following benefits:
L_BUFFER *lbuffer; lbuffer = L_buffer_create(32*1024); /* create a 32K buffer */ ...; L_buffer_delete(lbuffer); /* and delete it after use */
L_BUFFER *lb = L_buffer_create(32*1024); L_buffer_wraparound(lb, 0); /* disable wraparound */
L_buffer_printf(lbuffer, "U: user input %c\n", c); L_buffer_puts(lbuffer, "warning: its too hot"); L_buffer_putchar(lbuffer, '*');
Note: a null pointer passed to the `L_buffer_puts' function prints as `(null)'. (7)
Note that this does not change the contents of the buffer. This is important since we may have a hardware or software problem part of the way through the dump operation and you don't want to loose anything.
To reset the buffer after a successful dump use `L_buffer_clear'.
The output of `L_buffer_dump' consists of a starting message followed by the contents of the log. If a character in the log is not printable we print it out in hex on a line by itself.
* L_buffer_dump = log message and another * non-printable character 0x1 more log messages * end of dump
You also need to be able to integrate these functions into your design. See `examples/ott.c' for a complicated example. Here we will provide a simplified version which implements a new logging macro called `LFAST' which does a `printf' to the `log_buffer'. If you want to have all messages going to a `L_BUFFER' then you can redefine `L_DEFAULT_HANDLER'.
/* project.h - the project wide include file */ #include <nana.h> #include <L_buffer.h> /* LFAST(char *, ...) - log a message to the log_buffer */ /* ##f translates as the rest of the arguments to LFAST */ #define LFAST(f...) LHP(L_buffer_printf,log_buffer,##f) extern L_BUFFER *log_buffer; /* the log buffer */
The main program merely creates the log_buffer and eventually calls `L_buffer_dump' to print out the buffer when the system dies.
/* main.c - initialise the system and start things */ #include <project.h> L_BUFFER *log_buffer; main() { log_buffer = L_buffer_create(16000); if(log_buffer == NULL) { /* not enough store */ ... } LFAST("system starting at %f\n", now()); ...; } void fatal_error() { /* called on fatal errors */ FILE *f = fopen("project.errors","w"); L_buffer_dump(b, stderr); /* print log to stderr */ L_buffer_dump(b, f); /* print log to file */ }
Go to the first, previous, next, last section, table of contents.