Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: вопрос по IARy
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
LeoLabs
Компилю текст:
#pragma vector = TIMER2_OVF_vect
__interrupt void system_timer()
{
blink_timer++;
}

и выдает:

#pragma vector = TIMER2_OVF_vect
__interrupt void system_timer()
ST -Y, R31
ST -Y, R30
ST -Y, R17
ST -Y, R16
IN R17, 0x3F
}
blink_timer++;
LDI R30, LOW(blink_timer)
LDI R31, (blink_timer) >> 8
LD R16, Z
INC R16
ST Z, R16
}
OUT 0x3F, R17
LD R16, Y+
LD R17, Y+
LD R30, Y+
LD R31, Y+
RETI

при максимальной оптимизации.
Не пойму почему бы ему не использовать STS? или я что-то не так пишу или хваленый иар не спосбен на подвиги?
ЧТО Я НЕ ТАК ДЕЛАЮ?
vet
Цитата(LeoLabs @ Jun 16 2005, 13:30)
Не пойму почему бы ему не использовать STS? или я что-то не так пишу или хваленый иар не спосбен на подвиги?
*


Похоже, всё-таки не способен...

Вот как это скомпилировал CodeVision, для сравнения:
Код
26 char blink_timer;
;27
;28 // Timer 0 output compare A interrupt service routine
;29 interrupt [TIM0_COMPA] void timer0_compa_isr(void)
;30 {

       .CSEG
_timer0_compa_isr:
       ST   -Y,R30
       IN   R30,SREG
;31 blink_timer++;
       INC  R2
;32 }
       OUT  SREG,R30
       LD   R30,Y+
       RETI


вариант с переменной в памяти:
Код
;26 volatile char blink_timer;
_blink_timer:
       .BYTE 0x1
;27
;28 // Timer 0 output compare A interrupt service routine
;29 interrupt [TIM0_COMPA] void timer0_compa_isr(void)
;30 {

       .CSEG
_timer0_compa_isr:
       ST   -Y,R30
       IN   R30,SREG
       ST   -Y,R30
;31 blink_timer++;
       LDS  R30,_blink_timer
       SUBI R30,-LOW(1)
       STS  _blink_timer,R30
;32 }
       LD   R30,Y+
       OUT  SREG,R30
       LD   R30,Y+
       RETI

