Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WinAVR - как оно?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Evgeny_CD
Задумал я тут тулзы унифицировать окончательно. И понял, что альтернативы GNU / GCC нет - ибо, например, покупку IAR, считаю бессмысленной. Я просто понял, что оптимизация кода головой программера (и инвестирование денег в этого программера, и стимулирование оного (сделал хорошо - получи премию), разумеется, вздрачивание - куда же без него) дает больший эффект, чем выигрыш самого лучшего компилятора.

Что касается среды - http://www.eclipse.org/ ок.

С Армами все понятно. Там GCC рулит. Сами проверяли, инфы есть много на эту тему.

Но вот для AVR (иногда надо делать "контроллеры светодиодов" за 1.5$) никогда не пробовал subj. Каково мнение народа?

http://winavr.sourceforge.net/
pulsar-17
Мнение хорошее.
Компилятор делает хороший код, но иногда надо ему "помогать", писать исходник разбиваая сложные расчеты на несколько простых, явно перобразовывать типы (особенно char), учитывать, что AVR восьмиразрядный и лишние операции ненужны(по умолчанию int 16 бит). Причуды тоже есть, например иногда два ret в конце функции ставит... Но это компенсируется большим количеством всевозможных чисто GNUшных фич, морем всевозможных утилит, библиотек и хорошей документацией на все это.
ReAl
Цитата(Evgeny_CD @ Jul 29 2005, 13:47)
Задумал я тут тулзы унифицировать окончательно. И понял, что альтернативы GNU / GCC нет - ибо, например, покупку IAR, считаю бессмысленной. Я просто понял, что оптимизация кода головой программера (и инвестирование денег в этого программера, и стимулирование оного (сделал хорошо - получи премию), разумеется, вздрачивание - куда же без него) дает больший эффект, чем выигрыш самого лучшего компилятора.

Ага. Ковырялся недано в одних примерах к платке, поставляемых изготовителем. Скомпилировал, работает, пора рабочую программу писать, но... Не могу на те исходники смотреть, сердце кровью обливается.
Слегка прошёлся - и выглядеть стали "читабельнее", и объём загрузочного файла сократился с 6 до 5.5К. Это при том, что там ещё куча строк для выдачи на отладочный терминал.

Цитата(Evgeny_CD @ Jul 29 2005, 13:47)
Но вот для AVR (иногда надо делать "контроллеры светодиодов" за 1.5$) никогда не пробовал subj. Каково мнение народа?

http://winavr.sourceforge.net/
*

Несколько лет только им и пользуюсь. Проигрывает ИАР-у по объёму кода где-то на 5--20% в зависимости от задачи, стиля, ... (хотя последняя пара, которую сравнивал - что-то типа gcc 3.0.2 и иар 2.27).
impatt
avr-gcc штука классная, причём не надо тырить у IAR ничего, и никаких лекарств от запоров - тоже не надо. Что мне не понравилось - в коде обработчика прерывания GCC разрешает эти самые прерывания. Ну, ладно бы отключаемая функция была... А то код получается не совсем совместимый с проектами под, например, IAR. Пример: обработчик прерывания по достижению некоего числа таймером №1. Один чел написал код на IAR для реализации ШИМ, и сперва разрешил прерывания, а потом взялся настраивать таймер. Когда в обработчике прерывания не разрешены (IAR), то ничего страшного не происходит, а вот под GCC.. Контроллер уходил в обработчик немедленно после старта, потом входил повторно и так до упора, пока не переполнится стек, а потом вис нахрен. Ессно, расхваливаемый многими симулятор на AVRStudio работает криво (как мне показалось) и пришлось голову поломать, чтобы оживить ранее работоспособный проектик..
sensor_ua
Вот пробую под eclipse AVR-GCC4.0.2 сборки klen.org. Об эффективности пока сказать не могу, но уже приятно, что как-то работаетwink.gif
misyachniy
impatt
В GCC есть SIGNAL () и INTERRUPT().
Разница между ними в наличии команды sei() в INTERRUPT().
impatt
Цитата(misyachniy @ Jan 13 2006, 18:12) *
impatt
В GCC есть SIGNAL () и INTERRUPT().
Разница между ними в наличии команды sei() в INTERRUPT().


Спасибо, не знал. Теперь узнал и вздохнул с облегчением (я не шучу). Пользуюсь.
Уверен, что всё это описано в доке, но там всё на чисто англицком языке. Ессно, когда читаешь одно слово через три, пропустить немудрено.
Ещё раз благодарю.
m16
Цитата([banned] @ May 17 2006, 10:17) *
Цитата(pulsar-17 @ Jul 29 2005, 17:56) *

