WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
polinin
Родился
Сообщения: 9
Зарегистрирован: Пн апр 13, 2009 07:13:30

Сообщение polinin »

ikarab писал(а):Пишут не уж то правду ?

http://kazus.ru/forum/topics/15004.html

В проекте WinAVR при использовании "itoa" добавляется 180 байт, а в проекте CVAVR - 112, вот эта разница подрубает у меня всякую решительность. Но теперь даже не это важно. Просто принципиально непонятно как заставить этот код работать в WinAVR'e. Поэтому прошу помощи.


Это чистая правда.

А вопрос - как куски асма вставлять в WinAVR ?


Я отчётик о таком опыте оставил там, откуда Вы здесь меня процитировали. :)


2ARV. Притензий, кроме типовых, как и к любому компилятору языка высокого уровня у меня нет и не было. Тут всё понятно, и если решился - то будь готов к избыточности кода. Притензии были к библиотекам. Вот, нафига, собственно, такая и в таком виде функция "itoa" в "stdlib"? По "ключу" она формирует представление в "2", "16" или "10"... Это на мой взгляд чрезмерное увлечение универсальностью, применительно к МК, на которые и заточен весь WinAVR. Гуманнее было бы иметь три ф-ии, типа "itoa2", "itoa16" и "itoa10" - код короче. Далее, ещё прикол попался на глаза, открываем библиотеку LCD из avrlib (это типа SDK для WinAVR). Смотрим lcd.c:

Код: Выделить всё

LCD_DELAY; //wait

Угу, запомнили, открываем lcd.h:

Код: Выделить всё

#if F_CPU >= 16000000
#define LCD_DELAY   asm volatile ("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
..................................................................................

Офигенная реализация. :)))
Ну и ещё пару слов по асму. Я так и не понял идеи инлайнового асма в WinAWR. ИМХО, лучше он был бы реализован подобно CVAVR - простая вставка кода. Без вывертов, прозрачно.
Главная особенность в том, что в WinAVR не приветствуется использование явно указанных регистров в командах ассемблерных вставок - распределение регистров берет на себя компилятор, чтобы даже ассемблерные вставки оптимизировались!

Вот это ещё зачем? Если ты взялся, за АСМ в Си-проекте, то это как раз потому что тебя не устраивает "взгляд" компилятора с его "шаловливыми ручёнками". :)
WinAVR, кстати, нормально относится и к явному указанию регистров. Ну и с другой стороны, указатели ещё никто не отменял.

Всё здесь ИМХО, т.с. взгляд неискушённого любителя МК. :)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

polinin, прежде всего, WinAVR - плод коллективного творчества. потому если есть какая-то кривизна реализации - то это, в общем-то, понятно: сколько людей, столько и мнений. кому-то подай универсализм, кому-то скорость, кому-то размер... необходимость itoa вообще близка к нулю - нужная функция пишется руками за 5 минут, а вот наличие универсальной функции уже оправдано для ленивых :) и какой код для короткой задержки вы считаете более оптимальным, нежели приведенный пример? цикл? так ведь для него надо освободить регистр, занести туда значение и т.п. - глядишь, никакого выигрыша по объему и не выйдет :)

кстати, что за avrlib вы упомянули? в комплекте WinAVR не нахожу такого - это, видимо, чья-то частная библиотечка...

что касается ассемблера, то тут я с вами в корне не согласен. если вам надо вставить NOP или SEI - то тут WinAVR ничем не отличается от CVAVR (и даже попроще себя ведет). но если вы взялись за что-то посерьезнее, то... то вы должны знать, что и куда помещает компилятор в своей работе, чтобы это использовать или наоборот, не попортить - не так ли? а если вы отдаете компилятору выбор регистров для ассемблерной вставки - то он сам выберет те, которые наиболее удачно впишутся в тело уже имеющегося кода - без лишних сохранений, пересылок и т.п. иначе из-за вашей ассемблерной вставки с явными регистрами вы рискуете похерить всю оптимизацию компилятора, которую он произвел "вокруг" вставки...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
polinin
Родился
Сообщения: 9
Зарегистрирован: Пн апр 13, 2009 07:13:30

Сообщение polinin »

Прежде всего замечу, что мною сказанное не следует рассматривать как критику. Это просто частное мнение, бытовуха - мало есть таких вещей, которые нравились бы нам всегда и всесторонне - даже жёны которых мы сами какбы и выбираем. :)

