2017-02-08 14 views
1

Я использую ATMEL Studio 6.2 и ее инструментальную цепочку с avr-gcc (avr8-gnu-toolchain). У меня есть переменная, которая должна быть помещена в флэш (PROGMEM), и я объявить его как глобальный:Переменная 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: [email protected] 
@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: [email protected] 
"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" 
+0

Вы пробовали эту строку '(void) PROGMEM;' где-то в вашем коде, чтобы принудительно использовать переменную? если он не работает, тогда вы должны принудительно его в файле компоновщика (у вас есть файл-линкера?) –

+0

Я попытался использовать переменную в программе, но она по-прежнему не связана. ATMEL Studio создает файл make, но я могу установить «свободные» параметры в свойствах проекта. –

+0

можете ли вы разместить компоновщик в файле makefile? –

ответ

0

Странно, что __attribute__((used)) не работает. Два предложения попробовать.

Сначала измените переменную от static до volatile (или просто добавьте volatile). То, что может предотвратить его оптимизацию.

Если это не работает, вместо этого вы можете добавить строку компоновщика, чтобы сделать его «[р] retend символа символ не определен, чтобы заставить увязывание библиотеки модулей, чтобы определить его» (GCC Link Options). Это делается через -u symbol или --undefined=symbol.

Чтобы добавить его в файл проекта Atmel Studio, перейдите в Toolchain -> AVR/GNU Linker -> Miscellaneous. Затем в Other Linker Flags добавьте --undefined=gPrgLen.

Я использовал это, чтобы вставлять информацию о ревизии/компиляции в файл Hex, где он иначе не использовался. Таким образом, я мог бы извлечь память с устройства и узнать, при каких условиях он был создан (в основном для отслеживания изменений во время прототипирования и первоначальной отладки встроенного ПО). Мой файл main.c имел глобальный массив символов, который выглядел примерно как const char codeCompileDetails[] PROGMEM = "company_name-" __DATE__ "-" __TIME__;. В сочетании с --undefined=codeCompileDetails эти данные (здесь, включая дату и время, когда код был скомпилирован) всегда вносят его в исполняемый файл.