[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-libc-dev] Strange behaviour of program-space
From: |
E. Weddington |
Subject: |
Re: [avr-libc-dev] Strange behaviour of program-space |
Date: |
Sat, 19 Feb 2005 17:05:08 -0700 |
User-agent: |
Mozilla Thunderbird 0.7.3 (Windows/20040803) |
Florian Bantner wrote:
Hi List,
I don't know if this is the right list to ask this question, but the
other one (avr-chat) doesn't seem right either. Whatever...
Really, the avr-gcc-list would be best. You can find it here:
<http://savannah.nongnu.org/mail/?group=avr>
My question is this: I'm trying out (as a first step) the example in
the FAQ for putting strings in program-space. My program looks like
this and doesn't work. It just outputs garbage:
-- snip: does not work ----------
#include "avr/pgmspace.h"
const char string1[] PROGMEM = "Test eins";
const char string2[] PROGMEM = "Test zwei";
PGM_P array[2] PROGMEM = { string1, string2 };
The above is all correct.
void delay();
int main(){
uint8_t i;
PGM_P c;
lcdInit();
for( ever ){
lcdPut( '\n' );
for( i=0; i<2; i++ ){
for( c = array[ i ]; pgm_read_byte_near( c ) != '\0';
c++ ){
lcdPut( (char) pgm_read_byte_near( c ) );
}
}
delay();
}
}
Several things here:
- Don't forget that you've put the *array* itself into the Program
Space. So to get the beginning address of the string, you'll have to
read the array from Program Space.
- You generally don't have to expressly use the *_near() macros. Unless
you're using a mega128, using the pgm_read_byte() will work as the _near
version of the macro.
- The easiest way to think about, is express the access of the object
that is stored in program space as you normally would, then take the
address of it (if it's not already an address), and pass it to the
pgm_read_*() macros to read it from program memory.
- Try not to read the same value from program memory more than once, it
will be terribly inefficient in the code.
- Remember that pgm_read*() are MACROS, so be careful about potential
side effects, i.e. try not to do auto-increments of the parameter variable.
for(i = 0; i < 2; i++)
{
// Get the beginning address of the string from the array in Program
Space.
// string will contain the adress of the string store in Program
Space.
string = pgm_read_word(&(array[i]));
do
{
// Read the byte at address stored in string.
byte = pgm_read_byte(string);
if(byte != 0)
{
lcdPut(byte);
}
// Increment the Program Space address.
string++;
} while(byte); // Check for end of string.
}
Note that the above example has not been tested. Let me know if this
works for you.
Eric