Мнение хорошее.

но иногда надо ему "помогать"


если вы не хотите помогать компилятору, а наоборот ожидаете от него помощи то возьмите на [banned] - великолепный компилятор - программатор CodeVisionAVR (2Мб всего !) и дополните его бесплатным симулятором VMLAB (4Мб)

и просто насладитесь работой! вот примеры http://electronix.ru/redirect.php?http://[banned]/avrpic06.htm

Уважаемый, все Ваши полсотни постов как близнецы-братья содержимое которых сводится к одному - раскрутке собственного сайта но никак по сути поставленного вопроса , имхо
beer_warrior
Пользуюсь с 2003 года.Жалоб нет.
Надо немножко приноровиться (например как с SIGNAL/INTERRUPT),
требует определенной дисциплины мышления, (как с приведением типов, но это на мой взгляд это к лучшему), зато потом все идет как по маслу.
По оптимизации - местами проигрывает IAR, местами выигрывает.
haker_fox
Цитата([banned] @ May 17 2006, 15:17) *
Цитата(pulsar-17 @ Jul 29 2005, 17:56) *

Мнение хорошее.

но иногда надо ему "помогать"


если вы не хотите помогать компилятору, а наоборот ожидаете от него помощи то возьмите на [banned] - великолепный компилятор - программатор CodeVisionAVR (2Мб всего !) и дополните его бесплатным симулятором VMLAB (4Мб)

и просто насладитесь работой! вот примеры http://electronix.ru/redirect.php?http://[banned]/avrpic06.htm


bb-offtopic.gif Я использовал CodeVision. Да, неплохой компилятор. Как и все остальные. Но ничего особо замечательного я в нем не ощутил. Помощи он мне тоже ни какой не дал, что же можно от него ожидать, это ведь просто программа. Многим нравиться этот инструмент тем, что он поставляется с библиотеками для работы с ds18b20, hd44780 и другими приборами. Но мне, например, кажется что ничего особенного в этом нет. Еще не известно как написаны эти библиотеки. Да и лучше такие вещи, даже на начальных порах писать самому, потому что это повышает Level-up.
Симуляторы, такие, как VMLab & Proteus можно конечно использовать, но не стоит им полностью доверять. Все таки симулятор он и есть симулятор.
halfdoom
Цитата(Evgeny_CD @ Jul 29 2005, 13:47) *
И понял, что альтернативы GNU / GCC нет - ибо, например, покупку IAR, считаю бессмысленной.Но вот для AVR (иногда надо делать "контроллеры светодиодов" за 1.5$) никогда не пробовал subj. Каково мнение народа?

Тут все просто - если памяти программ в избытке, и можно поступиться быстродействием, то GCC это
хороший выбор. ИАР выигрывает у GCC по всяким мелким оптимизациям (исключение лиших загрузок
регистров, использование X и Z регистров для доступа к памяти даже без явного описания указателей
в программе) и наличием cross-call оптимизации.

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

BTW, я также отказался от использования make и перешел на jam. С использванием средств jam'a можно писать
такие вещи:
Код
rule target_gcc161 {
    tool_gcc;

    MCU_FULL =    atmega161;
    MCU_PROGR =    Mega161;
    MCU_SHORT =    m161;

    CCOPT_TYPE    = speed;
    CCOPT_LEVEL    = 2;
....
}

rule target_iar161 {
    tool_iar;

    MCU_FULL =    AT90Mega161;
    MCU_PROGR =    Mega161;
    MCU_SHORT =    m161;

    CCOPT_TYPE    = speed;
    CCOPT_LEVEL    = 9;

    CCFLAGS += --do_cross_call  --cross_call_passes=5;
}

А затем просто указывать "jam iar161" или "jam gcc161".
Laksus
Цитата
misyachniy
Jan 13 2006, 18:12
impatt
В GCC есть SIGNAL () и INTERRUPT().
Разница между ними в наличии команды sei() в INTERRUPT().

____________________________________________________________
Цитата
impatt
...Уверен, что всё это описано в доке,...

