Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Разница CodeVision и WinAVR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
virtuality
Гребаные идентификаторы....

Как просто было в CodeVision : PORTD.1=1; DDRD=1;
Пытаюсь в WinAVR сделать - достал примерно следующий код:

Код
  DDRD  &= ~(_BV(PD2));                            // Назначаем 2-ю линию порта D на вход
  PORTD |=  (_BV(PD2));                            // подключаем "подтягивающий" резистор


Нельзя ли попроще как-нибудь?


И еще вопрос - инициализирую АЦП - выдает беспорядочные хаотичные цифры. Понятно, что дело в том, что ловятся шумы. Вылечил резистором 4,7 кОм на питание. А как-нить программно нельзяли?
ksv198
Цитата(virtuality @ Jul 22 2006, 14:15) *
Гребаные идентификаторы....

Как просто было в CodeVision : PORTD.1=1; DDRD=1;
Пытаюсь в WinAVR сделать - достал примерно следующий код:

Код
  DDRD  &= ~(_BV(PD2));                            // Назначаем 2-ю линию порта D на вход
  PORTD |=  (_BV(PD2));                            // подключаем "подтягивающий" резистор


Нельзя ли попроще как-нибудь?

Например так:

Код
//определяем частые действия
#define cs_active   PORTD &=~(_BV(PD2))
#define cs_inactive   PORTD |=_BV(PD2)
...

//используем
cs_active;

...

cs_inactive;
...


Не панацея, но хоть немного легче smile.gif
niccom
Цитата(virtuality @ Jul 22 2006, 14:15) *
Гребаные идентификаторы....

Как просто было в CodeVision : PORTD.1=1; DDRD=1;
Пытаюсь в WinAVR сделать - достал примерно следующий код:

Код
  DDRD  &= ~(_BV(PD2));                            // Назначаем 2-ю линию порта D на вход
  PORTD |=  (_BV(PD2));                            // подключаем "подтягивающий" резистор


Нельзя ли попроще как-нибудь?


конечно можно
вот так тоже будет работать
DDRD &= ~_BV(PD2);
PORTD |= _BV(PD2);
а в чем проблема то?
с логическими операциями?
xemul
Код
#define bitset(var,bitno) ((var) |= 1 << (bitno))
#define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))
bitclr(DDRD, PD2);
bitset(PORTD, PD2);


Или ввести свой тип, например, так:
Код
typedef mytype
union
{
   uchar i;
   struct
   {
      uchar _0: 1;
      uchar _1: 1;
      ...
   } b;
}

и переопределить все потребные регистры
pitt
Разница CodeVision и WinAVR в том, что один пакет это IDE, предназначенное для тех, кто не является профессиональным software engineer, а другой именно пакет утилит для профессионалов или тех, кто на пути в этом направлении.
Laksus
Цитата
xemul
#define bitset(var,bitno) ((var) |= 1 << (bitno))
#define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))
bitclr(DDRD, PD2);
bitset(PORTD, PD2);

И еще можно добавить
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))
(Application Note "AVR035: Efficient C Coding for AVR")
______________

Извиняюсь, что влезаю со своим вопросом, но по моему он по этой теме.
Вопрос по поводу дефайнов в файлах io*.h в WinAVR.

Понятно использование имен бит типа:
/* UCSRA */
#define RXC 7
#define TXC 6 ...и так далее.

Понятно применение имен для адресов PINx, DDRx, PORTx.

Но не может ли кто нибудь объяснить какой смысл в
именовании бит в портах:
/* PORTD */
#define PD7 7
...
/* DDRD */
#define DDD7 7
...
/* PIND */
#define PIND7 7
...
Чем это лучше чем указывать биты портов просто цифрами?
По моему писать больше, а от ошибок не помогает.
__________
Александр
2006 07 22
xemul
Цитата(Laksus @ Jul 22 2006, 20:39) *
Понятно использование имен бит типа:
/* UCSRA */
#define RXC 7
#define TXC 6 ...и так далее.

Понятно применение имен для адресов PINx, DDRx, PORTx.

Но не может ли кто нибудь объяснить какой смысл в
именовании бит в портах:
/* PORTD */
#define PD7 7
...
/* DDRD */
#define DDD7 7
...
/* PIND */
#define PIND7 7
...
Чем это лучше чем указывать биты портов просто цифрами?
По моему писать больше, а от ошибок не помогает.
__________
Александр
2006 07 22


