WinAVR

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From Russian to

Threaded View
Hi All!

Hачинаю работать с микроконтроллерами AVR.
В качестве среды разработки выбрал WinAVR 20030913
и симулятор из AVRStudio.

Столкнулся со странным "глюком" компилятора.
Кто нибуддь может прокомментировать:

Пишу:

void delay1(){
unsigned int i;
    for(i=0xFF;i!=0;i--);
}

void delay2(){
unsigned int i;
    for(i=0x8FFF;i!=0;i--);
}

Получаю:

20:           for(i=0xFF;i!=0;i--);
+00000041:   EF8F        SER     R24              Load immediate
+00000042:   E090        LDI     R25,0x00         Load immediate
+00000043:   970F        SBIW    R24,0x0F         Subtract immediate from
word
+00000044:   F7F1        BRNE    -0x02            Branch if status flag
cleared
21:       }
+00000045:   9508        RET                      Subroutine return
@00000046: delay2
25:           for(i=0x8FFF;i!=0;i--);
+00000046:   EF8F        SER     R24              Load immediate
+00000047:   E89F        LDI     R25,0x8F         Load immediate
+00000048:   9701        SBIW    R24,0x01         Subtract immediate from
word
+00000049:   F7F1        BRNE    -0x02            Branch if status flag
cleared
26:       }
+0000004A:   9508        RET                      Subroutine return

В подпрограмме delay1 цикл выполняется только 17 раз.
delay2 - все в порядке.

Интересует много ли "глюков" в компиляторе и можно ли им пользоваться
в практической работе?

Сергей Авдюшин.




WinAVR
Привет Sergej!

05 Apr 04 10:49, Sergej S. Avdushin писал All:

 SA> Столкнулся со странным "глюком" компилятора.
 SA> Кто нибуддь может прокомментировать:

 SA> Пишу:

 SA> void delay1(){
 SA> unsigned int i;
 SA>     for(i=0xFF;i!=0;i--);
 SA> }

 SA> void delay2(){
 SA> unsigned int i;
 SA>     for(i=0x8FFF;i!=0;i--);
 SA> }

 SA> Получаю:

    [выкушено]

 SA> В подпрограмме delay1 цикл выполняется только 17 раз.
 SA> delay2 - все в порядке.

    Оптимизацию выключить не забыл (если она в твоем компиляторе выключается)?

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Слепой Пью, Глухой Ем...

Re: WinAVR
Hi Alex!

Quoted text here. Click to load it
выключается)?

Пробовал, то же самое.

Всего наилучшего,
Сергей Авдюшин.




WinAVR
Привет Sergej!

05 Apr 04 14:26, Sergej S. Avdushin писал All:

 >>     Оптимизацию выключить не забыл (если она в твоем компиляторе
 SA> выключается)?

 SA> Пробовал, то же самое.

    При отсутствии volatile в определениях твоих переменных вряд ли можно
упрекать компилятор в том, что он сократил не дающий эффукта код. ИМХО такое
поведение все-таки нельзя называть глюком, если в документации не написано
обратного...

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Если долго думать одни и те же мысли, они становятся грязными.

Re: WinAVR
Hi Oleksandr!
Quoted text here. Click to load it

Пробовал, получил ассемблерный листинг на нескольких страницах. :)

Quoted text here. Click to load it
Так получается очень хорошо.
Quoted text here. Click to load it

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

Спасибо!
Сергей.




WinAVR
Привет Sergej!

06 Apr 04 11:29, Sergej S. Avdushin писал All:

 SA> Вот вот. Про это и был вопрос: можно ли им пользоваться, или игрушка.
 SA> Всякий раз, когда начинаешь пользоваться новым средством, из него
 SA> лезет всякая ерунда. Потом притерается и "глюки" пропадают (пчти).

    Я тебя научу. Всякий раз перед тем как начать пользоваться новым средством,
изучи документацию на него. Тогда "глюки" и не возникнут. :)

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Чудо-йогурт Био. Чемпион среди какао.

WinAVR
Привет Sergej!

05 Apr 04 14:26, Sergej S. Avdushin писал All:

 >>     Оптимизацию выключить не забыл (если она в твоем компиляторе
 SA> выключается)?

 SA> Пробовал, то же самое.

    Я только сейчас сообразил, что сабж - это gcc. Правильно? Тогда смотрим,
какой код генерится из товего примера без оптимизации:

