Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ошибка при оптимизации
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Troll
Доброго дня.

Возникла следующая проблема.

При использовании параметров компиляции -ffunction-sections -fdata-sections и компоновки -Wl,--gc-sections в программе появляется ошибка. При сборке без данных параметров все работает.

Описание проблемы:
При старте программы происходит настройка периферии. PIT настраивается на период в 1 сек. По прошествии одной секунды происходит прерывание... Дальнейшее сокрыто мраком до перезагрузки проца WatchDog'om (через 16 сек).

Дополнительно:
- происходит именно прерывание от PIT, проверял путем выключением прерывания и увеличения периода (соответственно проц зависал на несколько секунд позже).
- в обработку прерывания PIT вставил команду сброса сторожевого таймера, сторожевой таймер не сбрасывается. Следовательно после прерывания проц переходит непонятно куда, либо не возвращается из прерывания.
- листинг функций конфигурации таймера и обработки прерываний для обоих режимов компиляции не отличается (за исключением начальных адресов функций). Листинг смотрел в объектном файле после линковки, то есть оптимизатор не выкидывает функции, как не нужные.
- единственное отличие, которое нашел, это то что функции располагаются в разных секциях. Что является само собой разумеющимся при использовании указанных параметров оптимизации.
- компилятор GNU GCC 4.2.2, binutils 2.18.

Буду рад услышать Ваши рекомендации по решению данной проблемы.

С уважением.
ARV
Цитата(Troll @ Feb 9 2009, 15:31) *
При использовании параметров компиляции -ffunction-sections -fdata-sections и компоновки -Wl,--gc-sections ...
при передачи компоновщику команды таким способом один минус лишний (выделен красным)
Troll
Цитата(ARV @ Feb 12 2009, 01:39) *
при передачи компоновщику команды таким способом один минус лишний (выделен красным)


Нет не помогает.

В какую еще сторону можно покопать?
ARV
листинг надо смотреть... что-то не то с таблицей векторов прерываний, наверное... -fdata-sections попробуйте убрать - лично у меня как-то не было эффекта от этой опции, сколько не пробовал...
Troll
Цитата(ARV @ Feb 12 2009, 11:05) *
листинг надо смотреть... что-то не то с таблицей векторов прерываний, наверное... -fdata-sections попробуйте убрать - лично у меня как-то не было эффекта от этой опции, сколько не пробовал...

-fdata-sections - убрал, не помогает.

в присоединенном файле листинг и map файл.
функции: pitc_handler - обработчик прерывания; configure_pit - настройка PIT.

А где в листинге смотреть таблицу векторов? Не нашел или не там смотрел.
Troll
Вроде разобрался...

Цитата(ARV @ Feb 12 2009, 11:05) *
что-то не то с таблицей векторов прерываний, наверное...
Да. Оптимизатор выкидывал секцию векторов.
В скрипте линкера изменил:
*(.vectors) -> KEEP(*(.vectors))

Для корректной работы с параметром "-fdata-sections"
в скрипт добавил строку: *(.data*)

Всем спасибо за участие.
Troll
А... немного погорячился.

С векторами все в порядке, а вот с оптимизированными данными нет.

При использовании опции "-fdata-sections" не обнуляются глобальные переменные, если глобальная переменная инициализируется не нулевым значением, то все нормально.

Пример:
CODE
int varA = 0;
int varB = 100;

main () {
printf("%d, %d\r\n", varA, varB);
}

В результате будет выведено "-220118871(просто случайное число), 100".

Вот такая фигня. Выслушаю Ваши предложения и замечания.
Troll
Продолжаем разговор...

Неициализированные переменные и переменные инициализированные нулем размещаются в секции _bss.
Без опции "-fdata-sections" переменные инициализируемые нулем - обнуляются. В mapfile есть строки:
CODE
.......................
*(.bss)
.bss 0x00200bec 0x4 syscalls.o
.bss 0x00200bf0 0x1 usart.o
*fill* 0x00200bf1 0x3 00
.bss 0x00200bf4 0xc din_dout.o
0x00200bf8 fin_counter1
0x00200bfc fin_counter2
........................
Далее после *fill* перечисляются все переменные, которые будут обнулены.

При включении опции "-fdata-sections" в mapfile:
CODE
..............................
.bss.fin_counter1
0x00202958 0x4 load address 0x00111b00
.bss.fin_counter1
0x00202958 0x4 din_dout.o
0x00202958 fin_counter1

.bss.fin_counter2
0x0020295c 0x4 load address 0x00111b04
.bss.fin_counter2
0x0020295c 0x4 din_dout.o
0x0020295c fin_counter2
......................