ARV писал(а):polinin, прежде всего, WinAVR - плод коллективного творчества. потому если есть какая-то кривизна реализации - то это, в общем-то, понятно: сколько людей, столько и мнений.


Бесспорно.

необходимость itoa вообще близка к нулю - нужная функция пишется руками за 5 минут


Или берётся ещё где-нить, нагло тырится, кпримеру. :)

и какой код для короткой задержки вы считаете более оптимальным, нежели приведенный пример? цикл? так ведь для него надо освободить регистр, занести туда значение и т.п. - глядишь, никакого выигрыша по объему и не выйдет :)


Выйдет-выйдет. :)
Вы прикиньте, в указанном мною примере для организации одной паузы гробится 14 байт флэша, а таких пауз в драйвере LCD... ну Вы в курсе. А найти под цикл регистр в SRAM - нет проблемы или не должно её быть, иначе что-то не так в консерватории где мы обучались. :)))

кстати, что за avrlib вы упомянули? в комплекте WinAVR не нахожу такого - это, видимо, чья-то частная библиотечка...


http://hubbard.engr.scu.edu/embedded/av ... index.html

что касается ассемблера, то тут я с вами в корне не согласен. если вам надо вставить NOP или SEI - то тут WinAVR ничем не отличается от CVAVR (и даже попроще себя ведет). но если вы взялись за что-то посерьезнее, то... то вы должны знать, что и куда помещает компилятор в своей работе, чтобы это использовать или наоборот, не попортить - не так ли?


Да, конечно, лучше знать. Но вовсе не обязательно. Именно поэтому я и сказал выше об указателях. И пусть там компилятор вращает регистрами как ему хочется, если уж хочется ему в этом не мешать. Поясню мысль. Жертвуете парой-тройкой регистров под "фиксированное закрепление" и все дела. Типа:

Код: Выделить всё

#ifdef __ASSEMBLER__
#  define  prt_for_var1  rXX
#  define  prt_for_var2  rXY
#else  /* !ASSEMBLER */
...
register  char*  prt_for_var1  asm("rXX");
register  char*  prt_for_var2  asm("rXY");
...


ну а далее всё просто. Вы будете всегда знать где расположены или куда положить (ну или что там ещё предусматривает контекст Вашей программы) при переходах на АСМ и обратно. И плата за это - мизер. :)
Передача аргументов в функцию (а это главная проблема, как мне представляется) компилятором в типовой компиляции производится одним и тем же образом, через одни и теже регистры - их также очень просто отследить.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

polinin писал(а):Поясню мысль. Жертвуете парой-тройкой регистров под "фиксированное закрепление" и все дела. Типа:

Код: Выделить всё

#ifdef __ASSEMBLER__
#  define  prt_for_var1  rXX
#  define  prt_for_var2  rXY
#else  /* !ASSEMBLER */
...
register  char*  prt_for_var1  asm("rXX");
register  char*  prt_for_var2  asm("rXY");
...


ну а далее всё просто. Вы будете всегда знать где расположены или куда положить (ну или что там ещё предусматривает контекст Вашей программы) при переходах на АСМ и обратно. И плата за это - мизер. :)
Передача аргументов в функцию (а это главная проблема, как мне представляется) компилятором в типовой компиляции производится одним и тем же образом, через одни и теже регистры - их также очень просто отследить.
не могу согласиться на 100%.
ваша рекомендация приведет к тому, что компилятору придется везеде и всюду освобождать эти "зафиксированные" регистры, чтобы можно было использовать ptr_for_var1 - в итоге весь код. кроме ассемблерной вставки, может стать весьма неоптимальным. при передаче параметров в функции все тоже решаемо, но либо потребует изучения документации GCC, либо анализа листинга - иначе для функций с разным количеством параметров вам придется использовать различные подходы к одинаковым внешне ассемблерным вставкам. тот метод. что предлагает WinAVR освобождает вас от этого - вы просто указываете "характеристику" регистра для ассемблерной команды, а WinAVR самостоятельно подберет подходящий наиболее оптимально. кстати, если вдруг будет необходимо - WinAVR добавит загрузку в регистр нужного значения автоматически - вам даже не надо будет об этом заботиться.