==============================
/* prologue end (size10%) */
        ldi r24,lo8(255)
        ldi r25,hi8(255)
        std Y+2,r25
        std Y+1,r24
.L2:
        ldd r24,Y+1
        ldd r25,Y+2
        sbiw r24,0
        brne .L4
        rjmp .L1
.L4:
        ldd r24,Y+1
        ldd r25,Y+2
        sbiw r24,1
        std Y+2,r25
        std Y+1,r24
        rjmp .L2
.L1:
/* epilogue: frame size=2 */
===============================

    А вот это с -O:

===============================
/* prologue end (size=0) */
        ldi r24,lo8(255)
        ldi r25,hi8(255)
.L6:
        sbiw r24,1
        brne .L6
/* epilogue: frame size=0 */
===============================

    А вот это с -O2, -O3 и -Os:

===============================
/* prologue end (size=0) */
        ldi r24,lo8(255)
        ldi r25,hi8(255)
.L6:
        sbiw r24,15
        brne .L6
/* epilogue: frame size=0 */
    ....................
/* prologue end (size=0) */
        ldi r24,lo8(-28673)
        ldi r25,hi8(-28673)
.L44:
        sbiw r24,1
        brne .L44
/* epilogue: frame size=0 */
===============================

    Так что "Hе верю" (с) что "Пробовал, то же самое".

    Hа самом же деле тебе нужна опция -fno-strength-reduce, которая как раз
запрещает оптимизатору сокращать количество проходов цикла.

    Для того чтобы разговор был предметным:
alx2% avr-gcc --version
avr-gcc (GCC) 3.3.1 20030707 (prerelease)
Copyright (C) 2003 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.

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Я удалю твою жажду. Без возможности восстановления.

Re: WinAVR
Hi Alex!

Quoted text here. Click to load it
смотрим,
Quoted text here. Click to load it

<.......... грызь длиииинный листинг.....>

Использую

avr-gcc (GCC) 3.3.2
Copyright (C) 2003 Free Software Foundation, Inc.

В makefile:
# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = 0

Исходник:
void xxxx(){
 unsigned int i;
     for(i=0x5FF;i!=0;i--);
}

Результат из симулятора AVR

@00000041: xxxx
- ----
C:\WinAVR\UART1/UART1.c ----------------------------------------------------
- ------------------
24:            for(i=0x5FF;i!=0;i--)
+00000041:   EF8F        SER     R24              Load immediate
+00000042:   E095        LDI     R25,0x05         Load immediate
+00000043:   9705        SBIW    R24,0x05         Subtract immediate from
word
+00000044:   F7F1        BRNE    -0x02            Branch if status flag
cleared
27:       }
+00000045:   9508        RET                      Subroutine return

Quoted text here. Click to load it


Спасибо!
Сергей Авдюшин.




WinAVR
Привет Sergej!

06 Apr 04 16:19, Sergej S. Avdushin писал All:

 SA> Использую

 SA> avr-gcc (GCC) 3.3.2

 SA> В makefile:
 SA> # Optimization level, can be [0, 1, 2, 3, s]. 0 turns off
 SA> # (Note: 3 is not always the best optimization level. See avr-libc
 SA> OPT = 0

 SA> Исходник:
 SA> void xxxx(){
 SA>  unsigned int i;
 SA>      for(i=0x5FF;i!=0;i--);
 SA> }

 SA> Результат из симулятора AVR

    [ тоже покушано ]

    Я же не телепат, ты покажи, с какими параметрами компилятор вызывается.
Откуда мне знать, что там у тебя в Makefile еще написано...

    И покажи результат выполнения avr-gcc -O0 -S test.c

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Пирожок вареный с вареньем.

Re: WinAVR
Hi Alex!

Quoted text here. Click to load it
вызывается.
Quoted text here. Click to load it

Если делать так, то получается то же самое, (длинный листинг), как ты
приводил в предидущем письме.
Я (ошибочно) полагал, что строчки в makefile
Quoted text here. Click to load it
делают то же само, что и указанный тобою ключ в коммандной строке.


Всего наилучшего,
спасибо,
Сергей Авдюшин.




Re: WinAVR
5-Apr-04 09:49 Sergej S. Avdushin wrote to All:

SA> void delay1(){
SA> unsigned int i;
SA>     for(i=0xFF;i!=0;i--);
SA> }
Компилятор просто помог выполнить тебе досчёт от  0xFF до 0 побыстрее :-)
Так как "внешне" единственная работа цикла - это декрементировать i
до нуля.

