реклама на сайте
подробности

 
 
> Прописывание версии ПО (прошивки)
Twin_by
сообщение Sep 7 2015, 08:04
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Всем здравствуйте! Столкнулся с проблемой и никак не могу найти ее решение. Стоит задача прописывать в файле программы main.c имя версии. Я пробовал объявлять строку const char name_fw[] = "xxxx"; или const char name_fw[] PROGMEM = "xxxx"; Но при оптимизации эта строка вырезается т.к. в программе она нигде не используется. В итоге main.hex не содержит информации о версии ПО, и при считывании прошивки с микроконтроллера поди угадай какая версия туда была залита. Подскажите как можно решить эту проблему.
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 32)
KSN
сообщение Sep 7 2015, 08:05
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 404
Регистрация: 3-12-04
Из: Новосибирск
Пользователь №: 1 304



Попробуйте объявить через __root
Go to the top of the page
 
+Quote Post
V_G
сообщение Sep 7 2015, 08:24
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Пишу в AVRStudio на ассемблере.
Вот такая строка в кодовом сегменте:
Код
Version:
.DB    __DAY__,__MONTH__,__YEAR__,__HOUR__,__MINUTE__,__SECOND__        ;версия ПО

пропишет в память дату и время компиляции прошивки (удобнее,чем № версии).
Если нет аналогичной возможности на Си, попробуйте сделать ассемблерную вставку.
Go to the top of the page
 
+Quote Post
pyzhman
сообщение Sep 7 2015, 08:33
Сообщение #4





Группа: Новичок
Сообщений: 1
Регистрация: 29-03-12
Из: Тольятти
Пользователь №: 71 064



/* Turn optimization off, for testing purposes */
#pragma opt-

/* Turn optimization on */
#pragma opt+
Go to the top of the page
 
+Quote Post
RadiatoR
сообщение Sep 7 2015, 08:45
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 270
Регистрация: 8-08-15
Из: Москва
Пользователь №: 87 901



Да что вы мучаетесь? напишите const volatile и будет вам счастье
Go to the top of the page
 
+Quote Post
Spider
сообщение Sep 7 2015, 08:53
Сообщение #6


В поисках истины
***

Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923



Цитата(ЯadiatoR @ Sep 7 2015, 11:45) *
Да что вы мучаетесь? напишите const volatile и будет вам счастье

Опередил sm.gif +1
Go to the top of the page
 
+Quote Post
EvgenWL
сообщение Sep 7 2015, 09:18
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 20-10-06
Из: Иваново
Пользователь №: 21 504



Twin_by, а как Вы на работающем устройстве определяете версию залитой в него прошивки? Напишите команду чтения версии вот и будет обращение к строке и никаких volatile не понадобится.
Go to the top of the page
 
+Quote Post
Twin_by
сообщение Sep 7 2015, 10:05
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Цитата(ЯadiatoR @ Sep 7 2015, 11:45) *
Да что вы мучаетесь? напишите const volatile и будет вам счастье


Volatile не помогает, при оптимизации строчка выкидывается

Цитата(EvgenWL @ Sep 7 2015, 12:18) *
Twin_by, а как Вы на работающем устройстве определяете версию залитой в него прошивки? Напишите команду чтения версии вот и будет обращение к строке и никаких volatile не понадобится.


А на работающем никак не определить версию ПО. Этого и не нужно. Нужно после того как сняли модуль, прочитать микроконтроллер и с помощью hex-editor (XVI32) найти имя прошивки.

Цитата(V_G @ Sep 7 2015, 11:24) *
Пишу в AVRStudio на ассемблере.
Вот такая строка в кодовом сегменте:
Код
Version:
.DB    __DAY__,__MONTH__,__YEAR__,__HOUR__,__MINUTE__,__SECOND__    ;версия ПО

пропишет в память дату и время компиляции прошивки (удобнее,чем № версии).
Если нет аналогичной возможности на Си, попробуйте сделать ассемблерную вставку.