То есть переменные инициализируются, но по адресам 0x00111b00, 0x00111b04 не нулевые значения.

Что надо сказать линкеру, чтобы он записывал по нужным адресам нули не знаю.

Как вариант решения можно использовать опцию "-fno-zero-initialized-in-bss" (по-умолчанию "-fzero-initialized-in-bss"), тогда переменные инициализируемые нулем располагаются в секции .data и все замечательно.

В общем вопрос корректной иницилизации остается открытым.
aesok
Цитата(Troll @ Mar 13 2009, 06:45) *
В скрипте линкера изменил:
*(.vectors) -> KEEP(*(.vectors))


Это уже исправленно в binutils 2.19.

Цитата(Troll @ Mar 13 2009, 06:45) *
С векторами все в порядке, а вот с оптимизированными данными нет.


Похоже линкер выкидывает .initX секции.
Попробуйте добавить KEEP() для всех .initX и .finiX секций.

Анатолий.
Troll
Все разобрался 08.gif

Цитата(aesok @ Mar 13 2009, 12:56) *
Похоже линкер выкидывает .initX секции.
Нет не выкидывает.

При включении оптимизации линкер раскидывает данные по разным секциям. Получается куча секций: ".bss.fin_counter1", ".bss.fin_counter2" и т. д. Причем эти секции не входят в .bss. Линковщик добавляет (не выкидывает) эти секции уже после секции bss, соответственно они и не инициализируются при старте. Добавил в скрипт линкера строку (выделена красным) и все заработало.

CODE
/*Кусок из скрипта линкера*/
/* collect all uninitialized .bss sections that go into FLASH */
.bss : {
. = ALIGN(4);
_sbss = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
}

Теперь кажется все, всем спасибо.
alx2
Цитата(Troll @ Mar 13 2009, 08:45) *
При использовании опции "-fdata-sections" не обнуляются глобальные переменные
...
Вот такая фигня. Выслушаю Ваши предложения и замечания.
Вообще-то обнуление .bss* - забота программиста. Проверяйте свой стартап-код. Линкер ничего никуда записывать не должен - это не его работа. Его работа - поместить объекты, требующие обнуления, в .bss*. А обнуление этой области - забота программиста.
ReAl
Цитата(alx2 @ Mar 15 2009, 14:41) *
Вообще-то обнуление .bss* - забота программиста. Проверяйте свой стартап-код. Линкер ничего никуда записывать не должен - это не его работа. Его работа - поместить объекты, требующие обнуления, в .bss*. А обнуление этой области - забота программиста.
А никто и не говорит, что линкер, выполняющийся на PC ("они не инициализируютя при старте" не равно "линкер их не инициаплизирует"), должен записывать нули в область памяти в микроконтроллере.
Сам стартап смотреть нет смысла, обнуляющий код для .bss в нём есть.
Но чтобы стартап-код, обнуляющий от _sbss до _ebss, обнулил входные для линкера секции .bss.*, линкер должен записать эти секции в свою выходную секцию .bss между точками генерации этих меток. Что и достигнуто было добавленной строкой - все входные .bss.* оказались в выходной .bss и стартап их "увидел".
Diz
Мне показалось, или выход из прерываний совсем некорректный ?
Troll
Цитата(Diz @ Mar 15 2009, 23:18) *
Мне показалось, или выход из прерываний совсем некорректный ?

Не понял Вашего вопроса, поясните подробнее, что Вы имели в виду.
alx2
Цитата(ReAl @ Mar 15 2009, 18:05) *
А никто и не говорит, что линкер, выполняющийся на PC ("они не инициализируютя при старте" не равно "линкер их не инициаплизирует"), должен записывать нули в область памяти в микроконтроллере.

Цитата(Troll @ Mar 13 2009, 10:53) *
Что надо сказать линкеру, чтобы он записывал по нужным адресам нули не знаю.

Цитата(ReAl @ Mar 15 2009, 18:05) *
Сам стартап смотреть нет смысла, обнуляющий код для .bss в нём есть.
Я в этом не был так уверен. Месяц назад в этом же форуме у кого-то была проблема из-за того, что он забыл в стартапе проинициализировать секцию .data.
Diz
Цитата(Troll @ Mar 16 2009, 06:15) *
Не понял Вашего вопроса, поясните подробнее, что Вы имели в виду.

В листинге не увидел восстановление PC = LR - 4 и CPSR, затем понял, что это должно быть делается в в общем irq-обработчике из startup.S.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.