|
From: | Dave Hansen |
Subject: | RE: [avr-gcc-list] Program Space String & optimization |
Date: | Wed, 14 Dec 2005 10:45:36 -0500 |
From: "bolet (sent by Nabble.com)" <address@hidden> [...]
The program works OK without optimization. It doesn't work with optimization (-o1). The code is:...includes... const char P_Txt[] PROGMEM = "Just a test.."; volatile PGM_P txt= P_Txt; int main (void) { ...Init code ... (reg setup & enable int) do{} while( (a=pgm_read_byte(txt)) ); // Wait for null char cli(); //Disable int for (;;); // Do nothing return(0); } SIGNAL (SIG_USART_DATA) { UDR0=pgm_read_byte(txt++); //Send a byte and increment pointer } The 'do while' assembler code generated (with -o1) : +00000041: 91E00100 LDS R30,0x0100 +00000043: 91F00101 LDS R31,0x0101 +00000045: 9184 LPM R24,Z 51: do{} while( (a=pgm_read_byte(txt)) ); // Wait for null char +00000046: 2388 TST R24 +00000047: F7F1 BRNE PC-0x01 Branch if not equal52: cli(); //Disable intAs you can see, the LPM instruction is outside the loop, so this is an infinite loop.-What's wrong with this code?
Seems to be a strange corner case. I'm not sure the compiler is misbehaving, but it might be. There should be a simple fix.
You've declared 'txt' to be volatile, which is good, but you don't show the declaration of 'a'. And I suspect it's not volatile. Since 'a' is not volatile, subsequent writes to the value may be optimized out. But the LPM should always happen because txt is volatile.
In any case, changing the declaration of 'a' to something like unsigned char volatile a;should do it. Removing 'a' entirely should fix it as well, but I'm assuming you're using it for other reasons.
-Which is this the correct way to work with flash data?
You don't seem to be handling flash wrong.
Any suggestion would be greatly appreciated.
HTH, -=Dave
[Prev in Thread] | Current Thread | [Next in Thread] |