Попробовал ваш вариант. Но ругается ошибкой " Error 1 unknown pseudo-op: `.db' ". Пишу в AtmelStudio 6.2
Код
asm("Version: .DB DAY__,__MONTH__,__YEAR__,__HOUR__,__MINUTE__,__SECOND");

Go to the top of the page
 
+Quote Post
Jury093
сообщение Sep 7 2015, 13:10
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050



Цитата(Twin_by @ Sep 7 2015, 13:05) *
Попробовал ваш вариант. Но ругается ошибкой " Error 1 unknown pseudo-op: `.db' ". Пишу в AtmelStudio 6.2

лет 10 назад выводил примерно так:
Код
uart_puts(__DATE__); // вывели дату прошивки в порт
uart_putc(' ');
uart_puts(__TIME__); // вывели время прошивки в порт

на выхлопе в консоли что-то типа Oct 24 2014 01:53:28
не заглядывал, но вероятно эти же цифры будут и в бинарнике..
(работает на m8, m128, m16, m32, m8535)
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Sep 7 2015, 13:27
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Компилятор-то какой?

Для gcc можно использовать
__attrubute__((used))
const char name_fw[] PROGMEM = "xxxx";


Подробности: https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gc...able-Attributes


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
Twin_by
сообщение Sep 8 2015, 10:57
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Вроде получилось. И получилось двумя способами: способ от Spider и от esaulenka. Единственное что общего у них, это что картинка флагов оптимизации (-Os) выглядела следующим образом

-ffunction-sections (prepare functions for garbage collection) = SET
-fdata-sections (prepare functions for data collection) = CLEAR (по умолчанию обычно SET)
-fpack-struct (pack structure members together) = SET
-fshort-enums (allocate only as many bytes needed by enaum types) = SET
-mshort-calls (use rjamp/rcall (limited range) on > 8K devices) = CLEAR

Поэтому, чтобы прописать версию прошивки (ПО) нужно было убрать флаг -fdata-sections и после инклудов написать:

Код
volatile const char fw_name[5] PROGMEM = "xxxx";

ИЛИ
Код
const char name_fw[5] PROGMEM = "xxxx";
__attribute__ ((used (name_fw)));


Если есть еще какие замечания или комментарии с интересом выслушаю. Всем спасибо за помощь и советы. Esaulenka отдельное спасибо за ссылочку. Она еще мне пригодиться)

Go to the top of the page
 
+Quote Post
Kovrov
сообщение Sep 9 2015, 08:58
Сообщение #12


Мастер-фломастер
****

Группа: Свой
Сообщений: 611
Регистрация: 29-12-05
Пользователь №: 12 700



Цитата(V_G @ Sep 7 2015, 12:24) *
Пишу в AVRStudio на ассемблере.
Вот такая строка в кодовом сегменте:
Код
Version:
.DB    __DAY__,__MONTH__,__YEAR__,__HOUR__,__MINUTE__,__SECOND__    ;версия ПО

пропишет в память дату и время компиляции прошивки (удобнее,чем № версии).
Если нет аналогичной возможности на Си, попробуйте сделать ассемблерную вставку.


слушайте действительно работает!
а где вы вычитали эту фичу?


--------------------
Вон ПОПОВ, клоун клоуном, а радио изобрел!!
Go to the top of the page
 
+Quote Post
V_G
сообщение Sep 9 2015, 11:27
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Уже не помню. Лет 15 назад, когда начинал работать с AVR-ками.
__DAY__ и прочее - это специфические константы avr-ассемблера. Видимо, в хэлпе по ассемблеру.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 9 2015, 12:00
Сообщение #14


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Twin_by @ Sep 8 2015, 13:57) *
Поэтому, чтобы прописать версию прошивки (ПО) нужно было убрать флаг -fdata-sections
И тем самым отключить выбрасывание всех неиспользуемых переменных. Если бы у меня возникла необходимость оставить в памяти неиспользуемую константу, я бы поместил ее в отдельную секцию (__attribute__((section("имя_секции")))) и разместил бы эту секцию именно туда, где она мне нужна, запретив линкеру ее выкидывать ( KEEP(*(имя_секции)) )


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Spider
сообщение Sep 9 2015, 13:04
Сообщение #15