Можно объявить i как volatile, но это дело заведёт её на стеке
со всеми вытекающими.
Можно в теле цикла поставить
 __asm__ __volatile__ ("nop");


SA> Интересует много ли "глюков" в компиляторе и можно ли им пользоваться
SA> в практической работе?
 1) Это был не глюк. Это фича такая.
 2) Ну так пользуюсь же.

wbr,



--
/* Oleksandr Redchuk, Brovary, Ukraine */
/* real '\x40' real '\x2E' kiev '\x2E' ua     */


WinAVR
Здравствуй, Sergej!

Monday April 05 2004 10:49, you (2:5020/52) wrote to All:

 SA> Пишу:

 SA> void delay1(){
 SA> unsigned int i;
 SA>     for(i=0xFF;i!=0;i--);

Вставь в тело цикла NOP и будет тебе щастье...

asm volatile ("nop");

 SA> }

 SA>  и можно ли им пользоваться в практической работе?

Да. С нахваливаемым IAR С  я не pаботал, но image craft, в сpавнении с gcc,
худший ваpиант. Это мое скpомное мнение, котоpое может не совпадать со скpомным
мнением почтенной публики.

p.s. Если нужна точная задеpжка - макpос удобнее.

something.h
-----------
void _delay (unsigned int __count)
{
asm volatile ( "1: sbiw %0,1" "\n\t"
                "brne 1b": "=w" (__count): "0" (__count) );
}


something.c
-----------
...
                //   Fclk16%MHz
_delay (1);     // 250 нс задеpжка
_delay (4);     // 1 мкс задеpжка
...


Alex


WinAVR
Thu, 08 Apr 2004 02:07:34 +0400 Alex Gavrikov wrote to Sergej S. Avdushin:


[...]

AG> Да. С нахваливаемым IAR С  я не pаботал, но image craft, в сpавнении с gcc,
AG> худший ваpиант. Это мое скpомное мнение, котоpое может не совпадать со
AG> скpомным мнением почтенной публики.

AG> p.s. Если нужна точная задеpжка - макpос удобнее.

    В ИАРе есть специальная встроенная функция __delay_cycles(unsigned long
int), при вызове которой компилятор генерит код (цикл и нопы), точно формирующий
требуемую задержку. Единственное ограничение там, это то, что аргумент ограничен
сверху неким числом порядка то ли 20000, то ли 200000. Но это не создает
проблем. :)

--
H.Z.

harry.zhurov<antispam::at>ngs<antispam::period>ru

We've slightly trimmed the long signature. Click to see the full one.
Re: WinAVR
Здравствуй, Harry!

Thursday April 08 2004 09:36, you (2:5020/400) wrote to me:

 AG>> p.s. Если нужна точная задеpжка - макpос удобнее.
 HZ>     В ИАРе есть специальная встроенная функция
 HZ> __delay_cycles(unsigned long int),

В gcc libc есть тоже:
delay (uint8_t mS); // в миллисекундах

Alex


Re: WinAVR
Hello, Alex!
You wrote to Harry Zhurov on Sun, 11 Apr 2004 02:43:41 +0400:

 AG>>> p.s. Если нужна точная задеpжка - макpос удобнее.
 HZ>>     В ИАРе есть специальная встроенная функция
 HZ>> __delay_cycles(unsigned long int),

 AG> В gcc libc есть тоже:
 AG> delay (uint8_t mS); // в миллисекундах

    Подобные функции _обычно_ обеспечивают задержку с точностью до кванта
планировщика (десятки мс).

With best regards,
            Alexander Derazhne.



WinAVR
Sun, 11 Apr 2004 02:43:41 +0400 Alex Gavrikov wrote to Harry Zhurov:


AG>>> p.s. Если нужна точная задеpжка - макpос удобнее.
HZ>>     В ИАРе есть специальная встроенная функция
HZ>> __delay_cycles(unsigned long int),

AG> В gcc libc есть тоже:
AG> delay (uint8_t mS); // в миллисекундах

    О! А как это оно к миллисекундам привязывается? Откуда компилятор знает
сколько тактов миллисекунда?

--
H.Z.

harry.zhurov<antispam::at>ngs<antispam::period>ru

We've slightly trimmed the long signature. Click to see the full one.
Re: WinAVR
Привет Harry!