____________________________________________________________
____________________________________________________________
Функции обработки прерываний SIGNAL() & INTERRUPT()
были до версии WinAVR-20050214-install.exe
прописаны в
...\WinAVR\avr\include\avr\signal.h
и описаны в
...\WinAVR\doc\avr-libcavr-libc-user-manual-1.2.3.pdf
_________
Но с версии WinAVR-20060125-install.exe
в
...\WinAVR\doc\avr-libc\avr-libc-user-manual-1.4.3.pdf
функция INTERRUPT() объявлена deprecated (осуждаемой)
и в файлах не прописана. Дескать, (стр.45...-1.4.3.pdf)
"As this macro has been used by too many unsuspecting people in the past, it has been
deprecated, and will be removed in a future version of the library. Users who want to
legitimately re-enable interrupts in their interrupt handlers as quickly as possible are
encouraged to explicitly declare their handlers as described above."
"above" - это ссылка на стр.128., где разъясняется как сделать
вложенные прерывания.
_________________
Александр
2006 05 27
msn
Пользуюсь больше 4-х лет. Особых замечаний не было. После того как добавили поддержку в студии работать стало еще приятнее, про IAR который изредка использовался для откладки кусков кода уже забыл. Есть правда пара мелких недочетов: от версии к версии иногда меняются различные часто используемые макросы, переезжают в другое место файлы заголовков, до сих пор нет нормально реализованной printf, иногда не хватает поддержки С++ и не очень удобно размещать массивы строк в Flash. Оптимизации маленьких кодов очень уступает IAR, проврете на замене местами байт в слове.
msn
Пользуюсь больше 4-х лет. Особых замечаний не было. После того как добавили поддержку в студии работать стало еще приятнее, про IAR который изредка использовался для откладки кусков кода уже забыл. Есть правда пара мелких недочетов: от версии к версии иногда меняются различные часто используемые макросы, переезжают в другое место файлы заголовков, до сих пор нет нормально реализованной printf, иногда не хватает поддержки С++ и не очень удобно размещать массивы строк в Flash. Оптимизации маленьких кодов очень уступает IAR, проврете на замене местами байт в слове.
SasaVitebsk
Цитата(halfdoom @ May 18 2006, 12:40) *
Цитата(Evgeny_CD @ Jul 29 2005, 13:47) *

И понял, что альтернативы GNU / GCC нет - ибо, например, покупку IAR, считаю бессмысленной.Но вот для AVR (иногда надо делать "контроллеры светодиодов" за 1.5$) никогда не пробовал subj. Каково мнение народа?

Тут все просто - если памяти программ в избытке, и можно поступиться быстродействием, то GCC это
хороший выбор. ИАР выигрывает у GCC по всяким мелким оптимизациям (исключение лиших загрузок
регистров, использование X и Z регистров для доступа к памяти даже без явного описания указателей
в программе) и наличием cross-call оптимизации.

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

BTW, я также отказался от использования make и перешел на jam. С использванием средств jam'a можно писать
такие вещи:
Код
rule target_gcc161 {
    tool_gcc;

    MCU_FULL =    atmega161;
    MCU_PROGR =    Mega161;
    MCU_SHORT =    m161;

    CCOPT_TYPE    = speed;
    CCOPT_LEVEL    = 2;
....
}

rule target_iar161 {
    tool_iar;

    MCU_FULL =    AT90Mega161;
    MCU_PROGR =    Mega161;
    MCU_SHORT =    m161;

    CCOPT_TYPE    = speed;
    CCOPT_LEVEL    = 9;

    CCFLAGS += --do_cross_call  --cross_call_passes=5;
}

А затем просто указывать "jam iar161" или "jam gcc161".


Вот бы поделился! smile.gif
Я думаю масса людей было бы Вам благодарна.
Я пока не нахожу в себе сил такую работу проделать. smile.gif
Ну и описаний не достаточно. Как-то они разбросаны и беспорядочны.
SpiritDance
А собственнно в чем вопрос у автора, если альтернативы gcc как многгоплатформенному компилятору особой нет? Знаю что компилятор реально хороший, под AVR проигрывает только IAR. Но есть некоторые мелкие особенности использования gcc в целом:
1 некоторые версии могут быть глючными даже при том что получили стабильный номер.
2 старшие версии могут в некоторых моментах быть не совместимыми с предыдущими, причем это как правило не документируется, так как создатели такие моменты просто могут упустить из вида.
3 существует обилие документации но вся она бестолковая, создается впечатление вороха бумажек вместо прошитых и разложенных по папкам документов
4 своеобразный синтаксис асм, берущий начало от AT&T, хотя многим нравится, я лично тоже не против.
klen
Вставлю вой пятачек с двумя дырачкамиsmile.gif

как выразились многие коллеги выше - компиллер это ИНСТУМЕНТ!, поэтому его надо выбирать исходя из постоновки задачи, и я сними глубоко уважаемо согласен. Это Раз. С другой стороны человек не конечнй автомат с известным числом состояний, поэтому компиллер (то есть друга) нада выбирать по любви и убеждению, чтобы "вместе прошивку делать", раскрыть так сказать потенциал!! Это как минимум два.
Я привел довольно общие два критерия выбора. На самом деле их мильон!!! Лично для меня вопрос заданный автором аналогичен вопросу "А тебе какие нравятся больше,черненькие или светленткие? Мне? Мне больше нравятся полненькие!!"