В поисках истины
***

Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923



Раз уж такая пьянка, а не расскажете как заставить make пересобирать конкретный *.c даже если в нём не было изменений?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Sep 9 2015, 13:38
Сообщение #16


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Spider @ Sep 9 2015, 16:04) *
Раз уж такая пьянка, а не расскажете как заставить make пересобирать конкретный *.c даже если в нём не было изменений?
Встречный вопрос: зачем?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Twin_by
сообщение Sep 10 2015, 12:37
Сообщение #17


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Цитата(Сергей Борщ @ Sep 9 2015, 15:00) *
И тем самым отключить выбрасывание всех неиспользуемых переменных. Если бы у меня возникла необходимость оставить в памяти неиспользуемую константу, я бы поместил ее в отдельную секцию (__attribute__((section("имя_секции")))) и разместил бы эту секцию именно туда, где она мне нужна, запретив линкеру ее выкидывать ( KEEP(*(имя_секции)) )


Что то не получается у меня реализовать ваш пример. Где я ошибся???
Код
const char name_fw[5] PROGMEM = "xxxx";
__attribute__ ((section (".init3")));
KEEP(*(".init3"));
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Sep 10 2015, 12:55
Сообщение #18


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Вы собственно не применили атрибут.
Код
const char __attribute__ ((section (".init3"))) name_fw[5] = "xxxx";
KEEP(*(".init3"));


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Twin_by
сообщение Sep 10 2015, 13:47
Сообщение #19


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Цитата(demiurg_spb @ Sep 10 2015, 15:55) *
Вы собственно не применили атрибут.
Код
const char __attribute__ ((section (".init3"))) name_fw[5] = "xxxx";
KEEP(*(".init3"));

Теперь ругается на звездочку: expected declaration specifiers or '...' before '*' token
Go to the top of the page
 
+Quote Post
msalov
сообщение Sep 10 2015, 14:00
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(demiurg_spb @ Sep 9 2015, 16:38) *
Цитата(Spider @ Sep 9 2015, 16:04) *
Раз уж такая пьянка, а не расскажете как заставить make пересобирать конкретный *.c даже если в нём не было изменений?
Встречный вопрос: зачем?


Например что бы обновлялась версия/дата сборки при каждой пересборке.
Делается это так:

Код
.PHONY: FORCE
FORCE:

timestamp.o: FORCE

%.o: %.c
    $(CC) ...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 10 2015, 19:05
Сообщение #21


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Twin_by @ Sep 10 2015, 16:47) *
Теперь ругается на звездочку: expected declaration specifiers or '...' before '*' token
Так строку KEEP(*(".init3")) надо в скрипт лнкера вписывать, чтобы он знал, в какое именно место памяти надо вашу строку разместить. И не стоит использовать секции .initX - они уже используются стартапом.


Цитата(Spider @ Sep 9 2015, 16:04) *
а не расскажете как заставить make пересобирать конкретный *.c даже если в нём не было изменений?
touch my_file.c & make
Чаще всего такая необходимость возникает при смене каких-то ключей в makefile. А поскольку мы заранее не знаем, какие файлы это может затронуть, лучше заставить make пересобирать все файлы при изменении makefile. У меня список всех объектных файлов собирается в переменной OBJ, поэтому в makefile присутствует строка:
Код
$(OBJ): makefile


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Twin_by
сообщение Sep 11 2015, 06:43
Сообщение #22


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Цитата(Сергей Борщ @ Sep 10 2015, 22:05) *
Так строку KEEP(*(".init3")) надо в скрипт лнкера вписывать, чтобы он знал, в какое именно место памяти надо вашу строку разместить. И не стоит использовать секции .initX - они уже используются стартапом.