Никто же не мешает задать свои осмысленные имена
#define ORelay PD6
#define ISens PD7

Я стараюсь работать избегать битовых операций с портами ввода/вывода, где это возможно, и держу их копии вида
Код
union
{
   uchar i;
   struct
   {
      uchar Out0: 1;   // естественно, лучше дать осмысленное имя
      ...
   } b;
} PortAOut;

с которыми производятся все необходимые операции, и которые переписываются наружу (например, в PortA) с требуемой частотой.
С вводом поступаю примерно также - при этом проще фильтровать медленные сигналы (та же клавиатура, например).
Ну а с быстрыми сигналами приходится работать непосредственно на портах.
И при этом мне намного симпатичнее описание для PIC'ов вида
Код
/* GPIO Bits */
static volatile bit    GPIO0    @ (unsigned)&GPIO*8+0;

Под WinAVR у меня такое не прокатило, хотя я еще не слишком упирался.
vesago
Цитата(pitt @ Jul 22 2006, 19:13) *
Разница CodeVision и WinAVR в том, что один пакет это IDE, предназначенное для тех, кто не является профессиональным software engineer, а другой именно пакет утилит для профессионалов или тех, кто на пути в этом направлении.

Как однако вы точно сказали. Недостаток PORTD.1 потом если надо код перегнать под другую платформу, менять больше придется. Приятнее когда PORTD=(1<<LED) - везде пройдет и понятнее имхо.
defunct
Цитата(vesago @ Jul 23 2006, 09:41) *
Недостаток PORTD.1 потом если надо код перегнать под другую платформу, менять больше придется. Приятнее когда PORTD=(1<<LED) - везде пройдет и понятнее имхо.

Приятнее спору нет, однако это совсем не равносильно с PORTD.1 = 1. И сгенеренные команды будут совсем разными.

Для PORTD.1 = 1 будет сгенерено
SBI PORTD, 1


Для PORTD = (1 << LED):
LDI Rxx, (1 << LED)
OUT PORTD, Rxx
pitt
Во-первых,
PORTD.1 = 1 эквивалентно PORTD |= ( 1 << 1 ); // ни в коем случае не PORTD = ( 1 << 1 );;
Во-вторых, WinAVR достаточно умен и генерирует код:
PORTD |= ( 1 << 1 );
+0000007E: 9A58 SBI 0x0B,1 Set bit in I/O register
Serg79
Цитата(defunct @ Jul 24 2006, 00:15) *
Цитата(vesago @ Jul 23 2006, 09:41) *

Недостаток PORTD.1 потом если надо код перегнать под другую платформу, менять больше придется. Приятнее когда PORTD=(1<<LED) - везде пройдет и понятнее имхо.

Приятнее спору нет, однако это совсем не равносильно с PORTD.1 = 1. И сгенеренные команды будут совсем разными.

Для PORTD.1 = 1 будет сгенерено
SBI PORTD, 1


Для PORTD = (1 << LED):
LDI Rxx, (1 << LED)
OUT PORTD, Rxx

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

Писать: " TIMSK.1 = 1; TIMSK.7 = 1; " можно себе позволить только если не приходиться сопровождать код.
Зато как приятно через полгода поднять код и увидеть там " TIMSK |= (1<<OCIE0)|(1<<OCIE2); ", сразу становиться понятно что у тебя сдесь делается.

А на счет того какой компилятор лучше смотри тему http://electronix.ru/forum/index.php?showtopic=12284
defunct
Цитата(Serg79 @ Jul 24 2006, 07:59) *
Ну это вы зря, WinAVR может позволить себе токое невежество только при отключенной оптимизации (-О0) и то не всегда.

Ну почему же.
Выражение PORTD = (1 << LED) однозначно указывает, что бит LED надо установить, а остальные сбросить.

Цитата
Писать: " TIMSK.1 = 1; TIMSK.7 = 1; " можно себе позволить только если не приходиться сопровождать код.

С этим нельзя не согласиться ;>
vesago
Цитата(pitt @ Jul 24 2006, 00:32) *
Во-первых,
PORTD.1 = 1 эквивалентно PORTD |= ( 1 << 1 ); // ни в коем случае не PORTD = ( 1 << 1 );;