и еще об указателях. из-за того, что в архитектуре AVR всего 3 пары регистров заточены под косвенные обращения к памяти (да и то лишь один - для обращения к FLASH), то использование в одной функции более трех указателей сильно "портит" код. так что с указателями надо быть поосторожнее, если имеешь цель получить суперкомпактный и супербыстрый код :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
polinin
Родился
Сообщения: 9
Зарегистрирован: Пн апр 13, 2009 07:13:30

Сообщение polinin »

ARV писал(а):ваша рекомендация приведет к тому, что компилятору придется везеде и всюду освобождать эти "зафиксированные" регистры, чтобы можно было использовать ptr_for_var1


Поясните. Я не понял почему компилятор должен везде и всюду освобождать "мои" регистры? Он их просто не должен трогать пока я этого сам не захочу - вот и всё.

в итоге весь код кроме ассемблерной вставки, может стать весьма неоптимальным.


Каким образом?

и еще об указателях. из-за того, что в архитектуре AVR всего 3 пары регистров заточены под косвенные обращения к памяти (да и то лишь один - для обращения к FLASH), то использование в одной функции более трех указателей сильно "портит" код. так что с указателями надо быть поосторожнее, если имеешь цель получить суперкомпактный и супербыстрый код :)


Это, на мой взгляд, выше обсуждаемого вопроса. Это просто данность, объективные обстоятельства, в которых надо работать. :)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

polinin писал(а):Поясните. Я не понял почему компилятор должен везде и всюду освобождать "мои" регистры? Он их просто не должен трогать пока я этого сам не захочу - вот и всё.
попробую пояснить.

предположим, вы написали:

Код: Выделить всё

register uint8_t my_var asm("r23");
то есть закрепили R23 за собственной глобальной переменной. потом вы написали какую-то функцию с 6-ю параметрами. для передачи параметров WinAVR начинает задействовать регистры: сначала берет R25, потом R24 и постепенно доходит до необходимости использовать R23 - но он же зафиксирован за вашей переменной! компилятор ни секунды не мешкая запихивает в стек содержимое R23, заносит в него нужное значение и выполняет вызов функции... а после того. как она отработает - восстановит эту переменную, т.е. R23... если вы "закрепите" таким способом указатель - еще хуже: регистровые пары-указатели (X, Y, Z) используются компилятором очень часто - для циклов, массивов и т.п., даже когда указатели явно в тексте программы не используются. в этом случае, вы уже догадались, будет бесконечное погружение вашей переменной в стек и вынимание ее оттуда...

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

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

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

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

Мой уютный бложик... заходите!
polinin
Родился
Сообщения: 9
Зарегистрирован: Пн апр 13, 2009 07:13:30

Сообщение polinin »

Поясняющее отступление. С атмелами знаком ровно три недели. Надо было заткнуть потребность. По совокупности цена-возможности подошла пара ATtiny(24 и 26). Потому как учить их устройство ломает, поставил CVAVR2.04, но версия "эволюшин" отказалась компилить код более ~1750 б. Переписал в WinVR'e - всё уже в работе. Ранее, лет 5 назад, работал с PIC-ами, тогда действительно серьёзно штудировал их архитектуру и все 35 инструкций. :) На Срр периодически програмлю под винду, облегчая себе работу. Поэтому в деталях применительно к теме я не разбираюсь и выражаю мысли только исходя из вышесказанного.

предположим, вы написали:

Код: Выделить всё

register uint8_t my_var asm("r23");
то есть закрепили R23 за собственной глобальной переменной.


Уже неправильно. Думаю, что этот регистр Вы не получите. WinAVR на этапе компиляции скажет Error или Warning. Нельзя брать всё, что захочется - у компилятора есть "свои привычки" которым он изменять и не собирается. Но пусть это будет "r8" и мы продолжим.

потом вы написали какую-то функцию с 6-ю параметрами. для передачи параметров WinAVR начинает задействовать регистры: сначала берет R25, потом R24 и постепенно доходит до необходимости использовать R23 - но он же зафиксирован за вашей переменной! компилятор ни секунды не мешкая запихивает в стек содержимое R23


Я взял 26 параметров и регистр стоит как вкопанный, храня указанное ему значение. Попробуйте вот этот код:

Код: Выделить всё