А какую секцию лучше использовать? Я кроме этих секций AVR GCC: секции памяти (что такое .text, .data, .bss, .noinit?) , других не знаю. И второй вопрос где и как отредактировать скрипт линкера или где можно прочитать про него? Так чтобы на доступном языке. Я с этими вещами первый раз столкнулся поэтому опыта в этом маловато.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 11 2015, 07:16
Сообщение #23


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Twin_by @ Sep 11 2015, 09:43) *
А какую секцию лучше использовать? Я кроме этих секций AVR GCC: секции памяти (что такое .text, .data, .bss, .noinit?) , других не знаю.
Пока вы глубоко в этом не разобрались, добавлять можно в .text. Добавлять в .data не очень хорошо - вы получите копию вашей строки в ОЗУ. .bss, .noinit - тоже ОЗУ, но в отличие от .data их содержимое вообще в прошивку не попадает.
Цитата(Twin_by @ Sep 11 2015, 09:43) *
И второй вопрос где и как отредактировать скрипт линкера
Поищите в комплекте вашего компилятора файлы с расширением .ld Посмотрите их содержимое, почитайте комментарии в них. выберите тот, который подходит к вашему процессору (можно было каким-то ключем линкера узнать, какой из них он использует по-умолчанию для вашего процессора, но я не помню какой именно ключ нужен. Вы можете найти его самостоятельно, почитав документацию на линкер Google->"gnu ld").
Копируйте выбранный файл в папку проекта, дайте ему внятное имя и укажите линкеру использовать этот файл (в командную строку линкера добавьте -Wl,-T,имя_файла_скрипта).

Цитата(Twin_by @ Sep 11 2015, 09:43) *
или где можно прочитать про него? Так чтобы на доступном языке.
Не знаю, насколько доступен для вас английский. По ссылке выше в документации на линкер это раздел "3 Linker Scripts". Можете поискать перевод.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Twin_by
сообщение Sep 11 2015, 13:05
Сообщение #24


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Цитата(Сергей Борщ @ Sep 11 2015, 10:16) *
Поищите в комплекте вашего компилятора файлы с расширением .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 ( 5.96 килобайт ) Кол-во скачиваний: 16
 
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 11 2015, 13:32
Сообщение #25


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Twin_by @ Sep 11 2015, 16:05) *
Код
*(.text)
KEEP(*(.text))
Тут имя секции .text не подходит. При линковке есть понятие "входные секции" - это которые компилятор создает в объектных файлах из вашего исходника и "выходные секции" - это в которые линкер складывает входные секции. То есть линкер берет входные секции и размещает их в выходные согласно скрипта. В выходном файле входных секций уже нет, в нем только выходные. Вы правильно разместили свою секцию внутри выходной секции .text. Но имя вашей секции надо было дать какое-то другое. Имя .text компилятор использует для кода.

Цитата(Twin_by @ Sep 11 2015, 16:05) *
Потом в Atmel Studio main Properties -> Toolchain -> AVR/GNU Linker/Miscellaneous прописал -Wl,-T,-version_fw.x (или -version_fw).
Минус лишний перед именем скрипта:-Wl,-T,version_fw.x

Цитата(Twin_by @ Sep 11 2015, 16:05) *
И при компилирование снова выдал ошибку: expected declaration specifiers or '...' before '*' token
А вы строчку KEEP(*(".init3")) из исходника убрали? Попробуйте так:
В исходнике
Код
__attribute__ ((section (".fw_version")))
const char name_fw[] = "xxxx";

В скрипте линкера:
Код
*(.text)
/*тут где-то еще должно быть*/  *(.text.*)
KEEP(*(.fw_version))


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Twin_by
сообщение Sep 11 2015, 14:03
Сообщение #26


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Цитата(Сергей Борщ @ Sep 11 2015, 16:32) *
Тут имя секции .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

Все предупреждения касаются векторов прерывания.

Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 11 2015, 14:53
Сообщение #27


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата
internal error:
Это ошибка в линкере. По-хорошему надо писать сообщение об ошибке его авторам. Я на такое не нарывлася. Приложите весь проект в архиве.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Twin_by
сообщение Sep 14 2015, 06:17
Сообщение #28


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Цитата(Сергей Борщ @ Sep 11 2015, 17:53) *
Это ошибка в линкере. По-хорошему надо писать сообщение об ошибке его авторам. Я на такое не нарывлася. Приложите весь проект в архиве.


