Hi,
I'm writing a display library for an 'unusual' (bistable cholesteric) graphics display... and have started to encounter 'weird' behavior (locking up, repeating a serial character over and over, etc.) that is almost certainly a memory corruption issue. Running the attached test sketch & library exactly as shown (the exact behavior is sensitive to physical code placement) on a Duemilanove with 0022 flushes out at least one clear case (note a character in the "String addr:" line is replaced by garbage):
Hello
set font
turn on
reset
clearing
set cursor
print (rom)
S~ring addr:24E
Got byte: HGot byte: eGot byte: lGot byte: lGot byte: oGot byte: ,Got byte: Got byte: wGot byte: oGot byte: rGot byte: lGot byte: dGot byte: !print
print #
write:0Got byte: 0
The most recent additions (before I started noticing effects of the bug) are that the library now subclasses Arduino's print(), the accompanying write() method, and the text generation functions (putch(), puts(), puts_P()), but I can't see any obvious memory-smashing bug in them.
Trying to isolate it by removing code/calls until it 'goes away', or printing out the memory contents / more debug data is unreliable, since even a few-byte change alters the behavior to effectively hide the problem. And I can't find a way to generate a map file or meaningful error messages (-Wall?) while in Arduino-land, it looks like the compiler arguments (and "avr-g++.exe" itself?) are hardcoded in the IDE, and building a sketch of any complexity via e.g. Makefile under win32 is nontrivial. Does anyone know a good way to go about debugging this?
(I'm a bit (er, lot) of a c++ noob... does using Serial's print() from inside a library that subclasses print() pose any problems?)
The most recently added code. See attachment for complete library and sketch testcase...:
[...]
void NVLCD::putch(byte c)
{
Serial.print("Got byte: ");
Serial.print(c);
// only supporting fixed size font for now
//if( font[FONT_LENGTH] == 0 && font[FONT_LENGTH+1] == 0)
{
// FIXME: Precompute all this stuff when initially setting a font
byte width = pgm_read_byte(&font[FONT_FIXED_WIDTH]);
byte height = pgm_read_byte(&font[FONT_HEIGHT]);
byte first_char = pgm_read_byte(&font[FONT_FIRST_CHAR]);
//Serial.print("\nWidth: ");
//Serial.print(width, HEX);
//Serial.print(" Height: ");
//Serial.print(height, HEX);
byte line=0;
byte temp=0;
if(c >= first_char)
{
// resolve ASCII value to character index in font
c = c - first_char;
// index the *byte* in font corresponding to this index
// NB: fonts can be > 8 pixels tall and/or wide.
byte char_width_bytes = width; // 1 byte -> 1 col (8 px vertical)
byte char_height_bytes = (height+7) / 8; // round up
//byte char_total_bytes
// >8 wide -> (char, char+1, ... in font data)
// >8 tall -> multiple lines (char, char+1, ... in font data)
// First byte: c * (char_width_bytes * char_height_bytes)
for(int row=0; row < char_height_bytes; row++)
{
// FIXME: advance cursor column here if multiline fonts...
for(int col=0; col < width; col++)
{
//Serial.print("row=");
//Serial.print(row, DEC);
//Serial.print(" col=");
//Serial.print(col, DEC);
int k = (c * (char_width_bytes * char_height_bytes) + (row * char_height_bytes) + col) + 6;
//Serial.print(" idx=");
//Serial.print(k, DEC);
byte cha = pgm_read_byte(&font[k]);
//Serial.print(" val=");
//Serial.print(cha, HEX);
//Serial.println(" ");
lcd_write(cha);
}
}
}
}
}
void NVLCD::putch_P(PGM_P pc)
{
}
void NVLCD::puts(const char * s)
{
// print a string from RAM
Serial.print("String addr:");
Serial.print((long int)s, HEX);
Serial.println();
set_seg_mapping();
lcd_mode_data();
while(*s != 0)
{
putch(*s);
//*s++;
s++;
}
}
void NVLCD::puts_P(PGM_P s)
{
// print a string from code memory
byte c;
Serial.print("String addr:");
Serial.print((long int)s, HEX);
Serial.println();
set_seg_mapping();
lcd_mode_data();
while((c = pgm_read_byte(s)) != 0)
{
putch(c);
s++;
}
}
// stolen from GLCD
/*
* needed to resolve virtual print functions
*/
void NVLCD::write(uint8_t c) // for Print base class
{
Serial.print(" write:");
Serial.print(c);
putch(c);
}
testcase.zip (10.3 KB)