smile.gif Я имел ввиду общий подход. Я имел ввиду, что лучьше сразу писать стандартно и использовать конструкции вроде PORTD |= ( 1 << blabla ); PORTD &= (1<<blabla) if((PORTD & (...))!=0)и т.п. Во всех нормальных компиляторах и на всех платформах будет работать.
vet
Цитата(Serg79 @ Jul 24 2006, 08:59) *
Писать: " TIMSK.1 = 1; TIMSK.7 = 1; " можно себе позволить только если не приходиться сопровождать код.

Никто не мешает в CV написать TIMSK.OCIE0 = 1;
Serg79
Цитата(vet @ Jul 24 2006, 11:52) *
Цитата(Serg79 @ Jul 24 2006, 08:59) *

Писать: " TIMSK.1 = 1; TIMSK.7 = 1; " можно себе позволить только если не приходиться сопровождать код.

Никто не мешает в CV написать TIMSK.OCIE0 = 1;

Я прикрепил заголовочный файл для ATMega64 из CV, так попробуй там найти флаг OCIE0. Это тебе придется все самому ручками прописывать.
Это один из минусов CV, кстати не самый маленький.
vet
Serg79
Ручками совершенно необязательно; лично я использую определения битов, взятые из заголовочных файлов IAR.
pokos
Цитата(vesago @ Jul 24 2006, 11:14) *
PORTD &= (1<<blabla)

С трудом представляю, где это может пригодиться. Попробуйте написать в том же духе строчку, сбрасывающую в ноль единственный бит.
Семён
Цитата(vet @ Jul 24 2006, 13:05) *
Serg79
Ручками совершенно необязательно; лично я использую определения битов, взятые из заголовочных файлов IAR.

Порты всегда переопределяю в отдельном файле, а то после разводки можно потратить еще кучу времени, так как конструкторы любят их менять как им удобно (кроме портов зависимых от аппаратуры). Далее всегда пишу макросы типа:
#define COMP_U_LOW COMPORATOR_U &= ~Bit(COMP_U);
для удобства использования. Остальную регистры переопределяю для быстрого перехода на другой контролер.
vesago
Цитата(pokos @ Jul 24 2006, 12:21) *
Цитата(vesago @ Jul 24 2006, 11:14) *

PORTD &= (1<<blabla)

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


PORTD &= ~(1<<blabla);
Код
#define LED_DDR              DDRD
#define LED_PORT             PORTD
#define LED_PIN                PIND
#define LED                       3
#define LED_ON                 LED_PORT |= (1<<LED)
#define LED_OFF                LED_PORT &= ~(1<<LED)

    if(system.led_timer == 0)
    {
      if((LED_PIN & (1<<LED)) == 0)
      {
        LED_ON;
      }
        else
        {
          LED_OFF;
        }

      system.led_timer = 0.1*(1000/SYSTEM_TICK);
    }
Serg79
Цитата(vet @ Jul 24 2006, 13:05) *
Serg79
Ручками совершенно необязательно; лично я использую определения битов, взятые из заголовочных файлов IAR.

Так и Я о том же, что в нормальных компиляторах (типа IAR или WinAVR) эти все флаги и т.п. прописанны в заголовочных файлах, а в CodeVisionAVR C Compiler этого нет, там все приходится ручками писать.
WHALE
дел на 5 минут,к тому-же я обычно свои библиотечные файлы исполь
зую,где уже все определено.
Serg79
Цитата(WHALE @ Jul 24 2006, 15:24) *
дел на 5 минут,к тому-же я обычно свои библиотечные файлы исполь
зую,где уже все определено.

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

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

А CodeVisionAVR C Compiler пройденный этап. И Я к ниму уже врядли когда вернусь после WinAVR.

Но это все, только мое личное мнение. excl.gif
Семён
Цитата(Serg79 @ Jul 24 2006, 15:55) *
Цитата(WHALE @ Jul 24 2006, 15:24) *

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

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

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

А CodeVisionAVR C Compiler пройденный этап. И Я к ниму уже врядли когда вернусь после WinAVR.

Но это все, только мое личное мнение. excl.gif