12 Apr 04 09:13, Harry Zhurov писал Alex Gavrikov:

 AG>> В gcc libc есть тоже:
 AG>> delay (uint8_t mS); // в миллисекундах

 HZ>     О! А как это оно к миллисекундам привязывается? Откуда компилятор
 HZ> знает сколько тактов миллисекунда?

    В avr-libc есть два макроса:

/* 8-bit count, 3 cycles/loop */
static __inline__ void
_delay_loop_1(uint8_t __count)
{
        asm volatile (
                "1: dec %0" "\n\t"
                "brne 1b"
                : "=r" (__count)
                : "0" (__count)
        );
}

/* 16-bit count, 4 cycles/loop */
static __inline__ void
_delay_loop_2(uint16_t __count)
{
        asm volatile (
                "1: sbiw %0,1" "\n\t"
                "brne 1b"
                : "=w" (__count)
                : "0" (__count)
        );
}

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Hе место портит человека, а человек место.

WinAVR
Mon, 12 Apr 2004 13:02:14 +0400 Alex Mogilnikov wrote to Harry Zhurov:

AM> 12 Apr 04 09:13, Harry Zhurov писал Alex Gavrikov:

AG>>> В gcc libc есть тоже:
AG>>> delay (uint8_t mS); // в миллисекундах

HZ>>     О! А как это оно к миллисекундам привязывается? Откуда компилятор
HZ>> знает сколько тактов миллисекунда?

AM>     В avr-libc есть два макроса:

AM> /* 8-bit count, 3 cycles/loop */
AM> static __inline__ void
AM> _delay_loop_1(uint8_t __count)
AM> {
AM>         asm volatile (
AM>                 "1: dec %0" "\n\t"
AM>                 "brne 1b"
AM>                 : "=r" (__count)
AM>                 : "0" (__count)
AM>         );
AM> }

AM> /* 16-bit count, 4 cycles/loop */
AM> static __inline__ void
AM> _delay_loop_2(uint16_t __count)
AM> {
AM>         asm volatile (
AM>                 "1: sbiw %0,1" "\n\t"
AM>                 "brne 1b"
AM>                 : "=w" (__count)
AM>                 : "0" (__count)
AM>         );
AM> }


    Ну, а миллисекунды-то тут где?

--
H.Z.

harry.zhurov<antispam::at>ngs<antispam::period>ru

We've slightly trimmed the long signature. Click to see the full one.
Re: WinAVR
Привет Harry!

12 Apr 04 17:25, Harry Zhurov писал Alex Mogilnikov:

 AM>>     В avr-libc есть два макроса:

 HZ>     Hу, а миллисекунды-то тут где?

    Я про миллисекунды ничего не говорил. Кому нужна задержка, тот сам
посчитает. Если захочет, конечно. :)

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Посетители должны общаться по сети.

Re: WinAVR
Здравствуй, Harry!

Monday April 12 2004 09:13, you (2:5020/400) wrote to me:

 AG>> В gcc libc есть тоже:
 AG>> delay (uint8_t mS); // в миллисекундах

 HZ>     О! А как это оно к миллисекундам привязывается? Откуда компилятор
 HZ> знает сколько тактов миллисекунда?

Увы мне! Я несколько пpогнал. В заголовочных файлах есть только два макpоса,
котоpые пpивел Alex Mogilnikov. А то, котоpый в миллисекундах, ниже.
С пpопозалами насчет пpеодоления тpаблов. Думаю, что офоpмить сие аки макpос
не сложно.

Кусочек из мана:

Macro definitions will include the same assembler code whenever they are
referenced. This may not be acceptable for larger routines. In this case
you may define a C stub function, containing nothing other than your
assembler code.

void delay(uint8_t ms)
{
uint16_t cnt;
asm volatile (
"\n"
"L_dl1%=:" "\n\t"
"mov %A0, %A2" "\n\t"
"mov %B0, %B2" "\n"
"L_dl2%=:" "\n\t"
"sbiw %A0, 1" "\n\t"
"brne L_dl2%=" "\n\t"
"dec %1" "\n\t"
"brne L_dl1%=" "\n\t"
: "=&w" (cnt)
: "r" (ms), "r" (delay_count)
);
}

The purpose of this function is to delay the program execution by a specified
number of milliseconds using a counting loop. The global 16 bit variable delay
count must contain the CPU clock frequency in Hertz divided by 4000 and must
have been set before calling this routine for the first time. As described
in the clobber section, the routine uses a local variable to hold a
temporary value.


Alex


Site Timeline