Go Down

Topic: new AES library (Read 80571 times) previous topic - next topic

casloureiro

Hello,

I have a program where I have several strings. To avoid the use of RAM, I'm using the PROGMEM to have array of strings, and also the F() to store strings on the flash (PGM).

I'm using a arduino mega2560, and I see if changes some strings to the flash, with F(), I start having problems with the encoding and decondig.

I have arrived to the point where I have a program with 83346 bytes (32% of program space). And all is working.

If I change the line:

Code: [Select]
_lcd->print("1) ");

to

_lcd->print(F("1) "));


The program size jumps to 83598 bytes, and the encode and decode doesn't work correctly.
I have made several changes on the code, but always I get a program above the 83346 I get problems on the AES library. All the rest is working.

I see that the library also uses PGM to store values.

My question, is there the possibility that the use of several strings stored on the PGM, could cause problem on the library?

I'm using AES CBC 128bits.

Thanks for any idea that can be shared.

-dev

Quote
Thanks for any idea that can be shared.
It is probably a near vs. far address problem.  Most pointers, like "const char *" or "const __FlashStringHelper *", are 16-bit addresses (i.e., "near" in the first 64K).

For function calls to "far" destinations, the linker is "supposed" to use a "trampoline" to get there, jumping to a "near" address first.  I get the impression that far calls are usually handled correctly.

For "far" data, I can't find anything other than managing it yourself with explicit declarations like uint_farptr_t and xxxx_PF variants, like memcpy_PF.

I don't think FLASH data (e.g., declared via the F macro) is guaranteed to be anywhere in particular.  The sketch code is preferentially loaded in the first 64K, but libraries may extend past that boundary.  I wonder if the code size pushes FLASH data past the 64K address boundary.  Then it is dereferenced incorrectly by code that expectes near pointers (e.g., Print methods).

To force the code to use far pointers for FLASH data, you have to do something like this:

Code: [Select]
const char someFlashData[] PROGMEM = "stringity string.";

void farPrint( const char *farFD )
{
  uint_farptr_t farAddr = pgm_get_far_address( farFD );
 
  do {
    char c = pgm_read_byte_far( farAddr++ );
    if (!c)
      break;
    Serial.write( c );
  }
}

void foo()
{
  farPrint( someFlashData );
}

Untested.   Functions/macros documented here.

If the AES library is using FLASH data, it would have to be modified to always use far pointers.  If it's just your sketch that is using FLASH data, you *should* be able to modify all the F macro uses to do something different.  Initial values may also fall into that category: they are loaded from FLASH into the RAM variable being initialized.

That's about all I can suggest.  Free advice is worth what you paid for it, my $0.02, YMMV, etc., etc.

You've been warned.  ;)
Really, I used to be /dev.  :(

Go Up