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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Yagarto Eclipse+GCC4.2.1/4.2.2 - в хидерах компилятся все функции!, Это такая "особенность" или я ... ?
injen-d
сообщение Jan 11 2008, 19:40
Сообщение #1


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

Группа: Свой
Сообщений: 91
Регистрация: 10-10-07
Из: Воронежа
Пользователь №: 31 250



Всем доброго времени суток.
Помогите пожалуйста, может кто сталкивался с подобными непонятками, буду очень признателен.
Не так давно AVRа стало маловато, решил переходить на ARM7, причем софт решил использовать свободный, чтоб так сказать все по честному. Выбор пал на YAGARTO Eclipse + GCC. До этого писал преимущественно на ассемблере, поэтому столкнулся с массой трудностей. Но постепенно все прояснялось, вот только со следующей проблемой борюсь уже 2 дня и ни сколько не продвинулся в ее решении. wacko.gif
Даже появились грешные мысли воспользоваться ломаным иаром или кейлом 05.gif
Проблема в следующем:
решил я воспользоваться файлом "libAT91SAM7S256.h" (взял его где-то из примеров) и сразу после его подключения и последующей компиляции (ни одну из его функций я еще не использовал) размер генерируемого кода увеличился с 1К до 17К. Как выяснилось компилятся все функции независимо от того, вызывались они или нет. После "танцев с бубном, протирки монитора и постукивания по системнику" совершенно чудесным образом хидер начал компилиться как надо: только те функции которые были вызваны из main (или другой функции). 08.gif
На радостях я решил сделать еще один хидер назвал его "icpsr.h" и вставил содержимое из файла "isrsupport.c" из примера demo_at91sam7_blink_flash. И тут опять старая проблема! Причем "libAT91SAM7S256.h" работает правильно, а "icpsr.h" компилится весь. Приведенные выше маневры не помогли. Подскажите, плиз проблема в компиляторе или в моей голове?
Проэкт прилагается.
Прикрепленный файл  NEW_workspace.rar ( 802.72 килобайт ) Кол-во скачиваний: 154


ЗЫ: при установке компилятору уровня оптимизации отличного от -О0 размер кода заметно сокращается, но компилятор начинает полностью игнорировать конструкции типа:
for (k = 600000; k != 0; k-- ); как будто их не существует!


--------------------
- Бендер, ты же робот, зачем тебе пить пиво?
- Незачем! Я могу бросить в любой момент!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 11 2008, 21:17
Сообщение #2


Гуру
******

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



Цитата(injen-d @ Jan 11 2008, 21:40) *
решил я воспользоваться файлом "libAT91SAM7S256.h" (взял его где-то из примеров) и сразу после его подключения и последующей компиляции (ни одну из его функций я еще не использовал) размер генерируемого кода увеличился с 1К до 17К.
Дело в том, что на уровне оптимизации -O0 выключено встраивание функций, и квалификатор __inline не работает. Поэтому включите оптимизацию хотя бы -O1, а лучше всего -Os. Чтобы любые неиспользуемые функции не подлинковывалисть в выходной файл, добавьте в makefile
Код
CFLAGS += -ffunction-sections -fdata-sections    # to remove dead code, if any, at link time
LDFLAGS += -Wl,--gc-sections    #remove dead code ("garbage collection")
Цитата(injen-d @ Jan 11 2008, 21:40) *
ЗЫ: при установке компилятору уровня оптимизации отличного от -О0 размер кода заметно сокращается, но компилятор начинает полностью игнорировать конструкции типа:
for (k = 600000; k != 0; k-- ); как будто их не существует!
Правильно. Этот код ничего не делает, поэтому и выкидывается. Вы же хотели оптимизацию - вот компилятор и сократил и код, и время выполнения. Вам ведь не нравятся другие медленно работающие программы? wink.gif Чтобы этого не происходило, объявите k как volatile или вставьте в тело цикла что-нибудь типа asm(" nop");


--------------------
На любой вопрос даю любой ответ
"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
injen-d
сообщение Jan 12 2008, 19:01
Сообщение #3


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