Я тут поигрался немного с форматом строчки, о точнее с содержимым строки name_fw[]. И заметил такую закономерность. Что если в строке четное количество символов, то проект соберется и выдаст Warning на вектора прерываний. А если в строке не четное количество символов, то все соберется без предупреждений.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 14 2015, 07:55
Сообщение #29


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Twin_by @ Sep 14 2015, 09:17) *
А если в строке не четное количество символов, то все соберется без предупреждений.
Попробуйте тогда сделать так:
Код
*(.text)
/*тут где-то еще должно быть*/  *(.text.*)
KEEP(*(.fw_version))
. = ALIGN(2);



--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Twin_by
сообщение Sep 14 2015, 11:30
Сообщение #30


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Цитата(Сергей Борщ @ Sep 14 2015, 10:55) *
Попробуйте тогда сделать так:
Код
*(.text)
/*тут где-то еще должно быть*/  *(.text.*)
KEEP(*(.fw_version))
. = ALIGN(2);

Помогло. Сейчас собирается без предупреждений. И создается два пустых байта после строки содержащей четное количество символов, и один байт если строка содержит не четное количество символов. Но была другая большая проблема. После прошивки микроконтроллера, он отказывался обрабатывать прерывания. Поэтому
Код
*(.fw_version)
KEEP(*(.fw_version))
. = ALIGN(2);


перенес из начала секции .text чуть ниже после *(.vectors) KEEP(*(.vectors)). И вроде работает, прерывания и АЦП обрабатывает. Сейчас секция .text приняла следующий вид
CODE
.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


Сообщение отредактировал IgorKossak - Sep 14 2015, 13:51
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 14 2015, 12:05
Сообщение #31


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Twin_by @ Sep 14 2015, 14:30) *
Помогло. Сейчас собирается без предупреждений. И создается два пустых байта после строки содержащей четное количество символов, и один байт если строка содержит не четное количество символов.
Строка в Си заканчивается нулевым байтом. . = ALIGN(2); при необходимости добавляет еще один, чтобы выровнять адрес на четный (команды у AVR должны располагаться по четным адресам.

Цитата(Twin_by @ Sep 14 2015, 14:30) *
Поэтому
Код
*(.fw_version)
KEEP(*(.fw_version))
. = ALIGN(2);


перенес из начала секции .text чуть ниже после *(.vectors) KEEP(*(.vectors)).
Да, ваш файл я не посмотрел, поленился. Мне казалось очевидным, что вектора прибиты к своим адресам гвоздями и никто не догадается их сдвигать, запихнув перед ними какие-то данные..


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Twin_by
сообщение Sep 14 2015, 12:53
Сообщение #32


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-09-11
Из: Минск
Пользователь №: 66 982



Цитата(Сергей Борщ @ Sep 14 2015, 15:05) *
Да, ваш файл я не посмотрел, поленился. Мне казалось очевидным, что вектора прибиты к своим адресам гвоздями и никто не догадается их сдвигать, запихнув перед ними какие-то данные..

А я вот догадался, с вашей помощью кстати ))) Зато как красиво было ... Бинарник открываешь и в первой же строчке информация о версии прошивки. Но такой вариант оказался не рабочий.

Огромное спасибо, что помогли замутить такую полезную штуку. В процессе я почерпнул много нового.

Сообщение отредактировал Twin_by - Sep 14 2015, 12:54
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 14 2015, 14:11
Сообщение #33


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Twin_by @ Sep 14 2015, 15:53) *
А я вот догадался, с вашей помощью кстати )))
"А что поделать, если хлопец одаренный?" wink.gif

Цитата(Twin_by @ Sep 14 2015, 15:53) *
Бинарник открываешь и в первой же строчке информация о версии прошивки.
Вы можете разместить ее в конце файла, тоже будет удобно искать.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 11:15
Рейтинг@Mail.ru


Страница сгенерированна за 0.0171 секунд с 7
ELECTRONIX ©2004-2016