Skip to main content
Tweeted twitter.com/StackElectronix/status/1322146259357106176
edited body
Source Link

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 typecasetypecast the return value of __builtin_avr_flash_segment() to a signed char.

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 typecase the return value of __builtin_avr_flash_segment() to a signed char.

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.

added 199 characters in body
Source Link

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 typecase the return value of __builtin_avr_flash_segment() to a signed char.

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.

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 typecase the return value of __builtin_avr_flash_segment() to a signed char.

added 129 characters in body
Source Link

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.

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.)

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.

Source Link
Loading