Философская тема однако smile.gif
aesok
Цитата(msn @ May 27 2006, 02:10) *
.... до сих пор нет нормально реализованной printf, ...


Что вам не хватает в 'printf', можно подробнее?
msn
Цитата([banned] @ May 27 2006, 09:21) *
Цитата(msn @ May 27 2006, 03:10) *

Пользуюсь больше 4-х лет.

до сих пор нет нормально реализованной printf


ну если ОНА так нужна то можно было уж свою написать и поделится с общественностью !

В большинстве случаев так и есть использую, свои функции из разряда print_num, print_hex, print _str, print _pstr и т.д. Но когда переносишь часть кодов, например, с какого ни будь 8051 для которого обычно пишу в Keil (там printf на мой взгляд очень хорошо сделано) то довольно таки накладно менять. Еще printf очень удобно пользоваться софте содержащим очень много разнородных сообщений для работы с пользователем, у меня это промышленные контролеры, где по объему эти сообщения / меню / разнообразная информация и т.д. занимают, чуть ли не половину места программы.
Свою не писал, не вижу смысла, использую уже написанные до меня (в инете их превеликое множество), допустим из Procyon AVRlib.


Цитата(aesok @ May 27 2006, 21:33) *
Цитата(msn @ May 27 2006, 02:10) *

.... до сих пор нет нормально реализованной printf, ...


Что вам не хватает в 'printf', можно подробнее?

Во первых первое что попадается на глаза при прочтении мануала Standard IO facilities:
Warning:
This implementation of the standard IO facilities is new to avr-libc. It is not yet expected to remain stable, so some aspects of the API might change in a future release.
Уже настораживает.

Когда то писал софт на 8515 (простенький диспетчерский контролер, задачей которого было прослушивание линии вывод разных сообщений и в нагрузку управлении нескольким дискретными входами / выходами), так вот из 8 КБ код и вызовы printf сожрали почти 6,5 КБ, т.е. больше 80 %. Частично посмотрел в дебугере реализацию самой функции и ее вызовом особенно где было несколько параметров (в основном целы числа, строки и символы) сложилось такое впечатление что ни кто ни чего не оптимизировал.
_4afc_
Я тоже пользуюсь только им, но раньше ( а скорее всего и сейчас) у него была одна особенность - он хранил все данные в RAM перенося их туда из FLASH в начальном коде. Раньше можно было только строки (char) хранить во FLASH. Причём в принципе заставить хранить там данные можно, а вот заставить взять средствами си - не получалось, он не использовал код LPM и брал соответственно значение из RAM.

При изменении переменных из прерываний не забывайте про volatile.

Ну и вообще прерывания лучше на ассемблере писать, а то слишком много ресурсов съедает.

