|
|
  |
Вопрос по WINAVR |
|
|
|
Jul 27 2007, 07:24
|

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

|
Цитата(AndryG @ Jul 26 2007, 16:01)  повозился вчера с makefile от компилятора ... добавил в gcc -D__AVR_$(TARGET)__ -- теперь в коде можно вспоминать только хидер io.h , а "персональные" хидеры для контроллера теперь io.h вставит!
Люди, а не поделится ли кто описанием ключей запуска на winavr на русском языке? Что-то я спросонок не пойму... Если есть ключ, например, -mmcu=atmega88 то gcc сам порождает и нужный __AVR_ATmega88__, и по мере необходимости всякие __AVR_ENHANCED__, __AVR_HAVE_LPMX__ и т.п. Причём я не помню времён, когда этого не было, т.е. когда мне не хватало комбинации -mmcu и io.h
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Oct 24 2007, 16:12
|

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

|
Цитата(ReAl @ Jul 5 2007, 21:04)  По кр. мере в двух самых свежих сборках WinAVR --gc-sections работает, незадействованные функции успешно выбрасывает (соответственно при -fdata-sections будет должно вышвыривать глоблаьные и static-переменные, на которые нет ссылок). Вероятно, заработало это где-то тогда, когда к обработчикам прерываний стали __attribute__((used)) цеплять. Вчера и я попробовал. Действительно выбрасывает. Даже те функции, которые с __attribute__((used)) описал. даже без -ffunction-sections. Пробовал и 20060421 и 20070525. Что же делать? Есть у меня одна функция, которая из отдельно скомпилированного загрузчика вызывается. И вторая проблема: то же самое, но с данными. -fdata-sections выкидывает массив, который нужно зарезервировать для функции из области загрузчика, т.е. скомпилированной отдельным проектом. Несмотря на наличие __attribute__((used)). Как бороться? Заводить фиктивные указатели на эти функцию и массив не хочу - некрасиво это. Еще один вопрос - как называется функция, с которой начинается выполнение (что в ENTRY() скрипта ld указывать)?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 25 2007, 21:40
|

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

|
Цитата(Сергей Борщ @ Oct 24 2007, 18:12)  Вчера и я попробовал. Действительно выбрасывает. Даже те функции, которые с __attribute__((used)) описал. даже без -ffunction-sections. Пробовал и 20060421 и 20070525. ... Заводить фиктивные указатели на эти функцию и массив не хочу - некрасиво это. Мда. Мрак. Бестолку фиктивный указатель... Сначала он выбрасывается "ввиду необращения", потом то, на что он указывал. Кстати, я пробовал с 20070525 --gc-sections без -ffunction-sections ничего не выбрасывает. А с -ffunction-sections - да, used не помогает. Почитал ещё - таки похоже used касается только компилятора и только на этапе компиляции файла. Линкеру никакой информации об этом аттрибуте не передаётся. Пока нарыл только то, что невызываемая ниоткуда функция не выбрасывается, если передать линкеру ключик -u/--undefined -Wl,-u,func_nameон применяется для принудительной линковки модуля из библиотеки по имени глобального символа, даже если на него нигде нет ссылки - эдакое ручное помещение символа в таблицу необходимых ссылок. Судя по описанию ключа - то же самое делается командой EXTERN в линкероном скрипте. После чего линкер считает это имя хоть кому-то да нужным и не выбрасывает по --gc-sections Цитата(Сергей Борщ @ Oct 24 2007, 18:12)  Еще один вопрос - как называется функция, с которой начинается выполнение (что в ENTRY() скрипта ld указывать)? В запускалке стандартной там вообще не функция, а идёт переход на weak метку __init, она в секции .init0, потом вслед за ней линкерным скриптом складываются секции вплоть до .init9, которая состоит из jmp main. А из init-секции в init-секцию переход не jmp/call, а просто "естественным путём". Т.е. если у себя завести функцию с именем __init, то по нулевому адресу будет поставлен jump (а не call) на неё и вся цепочка - инициализация указателя стека, обнуление __zero_reg__, инициализация .data, зачистка .bss, конструкторы С++ - пойдут лесом.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Oct 26 2007, 08:30
|

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

|
Цитата(ReAl @ Oct 26 2007, 00:40)  Пока нарыл только то, что невызываемая ниоткуда функция не выбрасывается, если передать линкеру ключик -u/--undefined Спасибо, использую. Непередача used линкеру - это как, бага или фича? Может надо сообщить авторам, чтоб поправили? Цитата(ReAl @ Oct 26 2007, 00:40)  В запускалке стандартной там вообще не функция, а идёт переход на weak метку __init, она в секции .init0, потом вслед за ней линкерным скриптом складываются секции вплоть до .init9, которая состоит из jmp main. А из init-секции в init-секцию переход не jmp/call, а просто "естественным путём". Т.е. ENTRY() не нужна? А по --gc-sections вся эта инициализация не выкинется однажды?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 26 2007, 08:56
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Сергей Борщ @ Oct 26 2007, 12:30)  А по --gc-sections вся эта инициализация не выкинется однажды? Не выкиниться, все стандартные имена (vectors, initX, и.т.д.) в ld скрипте начиня с версии binutils 2.17 помпомечены атрибутом KEEP (...). В версии 2.16 (WinAVR-2006..) еще не помечены, и по этой причине опции "-ffunction-sections" и "-fdata-sections" не работают. Анатолий.
Сообщение отредактировал aesok - Oct 26 2007, 08:59
|
|
|
|
|
Oct 26 2007, 12:03
|

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

