Is it possible to determine at runtime whether a pointer points to
PROGMEM'ed values or regular values? This would give some flexibility when writing code that handles both.
Not really, if you are asking whether you can determine (simply from its value) whether 0x100 is in RAM or PROGMEM. Both are possible candidates for a memory location.
F() macro works around this by changing the type of a variable at compile-time, so that the compiler can select a suitable method of printing. For example:
Serial.println ("Hello, world"); Serial.println (F("Hello, world"));
In this case the appropriate
println function is chosen at compile-time by the compiler, based on the type (one would be a
const char *, the other a
You are best off designing a way (similar to the
F() macro) where you can make the decision at compile time.
Is it possible to determine at runtime whether a pointer points to PROGMEM'ed values or regular values? This would give some flexibility when writing code that handles both.
The AVR MCUs are Harvard Architectures. Data and program memory spaces are separated. There are also several data memory spaces, e.g. SRAM, EEPROM, PROGMEM. Each of these have there own address space, and special instructions are used to access them.
In software anything is possible :) so it is possible to unify the address spaces and use a run-time mechanism to do the respective read and write. A simple method is to use the most significant bits to determine the address space. For instance,
SRAM 0x0000..0x7fff EEPROM 0x8000..0x8fff PROGMEM 0x9000..0xffff
SRAM pointers are as usual, EEPROM pointers have an extra 0x8000, and PROGMEM pointers an extra 0x9000.
The next step is to write a simple mapping function from the unified address space to the separate memory address spaces. This can be wrapped into a C+++ smart pointer and/or a simple C++ class hierarchy.
An example of this technique can be found in 1) Forth Virtual Machine for Arduino, https://github.com/mikaelpatel/Arduino-FVM (see https://github.com/mikaelpatel/Arduino-FVM/blob/master/src/FVM.cpp#L85), 2) RPN Postscript/Forth Command Shell for Arduino, https://github.com/mikaelpatel/Arduino-Shell (see https://github.com/mikaelpatel/Arduino-Shell/blob/master/Shell.h#L1059).
PS: An interesting detail with the AVR architecture is that the registers 0..31, and the io-registers, are mapped to the SRAM address space.