(Пример - обработка внешнего последовательного АЦП на си потребовала бы поставить Atmega48 на 80МГц, периписав код на асм с разделением регистров - уложился в 10 wink.gif
msn
Цитата(_4afc_ @ May 29 2006, 15:54) *
Я тоже пользуюсь только им, но раньше ( а скорее всего и сейчас) у него была одна особенность - он хранил все данные в RAM перенося их туда из FLASH в начальном коде. Раньше можно было только строки (char) хранить во FLASH. Причём в принципе заставить хранить там данные можно, а вот заставить взять средствами си - не получалось, он не использовал код LPM и брал соответственно значение из RAM.

Сейчас вроде все нормально:
Код
prog_char ansi_rus[64]={0x41,0xa0,0x42,0xa1,0xe0,0x45,0xa3,0xa4,    // Таблица перекодировки таблицы ЖКИ в соответствии с таблицей ANSI
...
                        0xc1,0xe6,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7};

...

void print_char(u8_t ch)
{
if (lcd_x>(LCD_COLUMN-1) || lcd_y>(LCD_ROW-1)) {return;}   // Если за пределами ЖКИ
if (ch>=0xc0 && !fl_no_use_ansi_rus) {ch=pgm_read_byte(&ansi_rus[ch-0xc0]);}
lcd_wr_data(ch);                                           // Вывести символ по текущим координатам
lcd_x++;                                                   // Передвигаемся на следующие знакоместо
}


Или

Код
const char txtErrorMaster__0[] PROGMEM = "  Исход. состояние  ";// 0 Текстовое представлениие произошедшей аврии / предупреждения
const char txtErrorMaster__1[] PROGMEM = "   Отказ модуля 1   ";// 1
const char txtErrorMaster__2[] PROGMEM = "   Отказ модуля 2   ";// 2
....

PGM_P txtErorrMaster[] = {txtErrorMaster__0,                    // Буфер для поиндексного доступа
                          txtErrorMaster__1,
                          txtErrorMaster__2,
....
};

....


void print_str(PGM_P addr)
{
u8_t ch;
while ((ch=pgm_read_byte(addr++))) {print_char(ch);}
}
beer_warrior
Цитата
Причём в принципе заставить хранить там данные можно, а вот заставить взять средствами си - не получалось, он не использовал код LPM и брал соответственно значение из RAM.


Да, к сожалению, невозможность легко манипулировать данными из флэш
было и остается самым серьезным недостатком avr-gcc.
Здесь ИАР рулит однозначно.
Postoroniy_V
Цитата(msn @ May 29 2006, 02:18) *
В большинстве случаев так и есть использую, свои функции из разряда print_num, print_hex, print _str, print _pstr и т.д. Но когда переносишь часть кодов, например, с какого ни будь 8051 для которого обычно пишу в Keil (там printf на мой взгляд очень хорошо сделано) то довольно таки накладно менять. Еще printf очень удобно пользоваться софте содержащим очень много разнородных сообщений для работы с пользователем, у меня это промышленные контролеры, где по объему эти сообщения / меню / разнообразная информация и т.д. занимают, чуть ли не половину места программы.
Свою не писал, не вижу смысла, использую уже написанные до меня (в инете их превеликое множество), допустим из Procyon AVRlib.

тоесть вы хотите сказать что в WInAvr не реализованы аналоги ваших -
print_hex,print_num,print _str,print _pstr посредством родного (winavr) PRINTF?
или то что они жрут много?
defunct
bb-offtopic.gif

Цитата(_4afc_ @ May 29 2006, 15:54) *
Ну и вообще прерывания лучше на ассемблере писать, а то слишком много ресурсов съедает.

(Пример - обработка внешнего последовательного АЦП на си потребовала бы поставить Atmega48 на 80МГц, периписав код на асм с разделением регистров - уложился в 10 wink.gif

Не убедительно ;>
В таком случае лучше вообще все писать на асм..

Не вижу смысла писать на Си под чипы у которых меньше 16k Flash..
Не исключено, что программа которая у Вас выполняется на m48, будучи полностью переписана на asm (и с условием наличия требуемых пинов) с успехом разместилась бы в t13.

ps: Пример - IP стек на ассемблере, чудно влез в m48 вместе с программой решающей прикладную задачу и пакетным драйвером PHY/MAC контроллера, еще 2kb флеша осталось (при этом на 20Mhz помимо выполнения основной задачи и общения с сервером по TCP обеспечивается еще и стабильный отклик 1ms на несколько десятков потоков ping'a с пакетами (ICMP) по 256 байт). Для решения этой же задачи на Си потребовался бы ARM ;>
aesok
Цитата(msn @ May 29 2006, 01:18) *
Во первых первое что попадается на глаза при прочтении мануала Standard IO facilities:
Warning:
This implementation of the standard IO facilities is new to avr-libc. It is not yet expected to remain stable, so some aspects of the API might change in a future release.
Уже настораживает.


printf - Это стандартная функция и она не будет изменяться.

Что касается функций открытия/закрытия потоков, то эти изменения уже произошли в avr-libc версии 1.4. В версии 1.2 была функция 'fdevopen' которая использовала динамическое выделение памяти (malloc()), в версии 1.4 этой функции нет.

Цитата(msn @ May 29 2006, 01:18) *
Когда то писал софт на 8515 (простенький диспетчерский контролер, задачей которого было прослушивание линии вывод разных сообщений и в нагрузку управлении нескольким дискретными входами / выходами), так вот из 8 КБ код и вызовы printf сожрали почти 6,5 КБ, т.е. больше 80 %.


Скорее всего это произошло из за того, что вы использовали полную версию 'printf' с поддержкой чисел с плавающей точкой. О разных вариантах функции 'printf', а точнее 'vfprintf', посмотрите описание 'vfprintf'. Если вам не нужны числа с плавающей точкой используйте стандартную версию функции 'vfprintf'.

Код
#include <stdio.h>

int
uart_putchar(char c, FILE *stream)
{
    return 0;
}


FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);

int main()
{      
    stdout = &uart_str;
    printf("test");
    
    return 0;

}


Размер кода для этой программы при использовании стандартной версии 'vfprintf' равен примерно 1.8KB, при использовании полной версии (с плавающей точкой) примерно 4,5KB. Конечно не бесплатно .....


Цитата(msn @ May 29 2006, 01:18) *
Частично посмотрел в дебугере реализацию самой функции и ее вызовом особенно где было несколько параметров (в основном целы числа, строки и символы) сложилось такое впечатление что ни кто ни чего не оптимизировал.


'vfprintf' написанна на С, пока не нашлось героя переписать ее на асме. smile.gif

Анатолий.
beer_warrior
Цитата
Скорее всего это произошло из за того, что вы использовали полную версию 'printf' с поддержкой чисел с плавающей точкой.

BTW в makefile который генерирует mfile присутствуют специальные опциии линкера для printf и scanf *_LIB_MIN и *_LIB_FLOAT.

Цитата
'vfprintf' написанна на С, пока не нашлось героя переписать ее на асме. smile.gif

А никто не пробовал играться с С++ и его перегружаемыми cin/cout?
sff
Я WinAVR использую года 2 и за это время сложилось достаточно положительное впечатление, но не без причуд. Похоже на уровне оптимизации WinAVR "не знает" что регистры 8 разрядные (разработчики портировали с другой архитектуры без существенной переработки, это моё личное мнение)

Например возьмём убогий пример, и откоипилируем с опцией -O2, компилятор последний офиц WinAVR (а по сути здесь и не важно)
Код
uint8_t get_small_val()
{
    return 0x8;
}
uint32_t test(uint32_t val)
{
    uint8_t tmp = get_small_val();
    val += (uint16_t)tmp << 8;
    return val;
}


то получим
Код
00000284 <get_small_val>:
     284:    88 e0           ldi    r24, 0x08; 8
     286:    90 e0           ldi    r25, 0x00; 0
     288:    08 95           ret

0000028a <test>:
     28a:    ef 92           push    r14
     28c:    ff 92           push    r15
     28e:    0f 93           push    r16
     290:    1f 93           push    r17
     292:    7b 01           movw    r14, r22
     294:    8c 01           movw    r16, r24
     296:    f6 df           rcall    .-20     ; 0x284 <get_small_val>
     298:    99 27           eor    r25, r25
     29a:    98 2f           mov    r25, r24
     29c:    88 27           eor    r24, r24
     29e:    aa 27           eor    r26, r26
     2a0:    bb 27           eor    r27, r27
     2a2:    8e 0d           add    r24, r14
     2a4:    9f 1d           adc    r25, r15
     2a6:    a0 1f           adc    r26, r16
     2a8:    b1 1f           adc    r27, r17
     2aa:    bc 01           movw    r22, r24
     2ac:    cd 01           movw    r24, r26
     2ae:    1f 91           pop    r17
     2b0:    0f 91           pop    r16
     2b2:    ff 90           pop    r15
     2b4:    ef 90           pop    r14
     2b6:    08 95           ret


Во-первых функции которые возвращают uint8_t расширяются до int (строчка 286), причём как я смотрел совершенно не зависит от опций оптимизаций, конечно есть волшеьная опция -mint8 которая заставляет int принимать 8 бит, но при этом разработчики не гарантируют что все проекты откомпилируются с данной опцией.

Во-вторых по согласованию распределения регистров с переменными, есть 3 типа, в стандартном, бедет всегда такая картина при передаче и возврашение 32 битного числа (292-294, 2aa-2ac). Причем если активно использовать 32 битные типы (да понимаю AVR не затачивался под 32) то таких констукций будет много. Причем нам явно младший байт после сдвига tmp прибавлять не надо, это очевидно. Но GCC этого "не прнимает". Причем если не написать (uint16_t) перед опеорацией сдвига, то компилятор расширит uint8_t до int, а int знаковое, и после сдвига явно сбросит 7 бит, чтобы расширение произошло "корректно".

Есть ещё моного тонкостей на которые я наткнулся...
Но вот если в проекте на так много 32битных вычисление то GCC может очень изащренно оптимизировать код, бывало когда я смотрел дамп аж сам биву давался как он налавкачел.. =)

Ещё один огромнейший и неоспоримый плюс GCC это ассемблерные вставки. В них можно написать что-то типа макроса и компилятор будет сам выбирать какие регистры ему в конкретном случае лучше использовать (применительно к inline конструкциям)

Код
    __asm__ __volatile__ (    
        "ldd %0, Z+14"            "\r\n"
        "andi %0, 0x8C"            "\r\n"
        "lsr %0"                "\r\n"        
        "mov __tmp_reg__, %0"    "\r\n"
        "lsr %0"                "\r\n"
        "swap __tmp_reg__"        "\r\n"
        "or %0, __tmp_reg__"    "\r\n"        
    : "=r" (resp)
    : "z" (data)
    );

Вместо %0, в котором размещается resp, компилятор сам подставит необхолимые регистр, далее указываем компилятору чтобы в Z было data. Если бы в констукции использовался явно какой-то регистр (например после mul) то его нужно было бы включить в список экранируемых регистров ( : "r1" , после : "z" (data) ). При это генерируемы код, если правильно составить макрос булет 100% безопасным.
Тема написания вставок вообще очень интересная, думаю общий обзор дал..

Я использую WinAVR на всех проектах с AVR, а где код сильно тормозил, использовую вставочку =)
msn
Цитата(Postoroniy_V @ May 29 2006, 16:54) *
тоесть вы хотите сказать что в WInAvr не реализованы аналоги ваших -
print_hex,print_num,print _str,print _pstr посредством родного (winavr) PRINTF?
или то что они жрут много?