#include <avr>
#include <util>
register int* prt_int asm("r8");
void test_func(int q, int a, int z, int x, int s, int w, int e, int d, int c, int v, int f, int r, int t, int g, int b, int n, int h, int y, int u, int j, int m, int k, int i, int o, int l, int p)
{
   q = a+z-x+s-w-e+d+c;
   v = f-r+t+g+b-n-h-y;
   u = j+m+k-i+o-l+p;
   q = v+u;
   q += q;
}

int main(void)
{
  int q=8,a=4354,z=56,x=4354,s=87,w=876,e=909,d=6543,
       c=909,v=509,f=322,r=65,t=765,g=545,b=43,n=644,
       h=78,y=87,u=87,j=787,m=878,k=787,i=78,o=43,l=43,p=565;
  prt_int = &q;
  for(;;)
  {
    _delay_ms(1);
    test_func(q,a,z,x,s,w,e,d,c,v,f,r,t,g,b,n,h,y,u,j,m,k,i,o,l,p);
  }
}


и посмотрите как ходят данные и что происходит с "r8". А ничего с ним не происходит. Держит присвоенное значение, как и положено. Но даже этого не надо. Вовсе не обязательно хранить в нём что-то всё время. Он интересен в оперативном плане. Дать ему значение, перейти в асм, там обработка данных и возврат в Си... да хоть опять-же через него - этого за глаза хватит. Да и функции с 6-ю аргументами - это (в контексте), ИМХО, изврат. Вы же не окна строить собираетесь... но пусть и так, всё равно одного указателя хватит на любое количество аргументов. Дело в оформлении.

ключевое слово register не означает, что этот регистр больше нигде не будет использован!


Ну не знаю. Кроме как здесь применять его не приходилось ещё. Возможно и так. Всё, что я твёрдо помню из читанного - это класс памяти. Ну и ещё немного, что так сходу и не сформулирую. :)

я тут протестировал на всякий случай, и выяснил. что с регистровыми переменными дела куда хуже. чем я мог предположить!


Я Вам дал код, который я не просто в таком голом виде смотрел, а втыкал его в проект с 24-м камнем, где кроме этого, ещё куча дел делается. Всё нормально. :) Более того, даже через "r0" тоже можно передавать данные. Думаю, что Вы понимаете о чём я говорю.
Так что, если компилятор безмолвно позволил Вам зафиксить регистр, то в принципе, как я и говорил ранее, он обойдётся без него. :)
Давайте свой код, где теряются данные, да ещё так, что "мои рекомендации" не сработают. ;)
polinin
Родился
Сообщения: 9
Зарегистрирован: Пн апр 13, 2009 07:13:30

Сообщение polinin »

Include мои порезались. :)
Добавить по слэшу и io.h с delay.h надо.
2-я попытка:

Код: Выделить всё

#include <avr>
#include <util>
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

polinin, ваш пример безусловно верный :) и это не отказ от моих слов и не парадокс :) это закономерность. читайте документацию:
You can define a global register variable in GNU C like this:
register int *foo asm ("a5");
Here a5 is the name of the register which should be used. Choose a register which is normally saved and restored by function calls on your machine, so that library routines will not clobber it.
обратите внимание на последнее предложение :) а теперь возьмите модуль stdio.h и задействуйте в своей программе функцию printf() или что-то аналогичное... и вы увидите, что содержимое многих глобальных регистровых переменных теряется после вызова этих функций. почему? читаем доку:
It is not safe for one function that uses a global register variable to call another such function foo by way of a third function lose that was compiled without knowledge of this variable (i.e. in a different source file in which the variable wasn't declared). This is because lose might save the register and put some other value there. For example, you can't expect a global register variable to be available in the comparison-function that you pass to qsort, since qsort might have put something else in that register. (If you are prepared to recompile qsort with the same global register variable, you can solve this problem.)
кратко, смысл этого заключается в том, что библиотечные функции, скомпилированные без учета того, что какой-то регистр может быть задействован для глобальной переменной, могут изменять его содержимое.

в вашей программе не было обращения к библиотечным функциям - и глобальная переменная успешно "спасалась" компилятором :)

кроме этого, все прочие мои рассуждения остаются в силе: получая оптимум в одном. есть риск потерять оптимум во всем остальном. "исключение" регистра из работы не обходится компилятору без проблем :)
кстати, polinin, не в обиду будь вам сказано: ваш пример после компиляции с включенной оптимизацией вообще ничего не делает с указанными регистрами и функция ваша с кучей параметров просто не вызывается и вообще отсутствует в коде :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
polinin
Родился
Сообщения: 9
Зарегистрирован: Пн апр 13, 2009 07:13:30