Группа: Свой
Сообщений: 91
Регистрация: 10-10-07
Из: Воронежа
Пользователь №: 31 250



Спасибо за разъяснение, но это проблему не решило.
Я поправил Makefile, правда не совсем так, как вы указали:
Код
CFLAGS += -ffunction-sections -fdata-sections    # to remove dead code, if any, at link time  
LDFLAGS += -Wl,--gc-sections    #remove dead code ("garbage collection")

я исправил на:
Код
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections

в соответствии с "GNAT User’s Guide For gcc version 4.2.2"
Цитата
7.3.2 Compilation options
The operation of eliminating the unused code and data from the final executable is directly
performed by the linker.
In order to do this, it has to work with objects compiled with the following options:
‘-ffunction-sections’ ‘-fdata-sections’. These options are usable with C and Ada
files. They will place respectively each function or data in a separate section in the resulting
object file.
Once the objects and static libraries are created with these options, the linker can perform
the dead code elimination. You can do this by setting the ‘-Wl,--gc-sections’
option to gcc command or in the ‘-largs’ section of gnatmake. This will create the final
executable, without including the code and data determined as never accessed.
Note that objects compiled without the ‘-ffunction-sections’ and ‘-fdata-sections’
options can still be linked with the executable. However, no dead code elimination will be
performed on those objects (they will be linked as is).
The GNAT static library is now compiled with -ffunction-sections and -fdata-sections.
This allows you to eliminate the unused code of the GNAT library from your executable.

После этого линкер начал требовать прописывания секции для каждой функции и глобальной переменной. После срочного изучения основ написания скриптов для линкера родились следующие строки:
Код
.text :        /* collect all sections that should go into FLASH after startup  */
    {
/*        *(.text)                    /* all .text sections (code)  */
        *(.text.main)
        *(.text.USART0_setup)
        *(.text.uart0_putc)
        *(.text.Usart_c_irq_handler)
        *(.text.LowLevelInit)
        *(.text.blinker)
                         ...

Проэкт начал компилиться без ошибок. biggrin.gif
Но не все так хорошо:
1) "правильно" компилятся только __inline функции, остальные же по-прежнему компилятся всегда и при удалении их вызова сами они никуда из итогового кода не исчезают.
2) линкер требует прописывания секций так же для функций находящихся в хидере icpsr.h (кроме __inline функций), даже если они не вызывались.
3) а если у меня в проэкте около сотни различных функций наберется? Это ж сколько писанины в разных файлах. wacko.gif А еще глобальные переменные...
Все вышеизложенное наталкивает на мысль, что решение должно быть гораздо проще.
К тому же, в первоначальном варианте, до вышеописанной правки, для эксперемента я сделал __inline все функции в файле icpsr.h, таким образом получилось два почти одинаковых файла icpsr.h и libAT91SAM7S256.h. Различие было лишь в количестве содержащихся функций. Затем я подключал эти хидеры в соседних строках одного си-файла и вызывал по одной функции из каждого файла тоже в соседних строках, при этом из файла libAT91SAM7S256.h компилировалась только вызываемая функция, а из icpsr.h все по отдельности + еще раз вызываемая на этот раз в нужном месте. Глаза поломал, но разницу между файлами (кроме количества содержащихся функций) не увидел. unsure.gif
В чем может быть причина?
Да и файл libAT91SAM7S256.h поначалу тоже компилился весь, но в какой-то момент во время танцев с бубном заработал как надо, и при последующей правке всяких мелочей содержимого и проб вариантов для поиска причины, работать не перестал.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 12 2008, 19:35
Сообщение #4


Гуру
******

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



Цитата(injen-d @ Jan 12 2008, 21:01) *
Я поправил Makefile, правда не совсем так, как вы указали:
Это не принципиально.
Цитата(injen-d @ Jan 12 2008, 21:01) *
После этого линкер начал требовать прописывания секции для каждой функции и глобальной переменной.
Я тоже не большой специалист, но у меня получилось так:
Код
  .text :
  {
    .......
    *(.text)            /* code */
    *(.text.*)          /* code */

    .............
  } > ROM