|
Цитата(aesok @ Oct 26 2007, 11:56)  Не выкиниться, все стандартные имена (vectors, initX, и.т.д.) в ld скрипте начиня с версии binutils 2.17 помпомечены атрибутом KEEP (...). Вот оно! Я клал свою функцию и массив в отдельные секции принудительно. Сделал в скрипте этим секциям KEEP() и все получилось. Спасибо!!! Остался открытым вопрос - то, что компилятор не передает линкеру атрибут used - это бага или так и должно быть? Цитата(AndryG @ Oct 26 2007, 13:17)  Почитал я ваши посты ... и поник ... как просто было с CV ... а тут  Сложности возникают при попытке сделать что-то нетривиальное - "чесать левое ухо правой ногой". Поверьте, я писал аналогичную программу в CV - знали бы вы сколько времени было потрачено, чтобы заставить его разместить ту самую функцию и тот самый массив по нужным мне адресам, и через какую ж.. это в конце-концов получилось реализовать. Так что зря пугаетесть - с WinAVR у вас могут быть трудности в начале, зато потом гладкий полет, с CV будете иметь с точностью до наоборот - сначала легкий старт, потом какое-то время полет, потом большие трудности (если, конечно, ваши программы будут развиваться). После того, как подружили WinAVR и AVRStudio проблем с WinAVR нет даже в начале. В этой связке сложности начнутся, если захотите использовать С++. Плагин пока почему-то не позволяет подключать плюсовые файлы. Но есть альтернатива в виде Eclipse - как среда разработки гораздо удобнее студии, студию можно пользовать только как симулятор.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 26 2007, 12:20
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(Сергей Борщ @ Oct 26 2007, 16:03)  Вот оно! Я клал свою функцию и массив в отдельные секции принудительно. Сделал в скрипте этим секциям KEEP() и все получилось. Спасибо!!! Остался открытым вопрос - то, что компилятор не передает линкеру атрибут used - это бага или так и должно быть? Из описания атрибута used следует что код функции должен быть в объектном файле, но ничего не говориться о том должен ли линкер добавить секцию где находиться этот код в исполняемый файл. Анатолий.
|
|
|
|
|
Oct 26 2007, 13:22
|

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

|
Цитата(aesok @ Oct 26 2007, 15:20)  Из описания атрибута used следует что код функции должен быть в объектном файле, но ничего не говориться о том должен ли линкер добавить секцию где находиться этот код в исполняемый файл. Честно говоря я описание аттрибутов читаю здесь и там сказано просто: Цитата means that code must be emitted for the function even if it appears that the function is not referenced И тут нет деления на объектный/исполняемый код. Компилятор-то все равно в объектник складывает все, и используемое и нет. А уже линкер собирает только нужное. Вот я и в непонимании нахожусь... Мне кажется, что именно линкер должен получать и использовать used. Иначе я не вижу смысла в used. Поправьте, если я не прав.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 26 2007, 19:20
|

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

|
Цитата(Сергей Борщ @ Oct 26 2007, 15:22)  и там сказано просто: means that code must be emitted for the function even if it appears that the function is not referenced И тут нет деления на объектный/исполняемый код. Компилятор-то все равно в объектник складывает все, и используемое и нет. А уже линкер собирает только нужное. Вот я и в непонимании нахожусь... Ну вот прочтя это я и решил, что такуи used относится только к компиляции файла - будет сгенерировано и окажется в объектнике. А дальше как линкер на душу положит. Хотя сначала мне казалось, что должно бы и до линкера дойти. Но нет - так нет, что тут скажешь, способ нашёлся, и то хорошо. Хотя какой-нибудь __attribute__((force_linking)) не помешал бы  Цитата(Сергей Борщ @ Oct 26 2007, 15:22)  Иначе я не вижу смысла в used. Поправьте, если я не прав. Ну, как минимум один вариант использования я нашёл Код static void init(void) __attrinbte__((section(".init5"),naked,used)); static void init(void) { ... } Это инициализация модуля, которая линкуется автоматически, если модуль (файл) подключен - нет риска забыть в начале main() забыть вызвать какой-то из множества init - размещением в "правильной" секции можно обеспечить выполнение этой инициализации, например, до выполнения каких-либо конструкторов, или до инициализации .data/очистки .bss (если в init открывается доступ к памяти на внешней шине). Благодаря used помещается в объектный файл, иначе невызванная static-функиця удалится ещё компилятором. Т.е. used даёт возможность тут использовать static, благодаря чему спрятать эту точку входа от доступа снаружи.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Oct 28 2007, 21:14
|
Участник

Группа: Новичок
Сообщений: 16
Регистрация: 2-03-07
Из: Киев
Пользователь №: 25 818

|
Цитата(AndryG @ Oct 26 2007, 12:17)  Почитал я ваши посты ... и поник ... как просто было с CV ... а тут  У меня очень навороченный прект на CV (ATmega2561 + на параллельной шине ST16C554). Все работает как часы. Единственный смысл перехода на WINAVR вижу только в том, что он бесплатный. Не нужно каждый раз при появлении новых версий искать лекарство. В остольном CV рулит. Работаю с ним 3,5 года.
--------------------
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|