Сообщение polinin »

ARV писал(а):polinin, ваш пример безусловно верный :) и это не отказ от моих слов и не парадокс :) это закономерность. читайте документацию:
You can define a global register variable in GNU C like this:
register int *foo asm ("a5");
Here a5 is the name of the register which should be used. Choose a register which is normally saved and restored by function calls on your machine, so that library routines will not clobber it.
обратите внимание на последнее предложение :)


Обратил. Всё как я и говорил. Компилятор, вобщем, лояльно относится к закреплению регистра. :)

а теперь возьмите модуль stdio.h и задействуйте в своей программе функцию printf() или что-то аналогичное... и вы увидите, что содержимое многих глобальных регистровых переменных теряется после вызова этих функций.


Даже это не мешает. Хотя, если Вы сходите по ссылке от ikarab туда, где я привёл пример вставки асмовой ф-ии, то увидите оговорку: "актуально для...", исходя из которой понятно, что использование библиотеки "stdio" в подобных случаях находится лишь в области теоритических возможностей. ;)

(If you are prepared to recompile qsort with the same global register variable, you can solve this problem.)


Да, проблема вполне решаема.

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


Иду Вам навстречу. И пусть меняют. Это никак не мешает.

в вашей программе не было обращения к библиотечным функциям - и глобальная переменная успешно "спасалась" компилятором :)


Вы не внимательно меня читали. :)

кроме этого, все прочие мои рассуждения остаются в силе: получая оптимум в одном. есть риск потерять оптимум во всем остальном. "исключение" регистра из работы не обходится компилятору без проблем :)


Не понимаю к чему у Вас сводится "оптимум", если такая переменная никак компилятору не мешает и он Вам её молча отдал. :)
polinin
Родился
Сообщения: 9
Зарегистрирован: Пн апр 13, 2009 07:13:30

Сообщение polinin »

ARV писал(а):кстати, polinin, не в обиду будь вам сказано: ваш пример после компиляции с включенной оптимизацией вообще ничего не делает с указанными регистрами :) и функция ваша с кучей параметров просто не вызывается и вообще отсутствует в коде :)))


Не обидно. Это идиотская функция. Сделана в угоду Вам. С тупым набором аргументов по количеству. :)))
Где Ваш код, кстати?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

Код: Выделить всё

#include "avr/io.h"
#include "stdio.h"
#include "util/delay.h"

register uint8_t prt_int asm("r20");
volatile char str[20];

int main(void){
   
  for(;;){
    sprintf(str,"%u",prt_int++);
    _delay_us(10);
    PORTB = prt_int;
  }
}
для выбора в качестве переменной R2 - все ништяк, если R20 - в str всегда 0 :)

P.S. кавычки в инклюдах условно - ибо уголки скрипт форума вырезает
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
polinin
Родился
Сообщения: 9
Зарегистрирован: Пн апр 13, 2009 07:13:30

Сообщение polinin »

ARV писал(а):

Код: Выделить всё

#include "avr/io.h"
#include "stdio.h"
#include "util/delay.h"

register uint8_t prt_int asm("r20");
volatile char str[20];

int main(void){
   
  for(;;){
    sprintf(str,"%u",prt_int++);
    _delay_us(10);
    PORTB = prt_int;
  }
}
для выбора в качестве переменной R2 - все ништяк, если R20 - в str всегда 0 :)


Ну да, я же говорил Вам, что компилятор отдаёт не всё подряд. На этот Ваш код он поругался так:

Код: Выделить всё

warning: call-clobbered register used for global register variable

Поэтому такой регистр лучше не трогать. Далее, к вопросу увязки нашего диалога с контекстом поднятого вопроса, посмотрим на результат компиляции Вашего кода:

Код: Выделить всё

Program:    1650 bytes (80.6% Full)

А в ATtiny24, которым (и им подобным) и посвящён наш диалог (как я считаю), всего 2кБ флэша. Т.е. места осталось на инициализацию контроллера и пару раз сказать принтэфом "Hello World!", да и то вникуда... Это к вопросу о целесообразности использования библиотек. :)
polinin
Родился
Сообщения: 9
Зарегистрирован: Пн апр 13, 2009 07:13:30

Сообщение polinin »

Код: Выделить всё

