demiurg_spb 0 9 сентября, 2015 Опубликовано 9 сентября, 2015 · Жалоба Раз уж такая пьянка, а не расскажете как заставить make пересобирать конкретный *.c даже если в нём не было изменений?Встречный вопрос: зачем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Twin_by 0 10 сентября, 2015 Опубликовано 10 сентября, 2015 · Жалоба И тем самым отключить выбрасывание всех неиспользуемых переменных. Если бы у меня возникла необходимость оставить в памяти неиспользуемую константу, я бы поместил ее в отдельную секцию (__attribute__((section("имя_секции")))) и разместил бы эту секцию именно туда, где она мне нужна, запретив линкеру ее выкидывать ( KEEP(*(имя_секции)) ) Что то не получается у меня реализовать ваш пример. Где я ошибся??? const char name_fw[5] PROGMEM = "xxxx"; __attribute__ ((section (".init3"))); KEEP(*(".init3")); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 10 сентября, 2015 Опубликовано 10 сентября, 2015 · Жалоба Вы собственно не применили атрибут. const char __attribute__ ((section (".init3"))) name_fw[5] = "xxxx"; KEEP(*(".init3")); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Twin_by 0 10 сентября, 2015 Опубликовано 10 сентября, 2015 · Жалоба Вы собственно не применили атрибут. const char __attribute__ ((section (".init3"))) name_fw[5] = "xxxx"; KEEP(*(".init3")); Теперь ругается на звездочку: expected declaration specifiers or '...' before '*' token Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msalov 0 10 сентября, 2015 Опубликовано 10 сентября, 2015 · Жалоба Раз уж такая пьянка, а не расскажете как заставить make пересобирать конкретный *.c даже если в нём не было изменений?Встречный вопрос: зачем? Например что бы обновлялась версия/дата сборки при каждой пересборке. Делается это так: .PHONY: FORCE FORCE: timestamp.o: FORCE %.o: %.c $(CC) ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 10 сентября, 2015 Опубликовано 10 сентября, 2015 · Жалоба Теперь ругается на звездочку: expected declaration specifiers or '...' before '*' tokenТак строку KEEP(*(".init3")) надо в скрипт лнкера вписывать, чтобы он знал, в какое именно место памяти надо вашу строку разместить. И не стоит использовать секции .initX - они уже используются стартапом. а не расскажете как заставить make пересобирать конкретный *.c даже если в нём не было изменений?touch my_file.c & make Чаще всего такая необходимость возникает при смене каких-то ключей в makefile. А поскольку мы заранее не знаем, какие файлы это может затронуть, лучше заставить make пересобирать все файлы при изменении makefile. У меня список всех объектных файлов собирается в переменной OBJ, поэтому в makefile присутствует строка: $(OBJ): makefile Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Twin_by 0 11 сентября, 2015 Опубликовано 11 сентября, 2015 · Жалоба Так строку KEEP(*(".init3")) надо в скрипт лнкера вписывать, чтобы он знал, в какое именно место памяти надо вашу строку разместить. И не стоит использовать секции .initX - они уже используются стартапом. А какую секцию лучше использовать? Я кроме этих секций AVR GCC: секции памяти (что такое .text, .data, .bss, .noinit?) , других не знаю. И второй вопрос где и как отредактировать скрипт линкера или где можно прочитать про него? Так чтобы на доступном языке. Я с этими вещами первый раз столкнулся поэтому опыта в этом маловато. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 11 сентября, 2015 Опубликовано 11 сентября, 2015 · Жалоба А какую секцию лучше использовать? Я кроме этих секций AVR GCC: секции памяти (что такое .text, .data, .bss, .noinit?) , других не знаю.Пока вы глубоко в этом не разобрались, добавлять можно в .text. Добавлять в .data не очень хорошо - вы получите копию вашей строки в ОЗУ. .bss, .noinit - тоже ОЗУ, но в отличие от .data их содержимое вообще в прошивку не попадает. И второй вопрос где и как отредактировать скрипт линкераПоищите в комплекте вашего компилятора файлы с расширением .ld Посмотрите их содержимое, почитайте комментарии в них. выберите тот, который подходит к вашему процессору (можно было каким-то ключем линкера узнать, какой из них он использует по-умолчанию для вашего процессора, но я не помню какой именно ключ нужен. Вы можете найти его самостоятельно, почитав документацию на линкер Google->"gnu ld"). Копируйте выбранный файл в папку проекта, дайте ему внятное имя и укажите линкеру использовать этот файл (в командную строку линкера добавьте -Wl,-T,имя_файла_скрипта). или где можно прочитать про него? Так чтобы на доступном языке.Не знаю, насколько доступен для вас английский. По ссылке выше в документации на линкер это раздел "3 Linker Scripts". Можете поискать перевод. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Twin_by 0 11 сентября, 2015 Опубликовано 11 сентября, 2015 · Жалоба Поищите в комплекте вашего компилятора файлы с расширением .ld Посмотрите их содержимое, почитайте комментарии в них. выберите тот, который подходит к вашему процессору (можно было каким-то ключем линкера узнать, какой из них он использует по-умолчанию для вашего процессора, но я не помню какой именно ключ нужен. Вы можете найти его самостоятельно, почитав документацию на линкер Google->"gnu ld"). Копируйте выбранный файл в папку проекта, дайте ему внятное имя и укажите линкеру использовать этот файл (в командную строку линкера добавьте -Wl,-T,имя_файла_скрипта). Что удалось узнать пока. Файлы ld Atmel Studio как таковые не использует. Она использует файлы в папке c:\WinAVR-20100110\avr\lib\ldscripts\avr2.* (avr2.* имеет поддержку процессора Attiny88 http://microsin.net/programming/avr/avr-gcc-options.html ) имеющие следующие описание: *.x script file is the default script *.xr script is for linking without relocation (-r flag) *.xu script is like .xr but *do* create constructors (-Ur flag) *.xn script is for linking with -n flag (mix text and data on same page). *.xbn script is for linking with -N flag (mix text and data on same page). Why are there five different linker scripts? Вот тут даются рекомендации по использованию своего скрипта AVR Libc Reference Manual Controlling the linker avr-ld. Там они предлагают заменить стандартный avr2.x на свой. Что я потом сделал. Я скопировал файл avr2.x в папку с проектом (там где Makefile, *.o, *.d), переименовал его в version_fw.x. Отредактировал его содержимое, добавив *(.text) KEEP(*(.text)) строчка 75 Потом в Atmel Studio main Properties -> Toolchain -> AVR/GNU Linker/Miscellaneous прописал -Wl,-T,-version_fw.x (или -version_fw). И при компилирование снова выдал ошибку: expected declaration specifiers or '...' before '*' token Прикрепил файл, расширение сменить на *.x version_fw.txt Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 11 сентября, 2015 Опубликовано 11 сентября, 2015 · Жалоба *(.text) KEEP(*(.text)) Тут имя секции .text не подходит. При линковке есть понятие "входные секции" - это которые компилятор создает в объектных файлах из вашего исходника и "выходные секции" - это в которые линкер складывает входные секции. То есть линкер берет входные секции и размещает их в выходные согласно скрипта. В выходном файле входных секций уже нет, в нем только выходные. Вы правильно разместили свою секцию внутри выходной секции .text. Но имя вашей секции надо было дать какое-то другое. Имя .text компилятор использует для кода. Потом в Atmel Studio main Properties -> Toolchain -> AVR/GNU Linker/Miscellaneous прописал -Wl,-T,-version_fw.x (или -version_fw).Минус лишний перед именем скрипта:-Wl,-T,version_fw.x И при компилирование снова выдал ошибку: expected declaration specifiers or '...' before '*' tokenА вы строчку KEEP(*(".init3")) из исходника убрали? Попробуйте так: В исходнике __attribute__ ((section (".fw_version"))) const char name_fw[] = "xxxx"; В скрипте линкера: *(.text) /*тут где-то еще должно быть*/ *(.text.*) KEEP(*(.fw_version)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Twin_by 0 11 сентября, 2015 Опубликовано 11 сентября, 2015 · Жалоба Тут имя секции .text не подходит. При линковке есть понятие "входные секции" - это которые компилятор создает в объектных файлах из вашего исходника и "выходные секции" - это в которые линкер складывает входные секции. То есть линкер берет входные секции и размещает их в выходные согласно скрипта. В выходном файле входных секций уже нет, в нем только выходные. Вы правильно разместили свою секцию внутри выходной секции .text. Но имя вашей секции надо было дать какое-то другое. Имя .text компилятор использует для кода. Минус лишний перед именем скрипта:-Wl,-T,version_fw.x А вы строчку KEEP(*(".init3")) из исходника убрали? Попробуйте так: В исходнике __attribute__ ((section (".fw_version"))) const char name_fw[] = "xxxx"; В скрипте линкера: *(.text) /*тут где-то еще должно быть*/ *(.text.*) KEEP(*(.fw_version)) Вроде получилось. проект собрался. Но выдал 21 предупреждения: c:/program files/atmel/atmel toolchain/avr8 gcc/native/3.4.1061/avr8-gnu-toolchain/bin/../lib/gcc/avr/4.8.1/../../../../avr/lib/avr25/crttn88.o: In function `__vector_1': (.text+0x0)(0,0): warning: internal error: out of range error Все предупреждения касаются векторов прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 11 сентября, 2015 Опубликовано 11 сентября, 2015 · Жалоба internal error:Это ошибка в линкере. По-хорошему надо писать сообщение об ошибке его авторам. Я на такое не нарывлася. Приложите весь проект в архиве. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Twin_by 0 14 сентября, 2015 Опубликовано 14 сентября, 2015 · Жалоба Это ошибка в линкере. По-хорошему надо писать сообщение об ошибке его авторам. Я на такое не нарывлася. Приложите весь проект в архиве. Я тут поигрался немного с форматом строчки, о точнее с содержимым строки name_fw[]. И заметил такую закономерность. Что если в строке четное количество символов, то проект соберется и выдаст Warning на вектора прерываний. А если в строке не четное количество символов, то все соберется без предупреждений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 14 сентября, 2015 Опубликовано 14 сентября, 2015 · Жалоба А если в строке не четное количество символов, то все соберется без предупреждений.Попробуйте тогда сделать так: *(.text) /*тут где-то еще должно быть*/ *(.text.*) KEEP(*(.fw_version)) . = ALIGN(2); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Twin_by 0 14 сентября, 2015 Опубликовано 14 сентября, 2015 (изменено) · Жалоба Попробуйте тогда сделать так: *(.text) /*тут где-то еще должно быть*/ *(.text.*) KEEP(*(.fw_version)) . = ALIGN(2); Помогло. Сейчас собирается без предупреждений. И создается два пустых байта после строки содержащей четное количество символов, и один байт если строка содержит не четное количество символов. Но была другая большая проблема. После прошивки микроконтроллера, он отказывался обрабатывать прерывания. Поэтому *(.fw_version) KEEP(*(.fw_version)) . = ALIGN(2); перенес из начала секции .text чуть ниже после *(.vectors) KEEP(*(.vectors)). И вроде работает, прерывания и АЦП обрабатывает. Сейчас секция .text приняла следующий вид .text : { *(.vectors) KEEP(*(.vectors)) *(.fw_version) KEEP(*(.fw_version)) . = ALIGN(2); /* For data that needs to reside in the lower 64k of progmem. */ *(.progmem.gcc*) *(.progmem*) . = ALIGN(2); __trampolines_start = .; /* The jump trampolines for the 16-bit limited relocs will reside here. */ *(.trampolines) *(.trampolines*) __trampolines_end = .; /* For future tablejump instruction arrays for 3 byte pc devices. We don't relax jump/call instructions within these sections. */ *(.jumptables) *(.jumptables*) /* For code that needs to reside in the lower 128k progmem. */ *(.lowtext) *(.lowtext*) __ctors_start = .; *(.ctors) __ctors_end = .; __dtors_start = .; *(.dtors) __dtors_end = .; KEEP(SORT(*)(.ctors)) KEEP(SORT(*)(.dtors)) /* From this point on, we don't bother about wether the insns are below or above the 16 bits boundary. */ *(.init0) /* Start here after reset. */ KEEP (*(.init0)) *(.init1) KEEP (*(.init1)) *(.init2) /* Clear __zero_reg__, set up stack pointer. */ KEEP (*(.init2)) *(.init3) KEEP (*(.init3)) *(.init4) /* Initialize data and BSS. */ KEEP (*(.init4)) *(.init5) KEEP (*(.init5)) *(.init6) /* C++ constructors. */ KEEP (*(.init6)) *(.init7) KEEP (*(.init7)) *(.init8) KEEP (*(.init8)) *(.init9) /* Call main(). */ KEEP (*(.init9)) *(.text) . = ALIGN(2); *(.text.*) . = ALIGN(2); *(.fini9) /* _exit() starts here. */ KEEP (*(.fini9)) *(.fini8) KEEP (*(.fini8)) *(.fini7) KEEP (*(.fini7)) *(.fini6) /* C++ destructors. */ KEEP (*(.fini6)) *(.fini5) KEEP (*(.fini5)) *(.fini4) KEEP (*(.fini4)) *(.fini3) KEEP (*(.fini3)) *(.fini2) KEEP (*(.fini2)) *(.fini1) KEEP (*(.fini1)) *(.fini0) /* Infinite loop after program termination. */ KEEP (*(.fini0)) _etext = .; } > text Изменено 14 сентября, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться