Struct PROGMEM arduino 1.6

Arduino Uno with Arduino ide 1.6

Hello,

I try to access of struct object in loop but not work…

please help me =)

#include <avr/pgmspace.h>

typedef struct row_def
{
    int length;
    const unsigned long * tab;  
   
} row;

const unsigned long  e1[] PROGMEM = {111111111L,22222222L};
const unsigned long  e2[] PROGMEM = {333333333UL};

const  row r1 PROGMEM  = {2 , e1 };
const  row r2 PROGMEM  = {1 , e2  };

const  int a PROGMEM  = 5;    

// const row long_table[3] PROGMEM = {r1,r2,r3}; NOT WORK (BAD DATA WHEN READ)!!!!!
const row  * pointeur ;
//*****************************************************************************************//
//                                      Initial Setup
//*****************************************************************************************//
void setup() {
  Serial.begin(9600); 
  const row long_table[2] PROGMEM = {r1,r2}; // GOOD DATA INSIDE
  pointeur = long_table;

  show();  // WORK
}

//*****************************************************************************************//
//                                      MAIN LOOP
//*****************************************************************************************//
void loop() {  
  show(); // NOT WORK
}

void show(){
  Serial.println(a);
  Serial.println(F("1. Accessing Long"));
  for (int i = 0; i < 2;i++) {
   Serial.print(pointeur[i].length); Serial.print("  ");

    for (int j = 0; j < pointeur[i].length;j++) {
      
       unsigned long x = pgm_read_dword(&pointeur[i].tab[j]); 
                                       
       Serial.println( x);            // read a 2-byte integer
    }
  }
}

Solve !!!!

I don't know if it's good idéa but it work perfectly !!!

If it's work in setup() and not in loop() then just use setup() .....

I have add while(1) { // code and read progmem } at end of the setup() function.

If you have a better solution ....

Generally speaking, initializing global variables with the addresses of function-local variables is a very bad idea. Even if those local variables are declared 'static', it's just not a design pattern you'll see a lot of advocacy for. With the exception of 'static' variables, any variables declared within the scope of a function are off-limits as soon as that function's finished executing. How PROGMEM would factor into that is somewhat unclear, but I'd suggest not relying on it. If you have a table that both setup() and loop() need to access, make it global, don't declare it in setup(). You can initialize it in setup(), though.

Also, just be aware that doing things like...

const row long_table[2] PROGMEM = {r1,r2};

...when r1 and r2 are PROGMEM will work fine on small-flash MCUs like the ATmega328p on your Uno, but can cause mysterious behavior on larger MCUs like the ATmega2560 on the Arduino Mega 2560. That's because the compiler only provides for build-time initialization of 16-bit addresses, so if your data is further out than that, the compiler will just silently truncate the addresses to 16 bits and you'll end up reading garbage. The result is that you need to fetch the addresses at runtime using the infinitely goofy pgm_get_far_address() extension.

const row long_table[2] PROGMEM = {r1,r2};

Does not use pointers (and so has no problems with addresses above 64k).

It initializes a new array of structs with two PROGMEM structs, which is at least fishy.

Whandall:

const row long_table[2] PROGMEM = {r1,r2};

Does not use pointers (and so has no problems with addresses above 64k).

It initializes a new array of structs with two PROGMEM structs, which is at least fishy.

Ah! Yes, I certainly misread that.

The compiler is just ignoring PROGMEM on the local array in this case. The data is ending up on the stack. Interestingly, when I paste the code into Arduino 1.81, it “works”, in that when loop() calls show(), the “correct” (1111111,222222,333333,etc.) is printed. The difference here is due to inlining. My 1.81 compiler is inlining setup() and loop() into main(). Consequently, setup()'s stack doesn’t ever get recycled. If I stick attribute((noinline)) on setup() and loop(), however, I observe the same “broken” behavior as the OP did with Arduino 1.6.