Pages: 1 2 [3]   Go Down
Author Topic: Help create maxSize sketch  (Read 1326 times)
0 Members and 1 Guest are viewing this topic.
Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17294
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think AVR arrays are limited to 32k bytes in size, at least in the compiler version Arduino uses.


That seems to be a accurate speculation as I had to create four arrays as the compiler complained about just using one when the arraysize variable I used got too big. So I guess if I have want to load up a mega2560 board (which I don't presently own) I would have to uses 8 arrays?

Lefty

Code:
long myInts0[arraysize] PROGMEM = {};  //Store initilized array into flash memory
long myInts1[arraysize] PROGMEM = {};
long myInts2[arraysize] PROGMEM = {};
long myInts3[arraysize] PROGMEM = {};
Logged

Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 799
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So I would like a general purpose sketch that can fill the flash memory on a sketch to near maximum size just to test reliablity of uploading large sketches. So I though maybe just a modified blink sketch with just a array defined with different sizes for the various AVR chips, see code comments below. I know the exact size has to take into consideration the size of the bootloader so it doesn't have to be exactly full size minus bootloader size, just use numbers that allow for a maximum size bootloader perhaps?

Try the attached program. It's a 32.1K PROGMEM array of text strings that print to the serial port. To test larger boards, just add more lines.

This is what the program looks like (not showing ALL the lines of course):

Code:
// crazy test of full program memory

void setup(void)
{

        Serial.begin(115200);

        const char *testData[324] = {
                PSTR("This is line 0000 in a text string living in program memory AKA PROGMEM.\r\n"),
                PSTR("This is line 0001 in a text string living in program memory AKA PROGMEM.\r\n"),
                PSTR("This is line 0002 in a text string living in program memory AKA PROGMEM.\r\n"),
---------- snip! ----------
                PSTR("This is line 0321 in a text string living in program memory AKA PROGMEM.\r\n"),
                PSTR("This is line 0322 in a text string living in program memory AKA PROGMEM.\r\n"),
                PSTR("This is line 0323 in a text string living in program memory AKA PROGMEM.\r\n")
        };

        char buffer[128];
        uint16_t x;
        for (x = 0; x < 324; x++) {
                sprintf_P(buffer, testData[x]);
                Serial.print(buffer);
        }
}

void loop(void) { ; }

* test.zip (1.28 KB - downloaded 2 times.)
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12928
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Not sure if this will even work ( didn't upload ), but this fills every single byte free on the mega

It also exposes a strange compiler or linker bug.  Try this...

Code:
#define nothing

template< uint64_t C, typename T >
  struct LargeStruct{
    T Data;
    LargeStruct< C - 1, T > Next;
};
template< typename T > struct LargeStruct< 0, T >{ };

typedef LargeStruct< 80, uint64_t > Container; //640 bytes

PROGMEM LargeStruct< 50, Container > l_Struct;  //32k
PROGMEM LargeStruct< 50, Container > l_Struct1;   //32k
PROGMEM LargeStruct< 50, Container > l_Struct2;   //32k
PROGMEM LargeStruct< 50, Container > l_Struct3;   //32k
PROGMEM LargeStruct< 50, Container > l_Struct4;   //32k
PROGMEM LargeStruct< 50, Container > l_Struct5;  //32k
PROGMEM LargeStruct< 50, Container > l_Struct6;   //32k
PROGMEM LargeStruct< 50, Container > l_Struct7;   //32k

PROGMEM LargeStruct< 431, uint16_t > l_Struct8; //862 bytes
void setup()
  {
    volatile int i = ( int ) &l_Struct;

/*
**********************************************************************
    volatile int i1 = ( int ) &l_Struct1;
    volatile int i2 = ( int ) &l_Struct2;
    volatile int i3 = ( int ) &l_Struct3;
    volatile int i4 = ( int ) &l_Struct4;
    volatile int i5 = ( int ) &l_Struct5;
    volatile int i6 = ( int ) &l_Struct6;
    volatile int i7 = ( int ) &l_Struct7;    
    volatile int i8 = ( int ) &l_Struct8;  
**********************************************************************
*/
  }

void loop(){}
Logged

Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 799
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Not sure if this will even work ( didn't upload ), but this fills every single byte free on the mega

It also exposes a strange compiler or linker bug.  Try this...

Code:
#define nothing

template< uint64_t C, typename T >
  struct LargeStruct{
    T Data;
    LargeStruct< C - 1, T > Next;
};
template< typename T > struct LargeStruct< 0, T >{ };

typedef LargeStruct< 80, uint64_t > Container; //640 bytes

PROGMEM LargeStruct< 50, Container > l_Struct;  //32k
PROGMEM LargeStruct< 50, Container > l_Struct1;   //32k
PROGMEM LargeStruct< 50, Container > l_Struct2;   //32k
PROGMEM LargeStruct< 50, Container > l_Struct3;   //32k
PROGMEM LargeStruct< 50, Container > l_Struct4;   //32k
PROGMEM LargeStruct< 50, Container > l_Struct5;  //32k
PROGMEM LargeStruct< 50, Container > l_Struct6;   //32k
PROGMEM LargeStruct< 50, Container > l_Struct7;   //32k

PROGMEM LargeStruct< 431, uint16_t > l_Struct8; //862 bytes
void setup()
  {
    volatile int i = ( int ) &l_Struct;

/*
**********************************************************************
    volatile int i1 = ( int ) &l_Struct1;
    volatile int i2 = ( int ) &l_Struct2;
    volatile int i3 = ( int ) &l_Struct3;
    volatile int i4 = ( int ) &l_Struct4;
    volatile int i5 = ( int ) &l_Struct5;
    volatile int i6 = ( int ) &l_Struct6;
    volatile int i7 = ( int ) &l_Struct7;    
    volatile int i8 = ( int ) &l_Struct8;  
**********************************************************************
*/
  }

void loop(){}

/usr/share/arduino-1.0.3/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../avr/bin/ld: region text is full (test.cpp.elf section .text)

That's the error I get with the above code (compiled for the UNO and MEGA2560 both do the same thing).
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12928
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

/usr/share/arduino-1.0.3/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../avr/bin/ld: region text is full (test.cpp.elf section .text)

That's the error I get with the above code (compiled for the UNO and MEGA2560 both do the same thing).

(That's a different problem)

Have you tried compiling the original?
Logged

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 70
Posts: 2171
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I use 1.5.1r2 and I'm pretty sure its GCC is 4.3.2.

I do not get errors, but yeah, the unused PROGMEM data is not removed. The missing bytes seem accounted for with 8x 16-bit pointers, and 6-bytes for each volatile load copy and save.

I'm not sure weather this is a bug ( or what you are pointing out ) as the flash read functions should be able to do arbitrary reading. And I guess not holding onto a pointer saves ram. Maybe there is a way using sections to place progmem data where you want.
Logged


Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12928
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


The unreferenced PROGMEM data should be removed because the compiler / linker were instructed to remove unreferenced data; an optimization bug.  Certainly not worth reporting.  It's just a strange thing I notice.
Logged

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 70
Posts: 2171
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I had a few Ideas for progmem, which won't work if the compiler removed unreferenced progmem data. So I did a bit of reading and it appears this isn't a bug and is actually set by the command line options.

 -ffunction-sections and -fdata-sections, tell the compiler to place all function metadata in one location of the object file and, data into another.

PROGMEM on a variable tells the compiler to put the data into a completely separate section appropriately named progmem.

Next the linker receives a flag --gc-sections which allows dead code removal, but only from the function and data sections. All other sections will be linked 'as is'.
Logged


Pages: 1 2 [3]   Go Up
Jump to: