3

I'm using an Arduino Due where double have a size of 8 bytes. In my software, I use double table const stored in prog memory, I was using an UNO before and used pgm_read_float_near() to retrieve these values. What function should I use?

2 Answers 2

6

Arduino Due (ARM Cortex-M3) doesn't need anything like PROGMEM as it has access into the flash memory in the same way as into the RAM. The const qualifier is enough to keep it in program memory only.

The AVR based boards like UNO needs PROGMEM because there are different instructions for fetching data from program memory and g++ is not very advanced in this way (some other compilers supports it directly - for example in gcc you can use __flash and __eeprom instead, but not in g++ as it was rejected for some reasons)

Edit:

Currently there are also AVRs with a new design (they are more like xmegas) and they are having flat address space (emulation) so with single pointer you can fetch RAM, FLASH, EEPROM and so on. But it's limited to the devices with smaller FLASH (all of it must fit into 64kB/16b pointers). In those cases you can just use const for global arrays and it'll be stored in FLASH (and not in FLASH and loaded into RAM upon startup like old AVRs) and string literals doesn't need P_STR / F() macros

For example:

  • Atmega4809 (nano every, uno wifi r2) and variants: 808, 809, 1608, 1609, 3208, 3209, 4808
  • Attiny(2/4/8/16/32)(0/1/2)(2,4,6,7) - eg Attiny212 1616 ...
  • It should be also possible on AVR16/AVR32 devices, but 64kB/128kB ones needs PROGMEM again (compiler can't optimize it into FLASH as you have only snapshot of 32kB in direct address space, but it's possible to change it - however there is also erratum about it not working properly)
2
  • “instruntions” ?? May 17, 2017 at 21:18
  • 4
    Yes, Jmaes, instruntions. They're what you hit microcontrollers with to make them work.
    – Majenko
    May 17, 2017 at 21:23
0

For anyone looking for an equivalent, you can manually copy the bytes into a double like:

double pgm_read_double(const double* address) {
    double result;
    memcpy_P(&result, address, sizeof(double));
    return result;
}

And use memcpy_PF for far addresses. But know that many MCUs have access into the flash memory in the same way as into the RAM, so you don't need to use this at all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.