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

Как видим, выигрыш не так уж велик.

Но он есть! :) И по скорости, и по размеру кода. Несмотря на несуразности в ISR. И не такой уж маленький. Почти 5% в первом случае и более 12 во втором. Представте, что проект занимает не 12 кил, а 15. Тут уже вопрос встает - "влезет/не влезет", а это серьезно.

Выигрыш по скорости - спорный вопрос. Что касается размера кода, процитирую:

Всегда должен быть какой-то запас. ... На развитие.

то есть - неправильно закладывать в проект кристалл, на котором программа едва уместится.

Кстати, для МК этого калибра размер проекта не такой маленький. Неужели можно так просто взять реальный проект и пересобрать другим пакетом?! Там же куча тулзозависимых вещей типа директив компилятора, расширенных ключевых слов и прочего. Т.е. требуется основательная доработка напильником.

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

 

Что непредсказуемого в кодогенерации у IAR?

В CodeVision имеем чёткие правила, как располагаются глобальные/локальные переменные, можно заранее сказать, какие регистры/флаги испортятся после тех или иных операций на С. В случае IAR этого уже нельзя с определённостью сказать на этапе написания программы, он распоряжается регистрами по своему усмотрению и в зависимости от опций проекта.

отлично интегрируется с ассемблером,

Не понял, что имеется в виду.

Просто примеры:

BOOL TickerNotExpired() {
 #asm("movw r30,_dwCounter")
 #asm("or r30,r31")
}

...

byte KeyPressed() {
 #asm
   lds r30,_key
   clr r31
   sts _key,r31
 #endasm
}

...

 byte b/*r16*/, m/*r17*/, sz/*r18*/, i/*r19*/;

   i = curr_zero;
   b = RxRadioBuf.u[i];
   m = RxFEC[i];
   #asm("swap r17")
   #asm("rol r17")
   #asm("swap r17")
   #asm("rol r16")
   if (PIN_RX) m |= 1;
   m &= 0x0F;
   RxFEC[i] = m;
   RxRadioBuf.u[i] = b;

...

 //memmove(&conf_buf,&conf_buf+1,sizeof(conf_buf)-1);
 i=0;
 #asm
   LDI  R26,LOW(_conf_buf+1)
   LDI  R27,HIGH(_conf_buf+1)
   LDI  R30,LOW(_conf_buf)
   LDI  R31,HIGH(_conf_buf)
 #endasm
 do {
   #asm
     ld r0,x+
     st z+,r0
   #endasm
 } while (++i<sizeof(conf_buf)-1);

 

а также лучше IAR'а использует аппаратные ресурсы AVR.

Опять, простите, не понял. Какие ресурсы? В чем "лучшесть"?

Пример: карта размещения переменных типичного проекта. Обратите внимание на размещение битовых переменных.

Variable                          Address   Size
f5ms                             GPIOR0.0    1/8
f1s                              GPIOR0.1    1/8
fNeedTransmit                    GPIOR0.2    1/8
thebit                           GPIOR0.3    1/8
failed                           GPIOR0.4    1/8
KeyCode                               90h      1
Digits                                91h      6
fNumberEntered                   GPIOR0.5    1/8
iTransmit                              R2      1
iTestKey                            R3,R4      2
bMatch                           GPIOR0.6    1/8
TestedKey_S7                           R5      1
i1s                                    R6      1
sreg_sv                                R7      1
r30_sv                                 R8      1
code                                  97h      8
last                                  9Fh      8

...

;16   thebit = FALSE; if (TCH_IN) thebit = TRUE;
    CBI  0x13,3
    SBIC 0x10,0
    SBI  0x13,3

 

Кстати, сравнивать эти два компилятора в некотором роде не совсем корректно - IAR несравненно богаче по возможностям - там есть ++. Это дорогого стОит. Предвижу возражение, что Вам это не надо. Не надо, так не надо. А мне надо. И весьма. Я не агитирую за IAR, не предлагаю бросить используемый инструмент и переходить на него. Смысл всего сказанного в том, что на сегодняшний день в целом IAR (при всех его недостатках) объективно является  лучшим пакетом для AVR.

Бесспорно, IAR - самый мощный компилятор для AVR, другое дело, что преимущества IAR'а проявляются на больших проектах, писать же код для какой-нибудь tiny2313, на мой взгляд, удобнее и выгоднее на CV.

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


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

Непонятно, как Вы объявили переменные. Нужно, чтобы они были вместе объявлены, чтобы компилятор видел их одновременно. Если они в разных файлах объявлены, то, ессно, компилятор тут ничего поделать не сможет (даже если они реально попали в предел 64 байта один от другого), т.к. просто не знает, что они рядом и не может рулить их размещением.

 

глобальные (видимые всем - не статик) переменные я объявляю в отдельном файле (думаю это рационально) global.c

 

...
unsigned char blink_timer = 0;
unsigned char Blink_Buffer[18];
...

 

аналогино с external обявляю в global.h , что и подключаю где надо.

#include  "iom8535.h"
#include  "global.h"

#pragma vector = TIMER2_OVF_vect
__interrupt void system_timer(void)
{
 blink_timer++;
 mySREG++;
}

Может ли это быть причиной непонимания компилятора?

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


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

Непонятно, как Вы объявили переменные. Нужно, чтобы они были вместе объявлены, чтобы компилятор видел их одновременно. Если они в разных файлах объявлены, то, ессно, компилятор тут ничего поделать не сможет (даже если они реально попали в предел 64 байта один от другого), т.к. просто не знает, что они рядом и не может рулить их размещением.

глобальные (видимые всем - не статик) переменные я объявляю в отдельном файле (думаю это рационально) global.c

Рациональность - понятие часто непонятное. :) Объявлять переменные надо там, где они по смыслу нужны. Т.е. в тех модулях (единицах компиляции), которые для них основные. Для вытаскивания всех их в один файл должны быть какие-то отдельные причины.

 

...
unsigned char blink_timer = 0;
unsigned char Blink_Buffer[18];
...

 

аналогино с external обявляю в global.h , что и подключаю где надо.

#include  "iom8535.h"
#include  "global.h"

#pragma vector = TIMER2_OVF_vect
__interrupt void system_timer(void)
{
 blink_timer++;
 mySREG++;
}

Может ли это быть причиной непонимания компилятора?

Так и есть. У Вас обе переменные объявлены в другой единице компиляции, и компилятор просто не "видит" их - откуда ему знать при компиляции этого файла, что оба объекта находятся рядом? Он этого не знает, т.к. не сам их тут распределяет, поэтому не может делать никаких предположений об их взаимом положении, поэтому вынужден генерить при каждом обращении полный код.

 

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

 

Подобные особенности архитектуры AVR и компилятора IAR для него в некоторой степени подталкивают пользователя к использованию агрегатных типов и объектов классов. :)

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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