Перейти к содержанию
    

повозился вчера с makefile от компилятора ...

добавил в gcc -D__AVR_$(TARGET)__ -- теперь в коде можно вспоминать только хидер io.h , а "персональные" хидеры для контроллера теперь io.h вставит!

 

Люди, а не поделится ли кто описанием ключей запуска на winavr на русском языке?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

повозился вчера с makefile от компилятора ...

добавил в gcc -D__AVR_$(TARGET)__ -- теперь в коде можно вспоминать только хидер io.h , а "персональные" хидеры для контроллера теперь io.h вставит!

 

Люди, а не поделится ли кто описанием ключей запуска на winavr на русском языке?

По умолчанию TARGET задается в makefile и только там определяется.

Что понимается под ключами? Опции компилятора и линкера, так в makefile все определяется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня релиз апреля(вроде) 2006 года ... таргет определяется в makefile ... но если в исходник не ставить хидер конкретного чипа, то комилятор ругается, что не определен тип микроконтроллера ... после добавления вышеуказанного куска в makefile мы добавляем define, по котрому io.h вставит нужный хидер нужного контроллера.

 

Для многих это полная фигня, а для меня маленькая победа в освоении компилятора :-) вот и поделился радостью.

 

А ключи ... да я имел ввиду описание опций вызова компилятора и линкера. То что они определяются в makefile - это здорово, но все же они упоминаются в "базовом" makefile.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

повозился вчера с makefile от компилятора ...

добавил в gcc -D__AVR_$(TARGET)__ -- теперь в коде можно вспоминать только хидер io.h , а "персональные" хидеры для контроллера теперь io.h вставит!

 

Люди, а не поделится ли кто описанием ключей запуска на winavr на русском языке?

Что-то я спросонок не пойму... Если есть ключ, например, -mmcu=atmega88 то gcc сам порождает и нужный __AVR_ATmega88__, и по мере необходимости всякие __AVR_ENHANCED__, __AVR_HAVE_LPMX__ и т.п. Причём я не помню времён, когда этого не было, т.е. когда мне не хватало комбинации -mmcu и io.h

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хм! -mmcu вспоминается ... но почему ж тогда у меня ругается, что не определен контроллер ?

 

Будем колупать дальше ... спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По кр. мере в двух самых свежих сборках WinAVR --gc-sections работает, незадействованные функции успешно выбрасывает (соответственно при -fdata-sections будет должно вышвыривать глоблаьные и static-переменные, на которые нет ссылок).

Вероятно, заработало это где-то тогда, когда к обработчикам прерываний стали __attribute__((used)) цеплять.

Вчера и я попробовал. Действительно выбрасывает. Даже те функции, которые с __attribute__((used)) описал. даже без -ffunction-sections. Пробовал и 20060421 и 20070525. Что же делать? Есть у меня одна функция, которая из отдельно скомпилированного загрузчика вызывается. И вторая проблема: то же самое, но с данными. -fdata-sections выкидывает массив, который нужно зарезервировать для функции из области загрузчика, т.е. скомпилированной отдельным проектом. Несмотря на наличие __attribute__((used)). Как бороться? Заводить фиктивные указатели на эти функцию и массив не хочу - некрасиво это.

Еще один вопрос - как называется функция, с которой начинается выполнение (что в ENTRY() скрипта ld указывать)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вчера и я попробовал. Действительно выбрасывает. Даже те функции, которые с __attribute__((used)) описал. даже без -ffunction-sections. Пробовал и 20060421 и 20070525.

...

Заводить фиктивные указатели на эти функцию и массив не хочу - некрасиво это.

Мда. Мрак.

Бестолку фиктивный указатель... Сначала он выбрасывается "ввиду необращения", потом то, на что он указывал.

Кстати, я пробовал с 20070525 --gc-sections без -ffunction-sections ничего не выбрасывает.

А с -ffunction-sections - да, used не помогает. Почитал ещё - таки похоже used касается только компилятора и только на этапе компиляции файла. Линкеру никакой информации об этом аттрибуте не передаётся.

Пока нарыл только то, что невызываемая ниоткуда функция не выбрасывается, если передать линкеру ключик -u/--undefined

-Wl,-u,func_name

он применяется для принудительной линковки модуля из библиотеки по имени глобального символа, даже если на него нигде нет ссылки - эдакое ручное помещение символа в таблицу необходимых ссылок. Судя по описанию ключа - то же самое делается командой EXTERN в линкероном скрипте. После чего линкер считает это имя хоть кому-то да нужным и не выбрасывает по --gc-sections

 

Еще один вопрос - как называется функция, с которой начинается выполнение (что в ENTRY() скрипта ld указывать)?
В запускалке стандартной там вообще не функция, а идёт переход на weak метку __init, она в секции .init0, потом вслед за ней линкерным скриптом складываются секции вплоть до .init9, которая состоит из jmp main. А из init-секции в init-секцию переход не jmp/call, а просто "естественным путём".