Много жрут.

Цитата(aesok @ May 29 2006, 17:27) *
Скорее всего это произошло из за того, что вы использовали полную версию 'printf' с поддержкой чисел с плавающей точкой. О разных вариантах функции 'printf', а точнее 'vfprintf', посмотрите описание 'vfprintf'. Если вам не нужны числа с плавающей точкой используйте стандартную версию функции 'vfprintf'.

Так и есть мне нужно было просчитывать несколько значений вытянутых из линии, результатом были числа с плавающей точкой (нужно было квадратный корень вычислять и выводить результат с точностью до 3 знаков после запятой). Все написал в лоб, без оптимизации.
pitt
"Но вот для AVR (иногда надо делать "контроллеры светодиодов" за 1.5$)"
Если время разработки дорого, а проект достатчно маленький и не сильно сложный CVAVR за 150 евро самое как раз. А вообще, если программирует электрик, то лучшего выбора не будет. Для профессионального программера - WINAVR очевидно лучше.
GetSmart
Неужто лучше ImageCraft ?
klen
Цитата(GetSmart @ Jun 2 2006, 04:51) *
Неужто лучше ImageCraft ?

Могу обосновать smile.gif
halfdoom
Цитата(SasaVitebsk @ May 27 2006, 16:59) *
Вот бы поделился! smile.gif
Я думаю масса людей было бы Вам благодарна.
Я пока не нахожу в себе сил такую работу проделать. smile.gif
Ну и описаний не достаточно. Как-то они разбросаны и беспорядочны.

