|
Ошибка при оптимизации, Помогите разобраться |
|
|
|
Feb 9 2009, 12:31
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
Доброго дня.
Возникла следующая проблема.
При использовании параметров компиляции -ffunction-sections -fdata-sections и компоновки -Wl,--gc-sections в программе появляется ошибка. При сборке без данных параметров все работает.
Описание проблемы: При старте программы происходит настройка периферии. PIT настраивается на период в 1 сек. По прошествии одной секунды происходит прерывание... Дальнейшее сокрыто мраком до перезагрузки проца WatchDog'om (через 16 сек).
Дополнительно: - происходит именно прерывание от PIT, проверял путем выключением прерывания и увеличения периода (соответственно проц зависал на несколько секунд позже). - в обработку прерывания PIT вставил команду сброса сторожевого таймера, сторожевой таймер не сбрасывается. Следовательно после прерывания проц переходит непонятно куда, либо не возвращается из прерывания. - листинг функций конфигурации таймера и обработки прерываний для обоих режимов компиляции не отличается (за исключением начальных адресов функций). Листинг смотрел в объектном файле после линковки, то есть оптимизатор не выкидывает функции, как не нужные. - единственное отличие, которое нашел, это то что функции располагаются в разных секциях. Что является само собой разумеющимся при использовании указанных параметров оптимизации. - компилятор GNU GCC 4.2.2, binutils 2.18.
Буду рад услышать Ваши рекомендации по решению данной проблемы.
С уважением.
--------------------
Hemos Pasado
|
|
|
|
|
Feb 12 2009, 03:59
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
Цитата(ARV @ Feb 12 2009, 01:39)  при передачи компоновщику команды таким способом один минус лишний (выделен красным) Нет не помогает. В какую еще сторону можно покопать?
--------------------
Hemos Pasado
|
|
|
|
|
Feb 12 2009, 06:18
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
Цитата(ARV @ Feb 12 2009, 11:05)  листинг надо смотреть... что-то не то с таблицей векторов прерываний, наверное... -fdata-sections попробуйте убрать - лично у меня как-то не было эффекта от этой опции, сколько не пробовал... -fdata-sections - убрал, не помогает. в присоединенном файле листинг и map файл. функции: pitc_handler - обработчик прерывания; configure_pit - настройка PIT. А где в листинге смотреть таблицу векторов? Не нашел или не там смотрел.
--------------------
Hemos Pasado
|
|
|
|
|
Mar 12 2009, 06:52
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
Вроде разобрался... Цитата(ARV @ Feb 12 2009, 11:05)  что-то не то с таблицей векторов прерываний, наверное... Да. Оптимизатор выкидывал секцию векторов. В скрипте линкера изменил: *(.vectors) -> KEEP(*(.vectors)) Для корректной работы с параметром "-fdata-sections" в скрипт добавил строку: *(.data*) Всем спасибо за участие.
--------------------
Hemos Pasado
|
|
|
|
|
Mar 13 2009, 03:45
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
А... немного погорячился. С векторами все в порядке, а вот с оптимизированными данными нет. При использовании опции "-fdata-sections" не обнуляются глобальные переменные, если глобальная переменная инициализируется не нулевым значением, то все нормально. Пример: CODE int varA = 0; int varB = 100;
main () { printf("%d, %d\r\n", varA, varB); } В результате будет выведено "-220118871(просто случайное число), 100". Вот такая фигня. Выслушаю Ваши предложения и замечания.
--------------------
Hemos Pasado
|
|
|
|
|
Mar 13 2009, 05:53
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
Продолжаем разговор... Неициализированные переменные и переменные инициализированные нулем размещаются в секции _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 и все замечательно. В общем вопрос корректной иницилизации остается открытым.
--------------------
Hemos Pasado
|
|
|
|
|
Mar 13 2009, 06:56
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Troll @ Mar 13 2009, 06:45)  В скрипте линкера изменил: *(.vectors) -> KEEP(*(.vectors)) Это уже исправленно в binutils 2.19. Цитата(Troll @ Mar 13 2009, 06:45)  С векторами все в порядке, а вот с оптимизированными данными нет. Похоже линкер выкидывает .initX секции. Попробуйте добавить KEEP() для всех .initX и .finiX секций. Анатолий.
|
|
|
|
|
Mar 13 2009, 08:41
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
Все разобрался Цитата(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 = .; }
Теперь кажется все, всем спасибо.
--------------------
Hemos Pasado
|
|
|
|
|
Mar 15 2009, 12:41
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Цитата(Troll @ Mar 13 2009, 08:45)  При использовании опции "-fdata-sections" не обнуляются глобальные переменные ... Вот такая фигня. Выслушаю Ваши предложения и замечания. Вообще-то обнуление .bss* - забота программиста. Проверяйте свой стартап-код. Линкер ничего никуда записывать не должен - это не его работа. Его работа - поместить объекты, требующие обнуления, в .bss*. А обнуление этой области - забота программиста.
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
|
Mar 15 2009, 13:05
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(alx2 @ Mar 15 2009, 14:41)  Вообще-то обнуление .bss* - забота программиста. Проверяйте свой стартап-код. Линкер ничего никуда записывать не должен - это не его работа. Его работа - поместить объекты, требующие обнуления, в .bss*. А обнуление этой области - забота программиста. А никто и не говорит, что линкер, выполняющийся на PC ("они не инициализируютя при старте" не равно "линкер их не инициаплизирует"), должен записывать нули в область памяти в микроконтроллере. Сам стартап смотреть нет смысла, обнуляющий код для .bss в нём есть. Но чтобы стартап-код, обнуляющий от _sbss до _ebss, обнулил входные для линкера секции .bss.*, линкер должен записать эти секции в свою выходную секцию .bss между точками генерации этих меток. Что и достигнуто было добавленной строкой - все входные .bss.* оказались в выходной .bss и стартап их "увидел".
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Mar 16 2009, 03:15
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
Цитата(Diz @ Mar 15 2009, 23:18)  Мне показалось, или выход из прерываний совсем некорректный ? Не понял Вашего вопроса, поясните подробнее, что Вы имели в виду.
--------------------
Hemos Pasado
|
|
|
|
|
Mar 16 2009, 10:57
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Цитата(ReAl @ Mar 15 2009, 18:05)  А никто и не говорит, что линкер, выполняющийся на PC ("они не инициализируютя при старте" не равно "линкер их не инициаплизирует"), должен записывать нули в область памяти в микроконтроллере. Цитата(Troll @ Mar 13 2009, 10:53)  Что надо сказать линкеру, чтобы он записывал по нужным адресам нули не знаю. Цитата(ReAl @ Mar 15 2009, 18:05)  Сам стартап смотреть нет смысла, обнуляющий код для .bss в нём есть. Я в этом не был так уверен. Месяц назад в этом же форуме у кого-то была проблема из-за того, что он забыл в стартапе проинициализировать секцию .data.
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|