Аналогично и для данных. Приведенные выше ключи компилятора заставляют выделять отдельную секцию для каждой функции и для каждой переменной (ибо линкер по --gc-sections умеет выкидывать только секции целиком).
Цитата(injen-d @ Jan 12 2008, 21:01) *
Все вышеизложенное наталкивает на мысль, что решение должно быть гораздо проще.
Использование шаблонного символа '*' в скрипте.
Цитата(injen-d @ Jan 12 2008, 21:01) *
Затем я подключал эти хидеры в соседних строках одного си-файла и вызывал по одной функции из каждого файла тоже в соседних строках, при этом из файла libAT91SAM7S256.h компилировалась только вызываемая функция, а из icpsr.h все по отдельности + еще раз вызываемая на этот раз в нужном месте.
Если до понедельника никто не ответит - покомпилирую приложенный вами выше проект, помедитирую. Пока не готов дать ответ.


--------------------
На любой вопрос даю любой ответ
"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
zltigo
сообщение Jan 12 2008, 19:44
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(injen-d @ Jan 12 2008, 21:01) *
1) "правильно" компилятся только __inline функции, остальные же по-прежнему компилятся всегда и при удалении их вызова сами они никуда из итогового кода не исчезают.

А с какого бодуна они должны исчезать smile.gif? Объектные файлы линкуются целиком.
Некоторые форматы объектников и соответственно поддерживающие их линкеры позволяют выборочную линковку, но это вымирающая (ARM IAR до перехода на elf умел ) редкость.
Читайте про библиотеки, делайте их и пользуйтесь.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
injen-d
сообщение Jan 12 2008, 19:56
Сообщение #6


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

Группа: Свой
Сообщений: 91
Регистрация: 10-10-07
Из: Воронежа
Пользователь №: 31 250



Цитата(zltigo @ Jan 12 2008, 22:44) *
А с какого бодуна они должны исчезать smile.gif? Объектные файлы линкуются целиком.
Некоторые форматы объектников и соответственно поддерживающие их линкеры позволяют выборочную линковку, но это вымирающая (ARM IAR до перехода на elf умел ) редкость.
Читайте про библиотеки, делайте их и пользуйтесь.

Создать библиотеку? Это интересно rolleyes.gif
Вы, случайно ссылочкой не располагаете, где почитать про создание библиотек для ARM-GCC ?
Буду очень признателен.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 12 2008, 20:46
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(injen-d @ Jan 12 2008, 21:56) *
Вы, случайно ссылочкой не располагаете, где почитать про создание библиотек для ARM-GCC ?

Дык, библиотекарь неотъемлимая часть набора инструментов. В GNU он, правда странновато называется ar (архивный библиотекарь).


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
injen-d
сообщение Jan 12 2008, 20:50
Сообщение #8


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

Группа: Свой
Сообщений: 91
Регистрация: 10-10-07
Из: Воронежа
Пользователь №: 31 250



Цитата(zltigo @ Jan 12 2008, 23:46) *
Дык, библиотекарь неотъемлимая часть набора инструментов. В GNU он, правда странновато называется ar (архивный библиотекарь).

Спасибо zltigo, нагуглил простое описание для GCC. Щас как раз пытаюсь сделать статическую библиотеку из icpsr.h, напишу что получится. wink.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 12 2008, 22:39
Сообщение #9


Гуру
******

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