warning: call-clobbered register used for global register variable

Кстати, таким простым способом можно легко вычислить регистры, которые используются компилятором, а так же для чего они ему нужны. После чего можно вообще отказаться (для конкретного случая и я об этом тоже говорил) от использования global register variable.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

1. распределение регистров WinAVR не скрывает - об этом рассказано в документации к avr-libc.
2. наш диалог, как я думал, имел отношение к WinAVR, а не конкретному камешку :)
3. warnings must be read carefully :) с этим я не спорю, спровоцировал компилятор :)
4. для мелких камешков лучше писать на ассемблере, имхо. и библиотеками пользоваться с великой осторожностью :)
5. для получения более компактного кода в WinAVR придется колдовать с опциями оптимизации. имхо, это правильнее, чем извраты с ассемблерными вставками, которым следует отвести нишу "когда деваться больше некуда". но в этом случае см. п.4 :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Lucifier
Родился
Сообщения: 4
Зарегистрирован: Сб апр 18, 2009 22:54:01

Сообщение Lucifier »

такой вопрос... чтобы я не компилировал в винавр всевермя выдает
Compiling C: asdasdasd.c
avr-gcc -c -mmcu=atmega8 -I. -gdwarf-2 -DF_CPU=8000000UL -OOPTIMIZATION_LEVEL -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=obj/asdasdasd.lst -std=gnu99 -Wundef -MD -MP -MF .dep/asdasdasd.o.d asdasdasd.c -o obj/asdasdasd.o
cc1.exe: error: invalid option argument '-OOPTIMIZATION_LEVEL'
make.exe: *** [obj/asdasdasd.o] Error 1


с чем это может быть связано?
Аватара пользователя
ikarab
Опытный кот
Сообщения: 828
Зарегистрирован: Пн мар 16, 2009 21:40:57
Контактная информация:

Сообщение ikarab »

Lucifier писал(а):с чем это может быть связано?

может О русская у вас в мэйк файле ?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

Lucifier писал(а):такой вопрос... чтобы я не компилировал в винавр всевермя выдает
Compiling C: asdasdasd.c
avr-gcc -c -mmcu=atmega8 -I. -gdwarf-2 -DF_CPU=8000000UL -OOPTIMIZATION_LEVEL -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=obj/asdasdasd.lst -std=gnu99 -Wundef -MD -MP -MF .dep/asdasdasd.o.d asdasdasd.c -o obj/asdasdasd.o
cc1.exe: error: invalid option argument '-OOPTIMIZATION_LEVEL'
make.exe: *** [obj/asdasdasd.o] Error 1


с чем это может быть связано?
ну написано же: инвалид опшн -О... для оптимизации определено только 5 вариантов опций: -O0, -O1, -O2, -O3 и -Os. а теперь посмотрите, что там у вас написано...
Арнаутов Юрий
Родился
Сообщения: 14
Зарегистрирован: Чт мар 19, 2009 19:35:49
Откуда: Алчевск

Сообщение Арнаутов Юрий »

При компиляции программы в WinAVR в нижнем окошке стало писать такие строги под конец компиляции:

Код: Выделить всё

avr-objcopy -j .text -j .data -O srec turtles.elf turtles.srec
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O ihex turtles.elf turtles_eeprom.hex \
   || { echo empty turtles_eeprom.hex not generated; exit 0; }
c:\WinAVR-20080610\bin\avr-objcopy.exe: --change-section-lma .eeprom=0x00000000 never used
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O binary turtles.elf turtles_eeprom.bin \
   || { echo empty turtles_eeprom.bin not generated; exit 0; }
c:\WinAVR-20080610\bin\avr-objcopy.exe: --change-section-lma .eeprom=0x00000000 never used
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O srec turtles.elf turtles_eeprom.srec \
   || { echo empty turtles_eeprom.srec not generated; exit 0; }
c:\WinAVR-20080610\bin\avr-objcopy.exe: --change-section-lma .eeprom=0x00000000 never used

> Process Exit Code: 0
> Time Taken: 00:01


Подскажите пожалуйста что это значит.

"turtles" - так называется фаил с программой на С.
Все гениальное - просто!!!!!!!!!
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

задано делать hex-файл для EEPROM, а содержимое EEPROM в программе не определено, вот и ругается, что нечего создавать. это не страшно.
Ответить

Вернуться в «AVR»