LeoLabs
не верю! ну не может такого быть!
vet
Ещё немного сравнительных результатов от ICC v6.30C и GCC 20040720 соответственно:
Код
; char blink_timer;
; #pragma interrupt_handler timer:4 timer:5
; void timer() {
    .dbline 44
;   blink_timer++;
    lds R24,_blink_timer
    subi R24,255  ; addi 1
    sts _blink_timer,R24
    .dbline -2
L7:
    ld R24,y+
    out 0x3f,R24
    ld R25,y+
    ld R24,y+
    .dbline 0; func end
    reti

Код
;char blink_timer;
;SIGNAL (SIG_OVERFLOW1)
;{
;  blink_timer++;
;}

.LM1:
/* prologue: frame size=0 */
    push __zero_reg__
    push __tmp_reg__
    in __tmp_reg__,__SREG__
    push __tmp_reg__
    clr __zero_reg__
    push r24
/* prologue end (size=6) */
    .stabn 68,0,69,.LM2-__vector_14
.LM2:
    lds r24,blink_timer
    subi r24,lo8(-(1))
    sts blink_timer,r24
/* epilogue: frame size=0 */
    pop r24
    pop __tmp_reg__
    out __SREG__,__tmp_reg__
    pop __tmp_reg__
    pop __zero_reg__
    reti
AlexOr
Нет слов.
Только маты.
AlexOr
Кстати,
LDI R30, LOW(blink_timer)
LDI R31, (blink_timer) >> 8
LD R16, Z
INC R16
ST Z, R16

занимает столько же места как и

LDS R30,_blink_timer
SUBI R30,-LOW(1)
STS _blink_timer,R30

но последнее в прерывании намного выгоднее (быстрее и менее расходно по регистрам).
Черт меня дернул сделать проект на IAR.
Сейчас взглянул на прологи/эпилоги и Ужаснулся.

Вопрос вдогонку:
Этот замечательный CodeVision умеет также легко работать с EEPROM как IAR?
vet
Цитата(AlexOr @ Jun 20 2005, 17:41)
Кстати,
LDI R30, LOW(blink_timer)
LDI R31, (blink_timer) >> 8
LD R16, Z
INC R16
ST Z, R16

занимает столько же места как и

LDS  R30,_blink_timer
SUBI R30,-LOW(1)
STS  _blink_timer,R30

но последнее в прерывании намного выгоднее (быстрее и менее расходно по регистрам).
Черт меня дернул сделать проект на IAR.
Сейчас взглянул на прологи/эпилоги и Ужаснулся.

Вопрос вдогонку:
Этот замечательный CodeVision умеет также легко работать с EEPROM как IAR?
*


Да, практически так же:
Код
 eeprom struct tag_conf {
   char block;
   char RegionString[16];
   char data[64];
 } eeConf;

unsigned int char CheckEEPROM(void)
{
 //вычисление контрольной суммы структуры eeConf в EEPROM
 char eeprom *p;
 unsigned int sum;
 char i;

 sum = 0;
 p = &eeConf;
 for (i=0; i<sizeof(eeConf); i++) sum += *p++;
 return sum;
}
LeoLabs
Задал этот вопрос (почему через указатели а не через STS) разработчикам, жду ответа, но т.к. у меня нет лицензии ждать придется долго, если вообще дождусь.
Но что я накопал: в applications notes лежит pdfник "Efficient C Coding for AVR".
наткнулся я там на следующее:

When accessing the global variables as structures the compiler is using the Z-pointer and the LDD and STD (Load/store with displacement) instructions to access the data. When the global variables are accessed without structures the compiler use LDS and STS (Load/store direct to SRAM).

, что по-русски значит: если переменная объявлена как структура, то компилятор будет использовать указатели, если нет то через LDS и STS.

вот такие дела.

однако переменная у меня объявлена:
unsigned char blink_timer = 0;
где не вижу я структуры.

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

P.S. pdfник "Efficient C Coding for AVR" ориентирован на иаровский компилятор.
dxp
Цитата(AlexOr @ Jun 20 2005, 19:41)
Кстати,
LDI R30, LOW(blink_timer)
LDI R31, (blink_timer) >> 8
LD R16, Z
INC R16
ST Z, R16

занимает столько же места как и

LDS  R30,_blink_timer
SUBI R30,-LOW(1)
STS  _blink_timer,R30

но последнее в прерывании намного выгоднее (быстрее и менее расходно по регистрам).


Это до тех пор, пока у Вас единственное обращение к однобайтовой переменной. Сделайте эту переменную интом, выигрыш не замедлит проявиться. Или, к примеру, если там не к одной переменной обращение, а к нескольким, лежащим в пределах досягаемости указателя (для этого их надо объявлять вместе). Или к структуре обращение. Словом, когда ситуация уходить от первого простейшего случая, результат меняется

Цитата(AlexOr @ Jun 20 2005, 19:41)
Черт меня дернул сделать проект на IAR.
Сейчас взглянул на прологи/эпилоги и Ужаснулся.
*

Не стОит так переживать из-за этой мелочи. Она погоду не делает совершенно. Наоборот, способность IAR'а приводить обращения к косвенным дает очень приличный выигрыш на деле. AVR-GCC имеет весьма неплохой кодогенератор, но он проигрывает IAR'у именно на этом моменте - AVR-GCC злоупотребляет lds/sts, из-за чего размер кода там получается больше.

Не знаю, как сегодня обстоит дело, но некоторое время назад остальные компляторы - CodeVision, ImageCraft уступали по качеству кодогенерации обоим - и IAR'у, и AVR-GCC. Может сейчас что-то изменилось, но сомневаюсь. Сравнивать надо не на коде из трех строк, а на реальных проектах. Попробуйте, увидите, что IAR рулит. smile.gif
LeoLabs
[/quote]

Не стОит так переживать из-за этой мелочи. Она погоду не делает совершенно. Наоборот, способность IAR'а приводить обращения к косвенным дает очень приличный выигрыш на деле. AVR-GCC имеет весьма неплохой кодогенератор, но он проигрывает IAR'у именно на этом моменте - AVR-GCC злоупотребляет lds/sts, из-за чего размер кода там получается больше.

*

[/quote]

Но прерывание ИАР слишком раздул, а надо то тока инкрементировать глобальную переменную. кстати это системный таймер и я думаю, что там не одна переменная может быть, но и несколько, а если они не подряд - то работа с указателями это только проигрыш.
dxp
Цитата(LeoLabs @ Jun 21 2005, 13:08)
Но прерывание ИАР слишком раздул, а надо то тока инкрементировать глобальную переменную. кстати это системный таймер и я думаю, что там не одна переменная может быть, но и несколько, а если они не подряд - то работа с указателями это только проигрыш.
*

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

Переменным не обязательно быть подряд. Им достаточно быть в пределах досягаемости указателя - 64 байта. Для того, чтобы они были вместе, достаточно их объявить вместе и включить оптимизацию clustering variables, которая, afair, включена по умолчанию.
LeoLabs
Цитата(dxp @ Jun 21 2005, 14:36)
Цитата(LeoLabs @ Jun 21 2005, 13:08)
Но прерывание ИАР слишком раздул, а надо то тока инкрементировать глобальную переменную. кстати это системный таймер и я думаю, что там не одна переменная может быть, но и несколько, а если они не подряд - то работа с указателями это только проигрыш.
*

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

Переменным не обязательно быть подряд. Им достаточно быть в пределах досягаемости указателя - 64 байта. Для того, чтобы они были вместе, достаточно их объявить вместе и включить оптимизацию clustering variables, которая, afair, включена по умолчанию.
*



ну что ж: вот расстояние между байтами 19, а как обрабатывается - при полной оптимизации, включая Clustering of variables.

5 #pragma vector = TIMER2_OVF_vect

\ In segment CODE, align 2, keep-with-next
6 __interrupt void system_timer(void)
\ system_timer:
7 {
\ 00000000 93FA ST -Y, R31
\ 00000002 93EA ST -Y, R30
\ 00000004 931A ST -Y, R17
\ 00000006 930A ST -Y, R16
\ 00000008 B71F IN R17, 0x3F
8 blink_timer++;
\ 0000000A .... LDI R30, 0x66
\ 0000000C .... LDI R31, 0x01
\ 0000000E 8100 LD R16, Z
\ 00000010 9503 INC R16
\ 00000012 8300 ST Z, R16
9 mySREG++;
\ 00000014 .... LDI R30, 0x79
\ 00000016 .... LDI R31, 0x01
\ 00000018 8100 LD R16, Z
\ 0000001A 9503 INC R16
\ 0000001C 8300 ST Z, R16
10
}
\ 0000001E BF1F OUT 0x3F, R17
\ 00000020 9109 LD R16, Y+
\ 00000022 9119 LD R17, Y+
\ 00000024 91E9 LD R30, Y+
\ 00000026 91F9 LD R31, Y+
\ 00000028 9518 RETI


В чем дело то? может у меня завихрения?
да и в прерываниях, которые очень критичны к скорости, совсем ни к чему указатели. а по поводу памяти - то ее почти всегда хватит, напротив быстродействия всегда мало.
vet
Цитата(dxp @ Jun 21 2005, 10:35)
Это до тех пор, пока у Вас единственное обращение к однобайтовой переменной. Сделайте эту переменную интом, выигрыш не замедлит проявиться. Или, к примеру, если там не к одной переменной обращение, а к нескольким, лежащим в пределах досягаемости указателя (для этого их надо объявлять вместе). Или к структуре обращение. Словом, когда ситуация уходить от первого простейшего случая, результат меняется

Цитата(dxp @ Jun 21 2005, 10:35)
Цитата(AlexOr @ Jun 20 2005, 19:41)
Черт меня дернул сделать проект на IAR.
Сейчас взглянул на прологи/эпилоги и Ужаснулся.
*

Не стОит так переживать из-за этой мелочи. Она погоду не делает совершенно. Наоборот, способность IAR'а приводить обращения к косвенным дает очень приличный выигрыш на деле. AVR-GCC имеет весьма неплохой кодогенератор, но он проигрывает IAR'у именно на этом моменте - AVR-GCC злоупотребляет lds/sts, из-за чего размер кода там получается больше.

Не знаю, как сегодня обстоит дело, но некоторое время назад остальные компляторы - CodeVision, ImageCraft уступали по качеству кодогенерации обоим - и IAR'у, и AVR-GCC. Может сейчас что-то изменилось, но сомневаюсь. Сравнивать надо не на коде из трех строк, а на реальных проектах. Попробуйте, увидите, что IAR рулит. smile.gif
*



Прямо сейчас скомпилировал реальный проект средних размеров на меге162.
Результаты:
Код
                    speed    size
CodeVision:        12956    12580
IAR:               12394    11182

Как видим, выигрыш не так уж велик.
Лично меня CodeVision привлекает тем, что генерирует предсказуемый код, отлично интегрируется с ассемблером, а также лучше IAR'а использует аппаратные ресурсы AVR.
dxp
Цитата(LeoLabs @ Jun 21 2005, 13:57)
ну что ж: вот расстояние между байтами 19, а как обрабатывается - при полной оптимизации, включая Clustering of variables.

Непонятно, как Вы объявили переменные. Нужно, чтобы они были вместе объявлены, чтобы компилятор видел их одновременно. Если они в разных файлах объявлены, то, ессно, компилятор тут ничего поделать не сможет (даже если они реально попали в предел 64 байта один от другого), т.к. просто не знает, что они рядом и не может рулить их размещением. А вот как это получается:
Код
char blink_timer1;
char buf[200];
char blink_timer2;

#pragma vector = TIMER2_OVF_vect
__interrupt void system_timer()
{
   blink_timer1++;
   blink_timer2++;
}

результат:
__interrupt void system_timer()
       ??system_timer:
{
93FA               ST      -Y, R31
93EA               ST      -Y, R30
931A               ST      -Y, R17
930A               ST      -Y, R16
B71F               IN      R17, 0x3F
   blink_timer1++;
....               LDI     R30, LOW(blink_timer1)
....               LDI     R31, (blink_timer1) >> 8
8100               LD      R16, Z
9503               INC     R16
8300               ST      Z, R16
   blink_timer2++;
8101               LDD     R16, Z+1
9503               INC     R16
8301               STD     Z+1, R16
}
BF1F               OUT     0x3F, R17
9109               LD      R16, Y+
9119               LD      R17, Y+
91E9               LD      R30, Y+
91F9               LD      R31, Y+
9518               RETI

Заметьте, что смещение при обращении ко второй переменной равно 1, несмотря на то, что при объявлении между ними массив в 200 байт. Т.е. компилятор эффективно расположил обе переменные последовательно - имеет право. Это и есть clustering variables. Т.е. достаточно, чтобы оба объявления были доступны компилятору в одной единице компиляции.


Цитата(LeoLabs @ Jun 21 2005, 13:57)
да и в прерываниях, которые очень критичны к скорости, совсем ни к чему указатели. а по поводу памяти - то ее почти всегда хватит, напротив быстродействия всегда мало.
*

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

Об этом их backfire следует сообщить разработчикам, чтобы они в дальнейшем поработали над поведением компилятора в ISR. Хотя, думается, что если до сих пор не исправили, то это по той причине, что никого [из пользователей] этот факт особенно не волнует. Ведь и в самом деле, если работоспособность и устойчивость системы зависит от пары тактов, то тут явно что-то не то в дизайне. Всегда должен быть какой-то запас. На устойчивость. На развитие. В конечном итоге все упирается в "успевает - не успевает". Если один успевает на три такта быстрее, чем успевает другой, то конечный результат будет одним и тем же.

Понятно, что хочется получить результат по максисмуму, но надо быть реалистами. Ни один МК, ни один компилятор не может быть лучше других по всем пунктам. Если бы это было так, то мы сейчас уже давно имели один МК и один компилятор для него.. smile.gif По совокупности надо смотреть. И сравнивать тоже по совокупности.
dxp
Цитата(vet @ Jun 21 2005, 15:04)
Прямо сейчас скомпилировал реальный проект средних размеров на меге162.
Результаты:
Код
                    speed    size
CodeVision:        12956    12580
IAR:               12394    11182

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

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

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

Цитата(vet @ Jun 21 2005, 15:04)
Лично меня CodeVision привлекает там, что генерирует предсказуемый код,

Что непредсказуемого в кодогенерации у IAR?
Цитата(vet @ Jun 21 2005, 15:04)
отлично интегрируется с ассемблером,

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

Цитата(vet @ Jun 21 2005, 15:04)
а также лучше IAR'а использует аппаратные ресурсы AVR.
*

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

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

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

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

Выигрыш по скорости - спорный вопрос. Что касается размера кода, процитирую:
Цитата(dxp @ Jun 21 2005, 13:25)
Всегда должен быть какой-то запас. ... На развитие.

то есть - неправильно закладывать в проект кристалл, на котором программа едва уместится.
Цитата(dxp @ Jun 21 2005, 13:25)
Кстати, для МК этого калибра размер проекта не такой маленький. Неужели можно так просто взять реальный проект и пересобрать другим пакетом?! Там же куча тулзозависимых вещей типа директив компилятора, расширенных ключевых слов и прочего. Т.е. требуется основательная доработка напильником.

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

Цитата(dxp @ Jun 21 2005, 13:25)
Что непредсказуемого в кодогенерации у IAR?

В CodeVision имеем чёткие правила, как располагаются глобальные/локальные переменные, можно заранее сказать, какие регистры/флаги испортятся после тех или иных операций на С. В случае IAR этого уже нельзя с определённостью сказать на этапе написания программы, он распоряжается регистрами по своему усмотрению и в зависимости от опций проекта.
Цитата(dxp @ Jun 21 2005, 13:25)
Цитата(vet @ Jun 21 2005, 15:04)
отлично интегрируется с ассемблером,

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

Просто примеры:
Код
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);


