即使声明为(已使用)PROGMEM变量也被丢弃

时间:2017-02-08 14:37:17

标签: c linker avr-gcc atmelstudio progmem

我使用ATMEL Studio 6.2及其工具链与avr-gcc(avr8-gnu-toolchain)。我有一个需要放在flash中的变量(PROGMEM),我将它声明为全局:

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

编译器没有抱怨并且链接器没有抱怨,但是当我打开.lss文件时,没有找到gPrgLen。在.map文件中,我们可以看到它已被列在"被丢弃的输入部分"

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

它是作为发行版构建的,但是调试版本会产生相同的结果。 如何强制链接器将此变量包含在*(.progmem*)部分?

EDIT
添加了static,但结果仍然相同。

这是链接器部分:

# 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 个答案:

答案 0 :(得分:0)

奇怪__attribute__((used))无效。尝试两个建议。

首先,将变量从static更改为volatile(或只添加volatile)。 可以阻止它被优化掉。

如果这不起作用,您可以在链接器中添加一行以使其“[p]使符号符号未定义,强制链接库模块以定义它” (GCC Link Options)。这是通过-u symbol--undefined=symbol完成的。

要将其添加到Atmel Studio项目文件,请转到工具链 - > AVR / GNU链接器 - >杂。然后在其他链接器标志中添加--undefined=gPrgLen

我已经使用它将修订/编译时信息嵌入到Hex文件中,否则不会使用它。这样我就可以从设备中检索内存并知道它在什么条件下构建(主要用于在原型设计和初始固件调试期间跟踪更改)。我的main.c文件有一个类似const char codeCompileDetails[] PROGMEM = "company_name-" __DATE__ "-" __TIME__;的全局char数组。与--undefined=codeCompileDetails结合,该数据(此处包括编译代码的日期和时间)始终将其作为可执行文件。