What is stored when I use keyword PROGMEM

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I've some trouble understanding the concept of PROGMEM.

So when I declare a constant array with the key PROGMEM, the data is not stored in the RAM but in the Flash memory.

Then I need to access the data e.g. 

(int16_t)pgm_read_word( &array[i])

How does this really work. 

I tought that using PROGMEM, in the RAM memory only pointers to the elements in the array are stored. But then the "&" doens't make sense, because array[i] then already would be an pointer.

So is it just that simple that I can call array[i] during runtime and get the adress of it? But if so, why I can't just use array[i] and access the data directly?

 

Thanks for helping!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The key concept here is harvard architecture. Code space (flash) and data space (ram) are separate. Different instructions are used to access the different areas. PROGMEM puts the data in flash, but you need to use the pgm_read functions to get the data from flash.
Note: newer versions of gcc implement __flash attribute which removes the need for pgm_read and progmem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PROGMEM is just a macro that resolves to __attribute__((__progmem__)) which in turn works similar like attribute section(". progmem.data") would, but with some extra checks. As opposed to named address spaces like __flash, attributes do not affect pointer targets, hence the access cannot be performed by open coded C: (inline) assembly must do the job.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You may want to look at the underlying opcodes the AVR uses. LD/LDS access something in RAM and load it into a register whereas there is a separate instruction, LPM, (load from program memory) that does the same but from flash (aka program memory aka PROGMEM) instead.

 

When you use pgm_read_XXX() you are simply saying "LPM this thing, don't just LD it"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

michac1995 wrote:
But if so, why I can't just use array[i] and access the data directly?

 

Because if you just use it like that, the compiler will assume the address of that array points to regular SRAM like all "normal" data, but it doesn't. So it will fetch some random data, not the one you want.

The address is only valid for the flash address space which is separate.