Цитата(injen-d @ Jan 12 2008, 22:50) *
Щас как раз пытаюсь сделать статическую библиотеку из icpsr.h, напишу что получится. wink.gif
Все же мне кажется, вы несколько не в ту сторону двигаетесь. Вы ведь не будете каждый файл компилировать в библиотеку.
1) нужно включить оптимизацию. В противном случае функции не будут инлайнится и если вы включите один заголовочник в несколько .c-файлов - получите несколько копий одной и той же функции в объектниках, с руганью на стадии линковки - линкер не знает, какую из копий использовать (он ведь не знает, что это копии)
2) все нестатические и невстраиваемые (не inline) функции из .c-файлов попадают в объектный файл при компиляции - ведь только на этапе линковки можно определить, какая функция потребуется, а какая нет.
3) линкер не знает, где начинается одна функция, а где заканчивается предыдущая, поэтому он может выкинуть только всю секцию целиком. Для этого компилятор помещает каждую функцию в отдельную секцию (-ffunction-sections). Тогда, если нет обращений к функции нет и обращений к этой секции и линкер может такую секцию выкинуть. Выкидывая секцию, линкер выкидывает функцию целиком, причем только одну. Поэтому, даже если будете пользоваться библиотеками, вам придется каждую функцию компилировать в библиотеку из отдельного исходного файла - иначе получите то же самое, что и сейчас.
4)-ffunction-sections прекрасно работает со скриптами, идущими в комплекте WinAVR. Пробовал и сборку Yagarto, тоже работает.

Указание в скрипте линкера входных секций как *(.text.*) не помогло?


--------------------
На любой вопрос даю любой ответ
"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
injen-d
сообщение Jan 13 2008, 10:33
Сообщение #10


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

Группа: Свой
Сообщений: 91
Регистрация: 10-10-07
Из: Воронежа
Пользователь №: 31 250



Цитата
Указание в скрипте линкера входных секций как *(.text.*) не помогло?

Еще как помогло! smile.gif
Правда файл crt.s перестал линковаться (вместо ассемблерных команд непонятные значения, занимающие тот же объем в итоговом файле). Но после вставки скрипта из примеров для WinARM и небольших в нем исправлений, все заработало.
В main.dmp вижу:
Код
0010047c <EnableFIQ>:
  10047c:    e10f0000     mrs    r0, CPSR
  100480:    e3c03040     bic    r3, r0, #64; 0x40
  100484:    e129f003     msr    CPSR_fc, r3
  100488:    e12fff1e     bx    lr
Disassembly of section .text.EnableIRQ:

0010048c <EnableIRQ>:
  10048c:    e10f0000     mrs    r0, CPSR
  100490:    e3c03080     bic    r3, r0, #128; 0x80
  100494:    e129f003     msr    CPSR_fc, r3
  100498:    e12fff1e     bx    lr
Disassembly of section .text.RestoreIRQ:

0010049c <RestoreIRQ>:
  10049c:    e10f2000     mrs    r2, CPSR
  1004a0:    e2000080     and    r0, r0, #128; 0x80
  1004a4:    e3c23080     bic    r3, r2, #128; 0x80
  1004a8:    e1833000     orr    r3, r3, r0
  1004ac:    e129f003     msr    CPSR_fc, r3
  1004b0:    e1a00002     mov    r0, r2
  1004b4:    e12fff1e     bx    lr

таким образом каждая функция расположена в своей секции, уровни оптимизации пробовал разные, в данном случае -Оs. Все функции на месте, хотя я вызываю только EnableIRQ() один раз в main.c.
Пробовал комментировать вызовы функций, находящихся в USART_setup.c в частности USART0_setup();
Картина та же - исчезает только команда вызова.
Может еще каких-нибудь флажков в мэйкфайле не хватает? laughing.gif
Цитата
Поэтому, даже если будете пользоваться библиотеками, вам придется каждую функцию компилировать в библиотеку из отдельного исходного файла - иначе получите то же самое, что и сейчас.

Вы, Сергей, абсолютно правы - уже убедился, так и есть: при вызове одной подключаются все. Слишком накладно получается каждую функцию из отдельного файла. unsure.gif


--------------------
- Бендер, ты же робот, зачем тебе пить пиво?
- Незачем! Я могу бросить в любой момент!
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 13 2008, 10:41
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(injen-d @ Jan 13 2008, 12:33) *
Слишком накладно получается каждую функцию из отдельного файла. unsure.gif