В принципе можно, немного причесать только. Скоро не обещаю, но попробую.
_4afc_
Цитата(defunct @ May 29 2006, 18:10) *
Цитата(_4afc_ @ May 29 2006, 15:54) *

Ну и вообще прерывания лучше на ассемблере писать, а то слишком много ресурсов съедает.

Не убедительно ;>
В таком случае лучше вообще все писать на асм..


Я так и сделал. Просто компилируется всё данным пакетом (WinAVR).
В прерываниях я имел в виду, что при входе там несколько регистров суются в стэк.
Я же выделил несколько регистров для прерываний и в одном из них хранил регистр флагов.
Это ускоряет начало работы вашего обработчика.

Больше всего мешает тормознутость самой A48 - посылки SPI выполняются с ощутимой задержкой.

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

CVAVR- не удобен своим визардом, в частности в визарде делители для таймеров ограничены.
Кроме того для A128 генерился код, который не работал сразу (пара регистров не инитилась).

ImageCraft - очень близок к WinAVR, но я замучился ставить каждое действие в скобки и постоянно преобразовывать типы перенося рабочий проект из WinAVR в ImageCraft. Читаемость текста пропала абсолютно.
Цитата
Я WinAVR использую года 2 и за это время сложилось достаточно положительное впечатление, но не без причуд. Похоже на уровне оптимизации WinAVR "не знает" что регистры 8 разрядные (разработчики портировали с другой архитектуры без существенной переработки, это моё личное мнение)

полностью согласен, отсюда и страсть к перенисению всех данных в озу.
pitt
Самый сер'езный нрдостаток AVRGCC, с моей точки зрения, отсутствие прагмы управления оптимизацией.
Разделение проекта на файлы с различной оптимизацией не решает задачи:возникает проблема с видимостью. Кроме того, хотя можно смириться, makefile в таком случае становится кошмаром.
beer_warrior
Цитата
отсутствие прагмы управления оптимизацией.

А зачем?
Цитата
Кроме того, хотя можно смириться, makefile в таком случае становится кошмаром.

Если это действительно нужно, пишется makefile не настолько навороченный универсальный как в mfile, а обычный с явно указанными ключами компилятора к каждому файлу и все дела.