ИМХО: переписываешь порты исключительно для облегчения себе жизни. Инструкцию LED_OFF не надо комментировать в отличие от PORTD.1=1;. К томуже при смени портов будешь выискивать в проекте все эти PORTD.1=1;
pokos
Цитата(vesago @ Jul 24 2006, 13:53) *
PORTD &= ~(1<<blabla);

Когда-то я придумал то же самое.... товарищи даже спрашивали, мол, зачем так сложно. Потом попробовал, во что превращают это разные компиляторы с разными опциями оптимизации. Интересно было!
_Bill
Цитата(pokos @ Jul 24 2006, 15:43) *
Цитата(vesago @ Jul 24 2006, 13:53) *
PORTD &= ~(1<<blabla);

Когда-то я придумал то же самое.... товарищи даже спрашивали, мол, зачем так сложно. Потом попробовал, во что превращают это разные компиляторы с разными опциями оптимизации. Интересно было!

И во что же?
Семён
Цитата(pokos @ Jul 24 2006, 16:43) *
Цитата(vesago @ Jul 24 2006, 13:53) *
PORTD &= ~(1<<blabla);

Когда-то я придумал то же самое.... товарищи даже спрашивали, мол, зачем так сложно. Потом попробовал, во что превращают это разные компиляторы с разными опциями оптимизации. Интересно было!

Всегда считал, что битовые операции с портами в AVR компилятор преобразует в что-то типа:
sbi DDRB,1
_Bill
Цитата(Семён @ Jul 24 2006, 16:07) *
Цитата(pokos @ Jul 24 2006, 16:43) *

Цитата(vesago @ Jul 24 2006, 13:53) *
PORTD &= ~(1<<blabla);

Когда-то я придумал то же самое.... товарищи даже спрашивали, мол, зачем так сложно. Потом попробовал, во что превращают это разные компиляторы с разными опциями оптимизации. Интересно было!

Всегда считал, что битовые операции с портами в AVR компилятор преобразует в что-то типа:
sbi DDRB,1

А разве не так?
Семён
Цитата(_Bill @ Jul 24 2006, 17:14) *
Цитата(Семён @ Jul 24 2006, 16:07) *

Цитата(pokos @ Jul 24 2006, 16:43) *

Цитата(vesago @ Jul 24 2006, 13:53) *
PORTD &= ~(1<<blabla);

Когда-то я придумал то же самое.... товарищи даже спрашивали, мол, зачем так сложно. Потом попробовал, во что превращают это разные компиляторы с разными опциями оптимизации. Интересно было!

Всегда считал, что битовые операции с портами в AVR компилятор преобразует в что-то типа:
sbi DDRB,1

А разве не так?

товарищ pokos утверждает что НЕТ. Кстати если у меня в проекте есть не используемая аппаратура их порты и регистры (если можно) стараюсь использовать в виде глобальных флагов.
typedef struct SYSTEM
{
unsigned char data1:1;
unsigned char data2:1;
unsigned char data3:1;
unsigned char data4:1;
}SYSTEM;
__no_init volatile SYSTEM system@0x40;

значительно увеличивается скорость работы установки флага system.data1=1;, сброса флага и проверки флага.
pokos
Цитата(Семён @ Jul 24 2006, 17:28) *
товарищ pokos утверждает что НЕТ.

Кстати, не утверждал, просто осадочек остался. И проверил в имеющихся ЦодеВижн и ИАР - нормально компилируют. Потом нашёл-таки проект, где чудеса. Дык, там опечатка - как раз PORTD &= (1<<blabla) вместо PORTD &= ~(1<<blabla);
Так что, пардоньте, товарищи.
Woodoo
Цитата(_Bill @ Jul 24 2006, 15:14) *
Цитата(Семён @ Jul 24 2006, 16:07) *

Цитата(pokos @ Jul 24 2006, 16:43) *

Цитата(vesago @ Jul 24 2006, 13:53) *
PORTD &= ~(1<<blabla);

Когда-то я придумал то же самое.... товарищи даже спрашивали, мол, зачем так сложно. Потом попробовал, во что превращают это разные компиляторы с разными опциями оптимизации. Интересно было!

Всегда считал, что битовые операции с портами в AVR компилятор преобразует в что-то типа:
sbi DDRB,1

А разве не так?