Цитата(dxp @ Jun 21 2005, 13:25)
Цитата(vet @ Jun 21 2005, 15:04)
а также лучше 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


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

Бесспорно, IAR - самый мощный компилятор для AVR, другое дело, что преимущества IAR'а проявляются на больших проектах, писать же код для какой-нибудь tiny2313, на мой взгляд, удобнее и выгоднее на CV.
LeoLabs
Цитата(dxp @ Jun 21 2005, 16:05)
Непонятно, как Вы объявили переменные. Нужно, чтобы они были вместе объявлены, чтобы компилятор видел их одновременно. Если они в разных файлах объявлены, то, ессно, компилятор тут ничего поделать не сможет (даже если они реально попали в предел 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++;
}

Может ли это быть причиной непонимания компилятора?
dxp
Цитата(LeoLabs @ Jun 22 2005, 07:24)
Цитата(dxp @ Jun 21 2005, 16:05)

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


Цитата(LeoLabs @ Jun 22 2005, 07:24)
глобальные (видимые всем - не статик) переменные я объявляю в отдельном файле (думаю это рационально) global.c

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

Цитата(LeoLabs @ Jun 22 2005, 07:24)
Код
...
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 для него в некоторой степени подталкивают пользователя к использованию агрегатных типов и объектов классов. smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.