You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
2.2 KiB
123 lines
2.2 KiB
/* log.c */ |
|
|
|
#include "types.h" |
|
#include "sdcard.h" |
|
#include "uart.h" |
|
#include "timer.h" |
|
#include "log.h" |
|
#include "config.h" |
|
|
|
/* This is shared with sdcard.c */ |
|
bool log_enabled; |
|
|
|
char log_buffer[LOG_BUFFERSIZE]; |
|
unsigned int log_bufferstart; |
|
unsigned int log_bufferend; |
|
|
|
unsigned int log_generation; |
|
|
|
/* DO NOT call when the buffer is empty */ |
|
/* This should be safe against writes to the buffer, as the writes only |
|
* affect log_bufferend. So no blocking of interrupts is necessary. |
|
*/ |
|
char log_get_byte(void) |
|
{ |
|
char i; |
|
i = log_buffer[log_bufferstart++]; |
|
log_bufferstart = log_bufferstart % LOG_BUFFERSIZE; |
|
|
|
return i; |
|
} |
|
|
|
void log_put_byte(char c) |
|
{ |
|
if (!log_enabled) |
|
return; |
|
|
|
/* If the buffer is full, we just discard data. |
|
* Better than overrunning. |
|
*/ |
|
if (((log_bufferend + 1) % LOG_BUFFERSIZE) == log_bufferstart) { |
|
#if 0 |
|
putstr("^"); |
|
#endif |
|
return; |
|
} |
|
log_buffer[log_bufferend++] = c; |
|
log_bufferend = log_bufferend % LOG_BUFFERSIZE; |
|
#if 0 |
|
putint(c); |
|
putch(' '); |
|
#endif |
|
} |
|
|
|
void log_put_uint16(unsigned int i) |
|
{ |
|
log_put_byte(i & 0xff); |
|
log_put_byte((i >> 8) & 0xff); |
|
} |
|
|
|
void log_put_uint(unsigned int i) |
|
{ |
|
log_put_byte(i & 0xff); |
|
log_put_byte((i >> 8) & 0xff); |
|
log_put_byte((i >> 16) & 0xff); |
|
log_put_byte((i >> 24) & 0xff); |
|
} |
|
|
|
void log_put_header(unsigned int timestamp) |
|
{ |
|
log_put_uint(LOG_MAGIC); |
|
log_put_uint(log_generation); |
|
log_put_uint(timestamp); |
|
log_put_uint(log_read_busytime()); |
|
} |
|
|
|
void log_put_config(void) |
|
{ |
|
log_put_uint(LOG_MAGIC_CONFIG); |
|
log_put_uint(CONFIG_VERSION); |
|
log_put_uint(sizeof(struct config)); |
|
log_put_array((char *)&config, sizeof(struct config)); |
|
} |
|
|
|
void log_put_array(char *data, int length) |
|
{ |
|
int i; |
|
|
|
for (i = 0; i < length; i++) |
|
log_put_byte(data[i]); |
|
} |
|
|
|
void log_put_float(float f) |
|
{ |
|
union { |
|
float f; |
|
unsigned int i; |
|
} data; |
|
data.f = f; |
|
log_put_uint(data.i); |
|
} |
|
|
|
unsigned int log_busystamp; |
|
unsigned int log_busytime; |
|
|
|
void log_mark_busy(void) |
|
{ |
|
unsigned int time = timer_read(); |
|
log_busystamp = time; |
|
} |
|
|
|
void log_mark_idle(void) |
|
{ |
|
unsigned int time = timer_read(); |
|
unsigned int diff = time - log_busystamp; |
|
log_busytime += diff; |
|
} |
|
|
|
unsigned int log_read_busytime(void) |
|
{ |
|
unsigned int time = log_busytime; |
|
log_busytime = 0; |
|
return time; |
|
}
|
|
|