Если речь идет только о портах с адресом 0...0x1F (0x20...0x3F) то это так, но не забудем что к другим портам, с адресом 0x20...0x3F (0x40...0x5F) это не применимо, и компилятор всегда скомпилет чтото типа
in r16, abc
andi r16, ~(1<<bit_name)
out abc, r16
pitt
Цитата(Woodoo @ Jul 24 2006, 15:31) *
Если речь идет только о портах с адресом 0...0x1F (0x20...0x3F) то это так, но не забудем что к другим портам, с адресом 0x20...0x3F (0x40...0x5F) это не применимо, и компилятор всегда скомпилет чтото типа
in r16, abc
andi r16, ~(1<<bit_name)
out abc, r16

Не совсем правда: для портов, которые не имеют команды SBI будет сгенерировано обращение к памяти.
WinAVR команду OUT давно не использует.
defunct
Цитата(Serg79 @ Jul 24 2006, 14:55) *
А CodeVisionAVR C Compiler пройденный этап. И Я к ниму уже врядли когда вернусь после WinAVR.

И правильно. Хотя:
А IAR еще лучше, но по 5.
А WinAvr хуже, но бесплатно
A CodeVision еще хуже, но по 3.

smile.gif

Цитата(Serg79 @ Jul 24 2006, 14:55) *
А CodeVisionAVR C Compiler пройденный этап. И Я к ниму уже врядли когда вернусь после WinAVR.

И правильно. Хотя:
А IAR еще лучше, но по 5.
А WinAvr хуже, но бесплатно
A CodeVision еще хуже, но по 3.

smile.gif
beer_warrior
Цитата
И правильно. Хотя:
А IAR еще лучше, но по 5.
А WinAvr хуже, но бесплатно
A CodeVision еще хуже, но по 3.


WinAVR не хуже, он просто сложнее в освоении и лишен всяких вкусностей коммерческого продукта.
Serg79
Цитата
WinAVR не хуже, он просто сложнее в освоении и лишен всяких вкусностей коммерческого продукта.

Полностью согласен. А на мой взгляд, он самый "равный" среди "равных".

WinAVR a14.gif
osnwt
Цитата(beer_warrior @ Jul 25 2006, 09:44) *
WinAVR не хуже, он просто сложнее в освоении и лишен всяких вкусностей коммерческого продукта.

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

Код
#define PRG_RDB(addr)   (*(PROGMEM char *)(addr))

