Hi,
I think I found the calls related to the UART function in simavr.
First is the following piece of code, which fills a buffer of 256 bytes, and sends a log message once said buffer got filled up or the \n character arrives.
if (p->flags & AVR_UART_FLAG_STDIO) {
const int maxsize = 256;
if (!p->stdio_out)
p->stdio_out = malloc(maxsize);
p->stdio_out[p->stdio_len++] = v < ' ' ? '.' : v;
p->stdio_out[p->stdio_len] = 0;
if (v == '\n' || p->stdio_len == maxsize) {
p->stdio_len = 0;
AVR_LOG(avr, LOG_OUTPUT,
FONT_GREEN "%s\n" FONT_DEFAULT, p->stdio_out);
}
}
I tested its behaviour with the following code:
uint16_t count;
void loop() {
Serial.print(count++);
//Serial.write('\n');
delay(10);
}
At first no character gets printed to the console, even in Linux, nonetheless, after some time they come all in one print like this:
0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
If I were to uncomment that line with the Serial.write('\n')
, then once again it works just as before.
Now, what is the AVR_LOG()
function?
After following the references, which wasn’t easy, I got the following:
#define AVR_LOG(avr, level, ...) \
do { \
avr_global_logger(avr, level, __VA_ARGS__); \
} while(0)
So AVR_LOG
is a macro for avr_global_logger
void
avr_global_logger(
struct avr_t* avr,
const int level,
const char * format,
... )
{
va_list args;
va_start(args, format);
if (_avr_global_logger)
_avr_global_logger(avr, level, format, args);
va_end(args);
}
Then avr_global_logger
is a call for _avr_global_logger
static avr_logger_p _avr_global_logger = std_logger;
_avr_global_logger
is an pointer that by default points to std_logger
std_logger(
avr_t * avr,
const int level,
const char * format,
va_list ap)
{
if (!avr || avr->log >= level) {
vfprintf((level > LOG_ERROR) ? stdout : stderr , format, ap);
}
}
std_logger
calls vfprintf
conditionally, finally!!
It looks like the message gets printed to stdout or stderr depending on the log level.
I don’t know how avr-gdb deals with the stdout output from a program or if there are any conditions tho make it work.
What do we know is that the console output only works under the condition that a \n character arrives, so it is usable for text messages but isn’t suitable for arbitrary binary data.
Still, this doesn’t explain why the windows version doesn’t work, yet I also found this comment about the gdb print management,
Not sure if it applies to us, however, it wouldn’t surprise me if it did by seeing how the disassemble bug is still there after all the years