Т.е. если у себя завести функцию с именем __init, то по нулевому адресу будет поставлен jump (а не call) на неё и вся цепочка - инициализация указателя стека, обнуление __zero_reg__, инициализация .data, зачистка .bss, конструкторы С++ - пойдут лесом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пока нарыл только то, что невызываемая ниоткуда функция не выбрасывается, если передать линкеру ключик -u/--undefined
Спасибо, использую. Непередача used линкеру - это как, бага или фича? Может надо сообщить авторам, чтоб поправили?
В запускалке стандартной там вообще не функция, а идёт переход на weak метку __init, она в секции .init0, потом вслед за ней линкерным скриптом складываются секции вплоть до .init9, которая состоит из jmp main. А из init-секции в init-секцию переход не jmp/call, а просто "естественным путём".
Т.е. ENTRY() не нужна? А по --gc-sections вся эта инициализация не выкинется однажды?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А по --gc-sections вся эта инициализация не выкинется однажды?

 

Не выкиниться, все стандартные имена (vectors, initX, и.т.д.) в ld скрипте начиня с версии binutils 2.17 помпомечены атрибутом KEEP (...).

 

В версии 2.16 (WinAVR-2006..) еще не помечены, и по этой причине опции "-ffunction-sections" и "-fdata-sections" не работают.

 

Анатолий.

Изменено пользователем aesok

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не выкиниться, все стандартные имена (vectors, initX, и.т.д.) в ld скрипте начиня с версии binutils 2.17 помпомечены атрибутом KEEP (...).
Вот оно! Я клал свою функцию и массив в отдельные секции принудительно. Сделал в скрипте этим секциям KEEP() и все получилось. Спасибо!!! Остался открытым вопрос - то, что компилятор не передает линкеру атрибут used - это бага или так и должно быть?

 

Почитал я ваши посты ... и поник ... как просто было с CV ... а тут :(
Сложности возникают при попытке сделать что-то нетривиальное - "чесать левое ухо правой ногой". Поверьте, я писал аналогичную программу в CV - знали бы вы сколько времени было потрачено, чтобы заставить его разместить ту самую функцию и тот самый массив по нужным мне адресам, и через какую ж.. это в конце-концов получилось реализовать. Так что зря пугаетесть - с WinAVR у вас могут быть трудности в начале, зато потом гладкий полет, с CV будете иметь с точностью до наоборот - сначала легкий старт, потом какое-то время полет, потом большие трудности (если, конечно, ваши программы будут развиваться).

После того, как подружили WinAVR и AVRStudio проблем с WinAVR нет даже в начале. В этой связке сложности начнутся, если захотите использовать С++. Плагин пока почему-то не позволяет подключать плюсовые файлы. Но есть альтернатива в виде Eclipse - как среда разработки гораздо удобнее студии, студию можно пользовать только как симулятор.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот оно! Я клал свою функцию и массив в отдельные секции принудительно. Сделал в скрипте этим секциям KEEP() и все получилось. Спасибо!!! Остался открытым вопрос - то, что компилятор не передает линкеру атрибут used - это бага или так и должно быть?

 

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

 

Анатолий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из описания атрибута used следует что код функции должен быть в объектном файле, но ничего не говориться о том должен ли линкер добавить секцию где находиться этот код в исполняемый файл.
Честно говоря я описание аттрибутов читаю здесь и там сказано просто:
means that code must be emitted for the function even if it appears that the function is not referenced
И тут нет деления на объектный/исполняемый код. Компилятор-то все равно в объектник складывает все, и используемое и нет. А уже линкер собирает только нужное. Вот я и в непонимании нахожусь... Мне кажется, что именно линкер должен получать и использовать used. Иначе я не вижу смысла в used. Поправьте, если я не прав.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и там сказано просто:

means that code must be emitted for the function even if it appears that the function is not referenced

И тут нет деления на объектный/исполняемый код. Компилятор-то все равно в объектник складывает все, и используемое и нет. А уже линкер собирает только нужное. Вот я и в непонимании нахожусь...

Ну вот прочтя это я и решил, что такуи used относится только к компиляции файла - будет сгенерировано и окажется в объектнике. А дальше как линкер на душу положит. Хотя сначала мне казалось, что должно бы и до линкера дойти. Но нет - так нет, что тут скажешь, способ нашёлся, и то хорошо. Хотя какой-нибудь __attribute__((force_linking)) не помешал бы :)

 

Иначе я не вижу смысла в used. Поправьте, если я не прав.
Ну, как минимум один вариант использования я нашёл
static void init(void) __attrinbte__((section(".init5"),naked,used));
static void init(void)
{
   ...
}

Это инициализация модуля, которая линкуется автоматически, если модуль (файл) подключен

- нет риска забыть в начале main() забыть вызвать какой-то из множества init

- размещением в "правильной" секции можно обеспечить выполнение этой инициализации, например, до выполнения каких-либо конструкторов, или до инициализации .data/очистки .bss (если в init открывается доступ к памяти на внешней шине).

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почитал я ваши посты ... и поник ... как просто было с CV ... а тут :(

У меня очень навороченный прект на CV (ATmega2561 + на параллельной шине ST16C554). Все работает как часы. Единственный смысл перехода на WINAVR вижу только в том, что он бесплатный. Не нужно каждый раз при появлении новых версий искать лекарство. В остольном CV рулит. Работаю с ним 3,5 года.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...