Макрос из AVR-USB для совместимости с IAR (правое - это IAR'овское выражение). У IAR же нет таких заморочек, используется обычный синтаксис при условии, что указатель описан правильно. Либо, как вариант, можно использовать generic тип указателя, адресующего любой тип памяти.
beer_warrior
Цитата
Насколько слышал, у него есть проблемы с адресацией данных, размещенных в памяти программ.

Есть такая, буква, но это единственный серьезный недостаток.
На практике однородные типы данных типа строк обрабатываються нормально, проблемы имеються только со структурами. Тут уже приходится мириться.
По части оптимизации кода и гибкости настроек ИАРу не уступает.
osnwt
Цитата(beer_warrior @ Jul 25 2006, 14:09) *
По части оптимизации кода и гибкости настроек ИАРу не уступает.

Если писать со знанием особенностей конкретного компилятора, то охотно верю. USB драйвер под WinAVR (gcc) компилируется компактнее, чем IAR'ом, поскольку специально оптимизирован под gcc (но не содержит непереносимых между этими компиляторами вещей).

Однако, попытка скомпилировать сторонний код, а именно - реализацию AES декриптора от Atmel, - показала, что для такого кода gcc существенно менее эффективен по сравнению с IAR (1.5 и 1 килобайт кода соответственно). Впрочем, не утверждаю, что тот код не оптимизировался под IAR (хотя по виду не похоже) и не имею желания устраивать войну компиляторов. Просто попробовал на конкретном примере и понял, что в конкретной ситуации IAR эффективнее (и позволил решить задачу втискивания кода в boot область, что не удалось с gcc, хотя код драйвера USB под ним компилировался компактнее на 200 байтов).
beer_warrior
Цитата
Если писать со знанием особенностей конкретного компилятора, то охотно верю. USB драйвер под WinAVR (gcc) компилируется компактнее, чем IAR'ом, поскольку специально оптимизирован под gcc (но не содержит непереносимых между этими компиляторами вещей).

Истинную правду говорите. Очень многое зависит от того как писать.
Цитата
Однако, попытка скомпилировать сторонний код, а именно - реализацию AES декриптора от Atmel, - показала, что для такого кода gcc существенно менее эффективен по сравнению с IAR (1.5 и 1 килобайт кода соответственно).

Это стандартная Атмеловская аппликуха?
Надо будет попробовать. Давно хотел поиметь для теста реальную задачу, чтобы как следует проанализировать оптимизацию IAR и WinAVR.
pitt
Цитата(beer_warrior @ Jul 25 2006, 07:09) *
По части оптимизации кода и гибкости настроек ИАРу не уступает.

Увы, уступает... Чего стоит хотя бы отсутствие прагмы управления оптимизацией. Но $3000 за одно рабочее место, это, конечно, не стоит. Да здравствует WinAVR!
beer_warrior
Цитата
его стоит хотя бы отсутствие прагмы управления оптимизацией.

Что вы вцепились в эту прагму? Это же очень частный случай.
Кроме того если нужен разный уровень оптимизации, разделите код пофайлово и будет вам щастие.

BTW, перечитывал давеча gcc manual:

Цитата
GCC supports several types of pragmas, primarily in order to compile code originally written
for other compilers. Note that in general we do not recommend the use of pragmas SeeSection 5.24 [Function Attributes], page 229, for further explanation.

А уж атрибутами там можно такого накрутить smile.gif
osnwt
Цитата(beer_warrior @ Jul 25 2006, 14:31) *
Это стандартная Атмеловская аппликуха?
Надо будет попробовать. Давно хотел поиметь для теста реальную задачу, чтобы как следует проанализировать оптимизацию IAR и WinAVR.

Это Appnote по реализации AES boot loader'а от атмела. Проект сделан под IAR, но я в попытках переделать этот проект под USB уперся в размер кода, чтобы впихнуть его с кучкой дополнительных функций и USB HID интерфейсом в 4 килобайта меги32. Потому проводил разные эксперименты по поводу того, как уменьшить размер кода, и пробовал компилировать разными компиляторами (а драйвером avr-usb поддержаны сегодня только gcc и IAR). Вышло, что сказал: сам драйвер компактнее транслируется gcc (но он под него оптимизирован, как и написано в его описании). А вот на коде AES я проиграл полкилобайта. Остался на IAR.
pitt
Цитата(beer_warrior @ Jul 25 2006, 13:35) *
Цитата
чего стоит хотя бы отсутствие прагмы управления оптимизацией.

Что вы вцепились в эту прагму? Это же очень частный случай.
Кроме того если нужен разный уровень оптимизации, разделите код пофайлово и будет вам щастие.

Я уверен, что Вам хорошо знакомы принципы инкапсуляции, так вот, если "разделить код пофайлово", то о них придеться забыть и никакого "щастия" не будет! А так хочется управлять оптимизацией локально.
tiasur
AVRGCC 4.1.1

При любой оптимизации:
Код

        PORTD |= ( 1 << 1 );  
  d2:    91 9a           sbi    0x12, 1           ; 18


При отключеной оптимизации:
Код

        PORTD |= ( 1 << 1 );  
  de:    a2 e3           ldi    r26, 0x32; 50
  e0:    b0 e0           ldi    r27, 0x00; 0
  e2:    e2 e3           ldi    r30, 0x32; 50
  e4:    f0 e0           ldi    r31, 0x00; 0
  e6:    80 81           ld    r24, Z
  e8:    82 60           ori    r24, 0x02; 2
  ea:    8c 93           st    X, r24



CodeVision

При любой оптимизации:
Код

;PORTD |= ( 1 << 1 );  
00007e 9a91          SBI  0x12,1


А также:
Код

;PORTD.1 = 1;  
00007f 9a91          SBI  0x12,1


Как видно тут разницы нет никакой. Однако для следующего кода CodeVision обходится всего одним регистром в отличии от AVRGCC 4.1.1:

Код

PORTD = ( 1 << 0 );  
PORTD = ( 1 << 1 );
PORTD = ( 1 << 2 );  
PORTD = ( 1 << 3 );
PORTD = ( 1 << 4 );  
PORTD = ( 1 << 5 );
PORTD = ( 1 << 6 );  
PORTD = ( 1 << 7 );


AVRGCC 4.1.1:
Код
int main(void)
{
  ce:    71 e0           ldi    r23, 0x01; 1
  d0:    62 e0           ldi    r22, 0x02; 2
  d2:    54 e0           ldi    r21, 0x04; 4
  d4:    48 e0           ldi    r20, 0x08; 8
  d6:    30 e1           ldi    r19, 0x10; 16
  d8:    20 e2           ldi    r18, 0x20; 32
  da:    90 e4           ldi    r25, 0x40; 64
  dc:    80 e8           ldi    r24, 0x80; 128

    while(1)
    {
        PORTD = ( 1 << 0 );  
  de:    72 bb           out    0x12, r23; 18
        PORTD = ( 1 << 1 );
  e0:    62 bb           out    0x12, r22; 18
        PORTD = ( 1 << 2 );  
  e2:    52 bb           out    0x12, r21; 18
        PORTD = ( 1 << 3 );
  e4:    42 bb           out    0x12, r20; 18
        PORTD = ( 1 << 4 );  
  e6:    32 bb           out    0x12, r19; 18
        PORTD = ( 1 << 5 );
  e8:    22 bb           out    0x12, r18; 18
        PORTD = ( 1 << 6 );  
  ea:    92 bb           out    0x12, r25; 18
        PORTD = ( 1 << 7 );
  ec:    82 bb           out    0x12, r24; 18


CodeVision:
Код
        ;      34         PORTD = ( 1 << 0 );  
00007a e0e1          LDI  R30,LOW(1)
00007b bbe2          OUT  0x12,R30
        ;      35         PORTD = ( 1 << 1 );
00007c e0e2          LDI  R30,LOW(2)
00007d bbe2          OUT  0x12,R30
        ;      36         PORTD = ( 1 << 2 );  
00007e e0e4          LDI  R30,LOW(4)
00007f bbe2          OUT  0x12,R30
        ;      37         PORTD = ( 1 << 3 );
000080 e0e8          LDI  R30,LOW(8)
000081 bbe2          OUT  0x12,R30
        ;      38         PORTD = ( 1 << 4 );  
000082 e1e0          LDI  R30,LOW(16)
000083 bbe2          OUT  0x12,R30
        ;      39         PORTD = ( 1 << 5 );
000084 e2e0          LDI  R30,LOW(32)
000085 bbe2          OUT  0x12,R30
        ;      40         PORTD = ( 1 << 6 );  
000086 e4e0          LDI  R30,LOW(64)
000087 bbe2          OUT  0x12,R30
        ;      41         PORTD = ( 1 << 7 );                 
000088 e8e0          LDI  R30,LOW(128)
000089 bbe2          OUT  0x12,R30
pitt
WinAVR size:
Код

PORTD = ( 1 << 0 );
  fc:    81 e0           ldi    r24, 0x01; 1
  fe:    8b b9           out    0x0b, r24; 11
PORTD = ( 1 << 1 );
100:    82 e0           ldi    r24, 0x02; 2
102:    8b b9           out    0x0b, r24; 11
PORTD = ( 1 << 2 );
104:    84 e0           ldi    r24, 0x04; 4
106:    8b b9           out    0x0b, r24; 11
PORTD = ( 1 << 3 );
108:    88 e0           ldi    r24, 0x08; 8
10a:    8b b9           out    0x0b, r24; 11
PORTD = ( 1 << 4 );
10c:    80 e1           ldi    r24, 0x10; 16
10e:    8b b9           out    0x0b, r24; 11
PORTD = ( 1 << 5 );
110:    80 e2           ldi    r24, 0x20; 32
112:    8b b9           out    0x0b, r24; 11
PORTD = ( 1 << 6 );
114:    80 e4           ldi    r24, 0x40; 64
116:    8b b9           out    0x0b, r24; 11
PORTD = ( 1 << 7 );
118:    80 e8           ldi    r24, 0x80; 128
11a:    8b b9           out    0x0b, r24; 11
PORTD |= ( 1 << 0 );
11c:    58 9a           sbi    0x0b, 0; 11
PORTD |= ( 1 << 1 );
11e:    59 9a           sbi    0x0b, 1; 11
PORTD |= ( 1 << 2 );
120:    5a 9a           sbi    0x0b, 2; 11
PORTD |= ( 1 << 3 );
122:    5b 9a           sbi    0x0b, 3; 11
PORTD |= ( 1 << 4 );
124:    5c 9a           sbi    0x0b, 4; 11
PORTD |= ( 1 << 5 );
126:    5d 9a           sbi    0x0b, 5; 11
PORTD |= ( 1 << 6 );
128:    5e 9a           sbi    0x0b, 6; 11
PORTD |= ( 1 << 7 );
tiasur
pitt, а какая у Вас версия?
pitt
Цитата(tiasur @ Jul 25 2006, 21:43) *
pitt, а какая у Вас версия?

WinAVR-20060421
Сергей Борщ
О! Может тут кто-нибудь скажет:
1) как заставить WinAVR не подлинковывать функции к которым никто не обращается? Бить исходный файл на десять (по файлу на функцию) и делать из них библиотеку не хочу - дурная работа и инкапсуляция страдает.
2) объявляю две функции (putstring, putstring_P) у одной аргумет - указатель на флеш, у второй - указатель на RAM. Еще не зная о тонкостях досупа к флеш в обоих написал putchar(*ptr++); и получил две функции с идентичным кодом (т.е. с LD вместо LPM во второй) _без_всяких_варнингов_. Это штатное поведение? Как же тогда отслеживать ошибки типа "забыл вытащить переменную через макрос"?
aesok
Цитата(Сергей Борщ @ Jul 26 2006, 21:16) *
О! Может тут кто-нибудь скажет:
1) как заставить WinAVR не подлинковывать функции к которым никто не обращается? Бить исходный файл на десять (по файлу на функцию) и делать из них библиотеку не хочу - дурная работа и инкапсуляция страдает.