Но, придется именно так, если пытаетесь делать абстрактную библиотеку. Практически для конкретной работы достаточно группы функций разбить по файлам и дополнительно добавить ключи условной трансляции для нескольких вариантов сборки.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
injen-d
сообщение Jan 13 2008, 11:02
Сообщение #12


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

Группа: Свой
Сообщений: 91
Регистрация: 10-10-07
Из: Воронежа
Пользователь №: 31 250



Цитата
группы функций разбить по файлам

Значит все таки можно для создания библиотеки несколько независимых функций в один файл?
Или вы имели ввиду /основная функция + вызываемые из нее функции/ в одном файле?


--------------------
- Бендер, ты же робот, зачем тебе пить пиво?
- Незачем! Я могу бросить в любой момент!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 13 2008, 11:25
Сообщение #13


Гуру
******

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



Цитата(injen-d @ Jan 13 2008, 12:33) *
Картина та же - исчезает только команда вызова.
Может еще каких-нибудь флажков в мэйкфайле не хватает? laughing.gif
До меня только сегодня дошло - вы опцию, которая должны передаваться линкеру, -Wl,--gc-sections (это одна опция), поместили в CFLAGS и передаете компилятору. А ее надо поместить в LDFLAGS, ибо при линковке вы в качестве флагов используете именно ее (точнее, у вас она названа LFLAGS, но в документации на GNU make ее рекомендуется называть LDFLAGS):
Код
main.out: $(OBJECTS) test.cmd
    @ echo "..linking"
    $(LD) $(LFLAGS) -o main.out $(OBJECTS) libc.a libm.a libgcc.a
чего-то я стормозил вчера в 21.35. У вас линкер не получает --gc-sections и поэтому не выкидывает неиспользуемые секции.

Цитата(injen-d @ Jan 13 2008, 13:02) *
Значит все таки можно для создания библиотеки несколько независимых функций в один файл?
Можно. Указав при компиляции --ffunction-sections. Круг замкнулся smile.gif


--------------------
На любой вопрос даю любой ответ
"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
zltigo
сообщение Jan 13 2008, 11:28
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(injen-d @ Jan 13 2008, 13:02) *
Значит все таки можно для создания библиотеки несколько независимых функций в один файл?

Без труда - нет.
Цитата
Или вы имели ввиду /основная функция + вызываемые из нее функции/ в одном файле?

Ну что-то приблизительно, как вариант.
Я имел ввиду, что совсем-уж независимые функции бывают редко и можно объединять их в группы, даже если они друг из друга не вызываются. Ну а то, что много файлов, то в общем-то сильных неудобств при нормальном редакторе с проектом, тэгами.... это вызывать не должно.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
injen-d
сообщение Jan 13 2008, 11:47
Сообщение #15


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

Группа: Свой
Сообщений: 91
Регистрация: 10-10-07
Из: Воронежа
Пользователь №: 31 250



Цитата
До меня только сегодня дошло - вы опцию, которая должны передаваться линкеру, -Wl,--gc-sections (это одна опция), поместили в CFLAGS и передаете компилятору. А ее надо поместить в LDFLAGS, ибо при линковке вы в качестве флагов используете именно ее (точнее, у вас она названа LFLAGS, но в документации на GNU make ее рекомендуется называть LDFLAGS)

Вобще-то, насколько я понял из документации (в школе учил французский biggrin.gif ), -Wl, - означает "передать следующий флаг линкеру".
Однако попробовал переименовать на LDFLAGS и т. д.
В итоге:
LDFLAGS = --gc-sections -Map main.map -T test.cmd
после компиляции ошибок нет, но:
Код
TOTAL SIZE:
arm-elf-size -t main.out
   text       data        bss        dec        hex    filename
      0          0          0          0          0    main.out
      0          0          0          0          0    (TOTALS)

Выходные файлы пусты, а объектные созданы правильно.


--------------------
- Бендер, ты же робот, зачем тебе пить пиво?
- Незачем! Я могу бросить в любой момент!
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 09:54
Рейтинг@Mail.ru


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