On an Atmel ATmega1284 (or any of its AVR cousins), is there any way to determine at compile time or at runtime whether an address that is passed to a function belongs to program memory space or data memory space?
Specifically, I want to provide a debug trace where the input string may be stored in program memory space or in data memory space, but I prefer to use just one function for it so the caller doesn't need to bother: if the input string is stored in program memory, I can copy it to a stack-allocated buffer and then pretend it was always in data memory. For example, in C-like pseudocode:
function my_trace(const char *string) {
if (is_in_program_memory_space(string)) {
strcpy_P(local_buffer, string);
print_the_(local_buffer);
}
else {
print_the_(string);
}
}
const char data_memory_string[] = "data memory string";
const char program_memory_string[] PROGMEM = "program memory string";
my_trace(data_memory_string);
my_trace(program_memory_string);
I tried to put in a breakpoint in the compiled code and it seems the addresses of a data-memory–allocated string and a program-memory–allocated string happen to be very close (like 0x800040 versus 0x800360) so I can't rely on address ranges. (And, doing that would probably be unsafe anyway, but that's a different discussion.)
Edit: I'm using the toolchain that comes with Atmel Studio, which in this case is version AVR_8_bit_GNU_Toolchain_3.6.2_1778.
Edit 2: The solution provided by user @NStorm indeed solves the problem. However, on my system it was necessary to typecast the return value of __builtin_avr_flash_segment() to a signed char.