Первый вариант:
1. Добавить опции "-ffunction-sections -fdata-sections" компилятору.

2. Добавить опцию "-gc-sections" (обязательно до опций -l и -L) линкеру.

Но это будет работать ТОЛЬКО с binutils 2.17. binutils 2.16.1 удалит не только не используемые функции но и прерывания. Я не особо тестировал, но похоже "-fdata-sections" не работает.

С binutils 2.17 есть еще одна прблемма: AVRStudio (4.12) не загружает .elf файлы в которых нет .data сегмента. Тоесть должна быть как минимум одна глобальная инициализированная переменная.

Ждите новый релиз WinAVR или попробуйте взять компилятор отсюда: http://www.klen.org/Projects/Avr-gcc/avr-gcc_last_build.html

Второй вариант:
Опция компилятора -fwhole-program.

Но опять-же чтобы прерывания остались на месте придется постараться. Нужно добавить атрибут "used" в объявления функций прерываний. Подробнее здесь: http://savannah.nongnu.org/bugs/?func=deta...p;item_id=16411

Я это не тестировал.

Анатолий.
beer_warrior
Цитата
2) объявляю две функции (putstring, putstring_P) у одной аргумет - указатель на флеш, у второй - указатель на RAM. Еще не зная о тонкостях досупа к флеш в обоих написал putchar(*ptr++); и получил две функции с идентичным кодом (т.е. с LD вместо LPM во второй) _без_всяких_варнингов_. Это штатное поведение? Как же тогда отслеживать ошибки типа "забыл вытащить переменную через макрос"?

Как только в _объявлении_ присутсвует модификатор flash - сгенерится LPM. Проблемы будут, если попытаться одной и той же функцией обращаться и к RAM и к flash манипулируя аргументом.
Об этом надо просто постоянно помнить, хотя для простых манипуляций лучше пользоваться библиотечными функциями. Ну и еще не грех включить warning на максимальном уровне.
pitt
Цитата(beer_warrior @ Jul 26 2006, 17:53) *
Как только в _объявлении_ присутсвует модификатор flash - сгенерится LPM. Ну и еще не грех включить warning на максимальном уровне.

По моему разумению модификатор flash это CVAVRина, а WinAVR ее не имеет, но может быть я ошибаюсь.
А вот выключать или оставлять warning(s) это ОЧЕНЬ большой грех.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.