1
votes

I'm using ATMEL Studio 6.2 and its toolchain with avr-gcc (avr8-gnu-toolchain). I have a variable that needs to be placed in flash (PROGMEM) and I declare it as a global:

static const uint16_t gPrgLen PROGMEM __attribute__((used)) = 0;

The compiler doesn't complain and the linker doesn't complain, but when I open the .lss file, there is no gPrgLen to be found. In the .map file we can see that it has been listed under "discarded input sections"

Discarded input sections
.progmem.data.gPrgLen    0x00000000    0x2    Boot.o

It is built as a release, but a debug build gives the same result. How can I force the linker to include this variable in the *(.progmem*) section?

EDIT
Added static but still the same result.

Here is the linker part:

# All Target
all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES)

$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP) $(LIB_DEP)
@echo Building target: $@
@echo Invoking: AVR/GNU Linker : 4.8.1
$(QUOTE)C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="Boot.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,--gc-sections -Wl,-section-start=.text=0xf800  -mmcu=at90usb647  
@echo Finished building target: $@
"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "Boot.elf" "Boot.hex"
"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-objcopy.exe" -j .eeprom  --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0  --no-change-warnings -O ihex "Boot.elf" "Boot.eep" || exit 0
"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-objdump.exe" -h -S "Boot.elf" > "Boot.lss"
"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O srec -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "Boot.elf" "Boot.srec"
"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-size.exe" "Boot.elf"
1
have you tried this line (void)PROGMEM; somewhere in your code to force usage of the variable? if it doesn't work, then you have to force it in the linker file (do you have a linker file ?)Jean-François Fabre
I have tried to use the variable in the program, but it's still not linked. ATMEL Studio is generating the make file, but I can set "free" options in the project properties.Max Kielland
can you post the linker part of the makefile?Jean-François Fabre
Updated with makefile linker section.Max Kielland
Are you using avr-g++? Try putting extern "C" at the very beginning of the line defining the PROGMEM variable, to tell the compiler not the mangle its name.David Grayson

1 Answers

0
votes

Odd that __attribute__((used)) isn't working. Two suggestions to try.

First, change the variable from static to volatile (or just add volatile). That may prevent it from being optimized away.

If that doesn't work, instead you can add a line to the linker to make it "[p]retend the symbol symbol is undefined, to force linking of library modules to define it" (GCC Link Options). This is done via -u symbol or --undefined=symbol.

To add it to the Atmel Studio project file, go to Toolchain -> AVR/GNU Linker -> Miscellaneous. Then in Other Linker Flags add --undefined=gPrgLen.

I've used this to embed revision/compile-time information into the Hex file where it wasn't otherwise used. That way I could retrieve the memory from a device and know under what conditions it was built (primarily for tracking changes during prototyping and initial firmware debugging). My main.c file had a global char array that looked something like const char codeCompileDetails[] PROGMEM = "company_name-" __DATE__ "-" __TIME__;. Coupled with --undefined=codeCompileDetails, that data (here including the date and time the code was compiled) always makes it into the executable.