ИМХО вся прелесть makefile - возможность накрутить такой режим компиляции, который ни одной IDE не под силу.
WHALE
Цитата(_4afc_ @ Jun 2 2006, 13:45) *
Больше всего мешает тормознутость самой A48 - посылки SPI выполняются с ощутимой задержкой.

CVAVR- не удобен своим визардом, в частности в визарде делители для таймеров ограничены.
Кроме того для A128 генерился код, который не работал сразу (пара регистров не инитилась).

Можно пару вопросов?
А как вы меряли задержку посылки SPI-тестовой прогой в цикле-загрузка данных-дернуть пин.И как частотомером в интервальном режиме или осцилом с внешней синхронизацией?
И вывод по поллингу или по прерываниям?
И сколько тактов получилась задержка?
А насчет кодвижина вы попали пальцем в небо cranky.gif В визарде устнавливаются все разряды прескалера,и насчет меги128-у меня сейчас на столе девайс лежит-все путем,в стартап не лазил.
С какими регистрами проблема-то была?
pitt
Цитата(beer_warrior @ Jun 2 2006, 08:10) *
Цитата
отсутствие прагмы управления оптимизацией.

А зачем?

Это примерно тоже самое как и иностранный язык! Не понимаю ну и зачем?!
Есть такое понятие как инкапсуляция. Чтобы какая-нибудь переменная была видима только в одном файле ее делают static. Теперь представем себе, что она нам необходима в нескольких местах, которые хотелось бы оптимизировать по-разному, но переменная-то static...
IAR, как наиболее профессиональный компилятор эту прагму поддерживает.
beer_warrior
Цитата
Теперь представем себе, что она нам необходима в нескольких местах, которые хотелось бы оптимизировать по-разному

Вот этого то и не понимаю, код или отпимизируеться или нет.
Зачем это нужно с отдельно взятыми модулями? Все равно оно все ляжет в один бинарник. Тем более как сделать это я показал.
pitt
Цитата(beer_warrior @ Jun 2 2006, 09:07) *
Вот этого то и не понимаю.

А вот тут, извините, помочь не смогу...
pitt
avrfreaks
Igor_U
Помогите разобраться. Не собирается проект. Линковщик ругается, что не определить ссылку. Вот что пытаюсь собрать:

main.cpp
Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include "clDS1820.h"

int main(void)
{
clDS1820<4> dd;
volatile uint8_t d=dd.Finish();
for(;;);
return (0);
};


clDS1820.h
Код
#ifndef _DS1820_MY_LIBRARY_
#define _DS1820_MY_LIBRARY_
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

template <uint8_t count> class clDS1820
{
private:
    static const uint8_t dsd=4;
public:
    uint8_t Finish(void);
};
#endif


clDS1820.cpp
Код
#include "clDS1820.h"
template <uint8_t count> uint8_t clDS1820<count>::Finish(void)
{
return(dsd);
}


Вот что выдает компилятор:
Код
avr-gcc (GCC) 3.4.5
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiling: main.cpp
avr-g++ -c -mmcu=at90can128 -I. -gdwarf-2 -DF_CPU=14745600UL  -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wa,-adhlns=main.lst -Ic:\Sourse\Library -std=gnu++98 -MD -MP -MF .dep/main.o.d main.cpp -o main.o
main.cpp: In function `int main()':
main.cpp:12: warning: unused variable 'd'

Compiling: clDS1820.cpp
avr-g++ -c -mmcu=at90can128 -I. -gdwarf-2 -DF_CPU=14745600UL  -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wa,-adhlns=clDS1820.lst -Ic:\Sourse\Library -std=gnu++98 -MD -MP -MF .dep/clDS1820.o.d clDS1820.cpp -o clDS1820.o

Linking: main.elf
avr-g++ -mmcu=at90can128 -I. -gdwarf-2 -DF_CPU=14745600UL  -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wa,-adhlns=main.o -Ic:\Sourse\Library -std=gnu++98 -MD -MP -MF .dep/main.elf.d main.o clDS1820.o --output main.elf -Wl,-Map=main.map,--cref    -lm
main.o: In function `main':
C:\Sourse\Spirit\trunk\GCC/main.cpp:12: undefined reference to `clDS1820<(unsigned char)4>::Finish()'
C:\WinAVR\utils\bin\make.exe: *** [main.elf] Error 1

> Process Exit Code: 2
> Time Taken: 00:00


Если функцию Final описать в файле clDS1820.h, т.е. при объявлении класса, то все собирается. Т.е. вот так:
Код
template <uint8_t count> class clDS1820
{
private:
    static const uint8_t dsd=4;
public:
    uint8_t Finish(void){return(dsd);};
};
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.