реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Winavr сокращает функцию, если переменные размещены в регистрах
A.l.e.x.
сообщение Jun 10 2008, 11:54
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 69
Регистрация: 4-02-08
Из: Винница
Пользователь №: 34 732



Помогите разобраться с WINAVR. При размещении переменных в регистрах компилятор ведёт себя подозрительно: сокращает функции, в которых они используются. 07.gif Но при обычном объявлении всё работает. Подскажите, где может быть ошибка?

Код
#include <avr/io.h>
#include <avr/interrupt.h>
volatile register unsigned long count_ms asm("r4");
volatile register unsigned char flag_ms asm("r8");
/////////////////////////////////////////////////////////////////////////////////////////////////
void timer_ms(unsigned long value)
{
    count_ms = value;
    flag_ms = 0;
    while(flag_ms == 0);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
ISR(TIM0_COMPA_vect)
{
    if(count_ms){--count_ms;}
    else{flag_ms = 1;}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
int main(void)
{
    TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(0<<COM0B1)|(0<<COM0B0)|(1<<WGM01)|(0<<WGM00);    //CTC
    TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(1<<CS01)|(0<<CS00);        // FCPU/8
    OCR0A = 149;
    TIMSK0 = (0<<OCIE0B)|(1<<OCIE0A)|(0<<TOIE0);
    sei();
    
    
    while(1){
        timer_ms(100);
        PORTB ^= 0x01;
    }
}

Прикрепленные файлы
Прикрепленный файл  timer_ms.rar ( 7.91 килобайт ) Кол-во скачиваний: 41
 
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 10 2008, 12:15
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Регистровые volatile переменные в GCC не работают.

Анатолий

AVRGCC ignores "volatile" keyword for "register" variables
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17336

Сообщение отредактировал aesok - Jun 10 2008, 12:28
Go to the top of the page
 
+Quote Post
A.l.e.x.
сообщение Jun 10 2008, 12:36
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 69
Регистрация: 4-02-08
Из: Винница
Пользователь №: 34 732



Цитата(aesok @ Jun 10 2008, 15:15) *
Регистровые volatile переменные в GCC не работают.

Анатолий

AVRGCC ignores "volatile" keyword for "register" variables
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17336


И каков же выход? Использовать IAR?
Go to the top of the page
 
+Quote Post
dimka76
сообщение Jun 10 2008, 12:55
Сообщение #4


developer
****

Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032



Цитата(A.l.e.x. @ Jun 10 2008, 15:36) *
И каков же выход? Использовать IAR?


Используйте GPIO0, GPIO1, GPIO2. В принципе можно даже использовать любые незадействованные SFR с адресом 0х00 - 0х1F


--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 10 2008, 13:59
Сообщение #5


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(A.l.e.x. @ Jun 10 2008, 16:36) *
И каков же выход?
Просто уберите volatile при объявлении регистровой переменной,
все должно скомпилится правильно.
Go to the top of the page
 
+Quote Post
A.l.e.x.
сообщение Jun 10 2008, 14:02
Сообщение #6


Участник
*

Группа: Свой
Сообщений: 69
Регистрация: 4-02-08
Из: Винница
Пользователь №: 34 732



Цитата(dimka76 @ Jun 10 2008, 15:55) *
Используйте GPIO0, GPIO1, GPIO2. В принципе можно даже использовать любые незадействованные SFR с адресом 0х00 - 0х1F

Если не трудно, подскажите как использовать SFR в дипазоне 0x09...0x13 (записать/прочитать данные 2-х или 4-х байтные)?


Цитата(singlskv @ Jun 10 2008, 16:59) *
Просто уберите volatile при объявлении регистровой переменной,
все должно скомпилится правильно.

Скомпилировалось, но не правильно. Можете сами проверить, в архиве весь проект...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 10 2008, 14:06
Сообщение #7


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(A.l.e.x. @ Jun 10 2008, 18:02) *
Скомпилировалось, но не правильно. Можете сами проверить, в архиве весь проект...
А какая версия WinAVR ?
Скомпилируйте с листингом и покажите его.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 10 2008, 14:19
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(A.l.e.x. @ Jun 10 2008, 15:36) *
И каков же выход?
Конкретно в этом простом случае можно написать вставку на инлайновом ассемблере.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
A.l.e.x.
сообщение Jun 10 2008, 14:33
Сообщение #9


Участник
*

Группа: Свой
Сообщений: 69
Регистрация: 4-02-08
Из: Винница
Пользователь №: 34 732



Цитата(singlskv @ Jun 10 2008, 17:06) *
А какая версия WinAVR ?
Скомпилируйте с листингом и покажите его.


WinAVR-20080512

Код
> "make.exe" all

-------- begin --------
avr-gcc (WinAVR 20080512) 4.3.0
Copyright (C) 2008 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.


Compiling C: main.c
avr-gcc -c -mmcu=attiny13 -I. -gdwarf-2 -DF_CPU=1200000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -pedantic -Wa,-adhlns=./main.lst  -std=gnu99 -Wundef -MMD -MP -MF .dep/main.o.d main.c -o main.o
main.c:4: warning: file-scope declaration of 'count_ms' specifies 'register'
main.c:5: warning: file-scope declaration of 'flag_ms' specifies 'register'

Linking: main.elf
avr-gcc -mmcu=attiny13 -I. -gdwarf-2 -DF_CPU=1200000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -pedantic -Wa,-adhlns=main.o  -std=gnu99 -Wundef -MMD -MP -MF .dep/main.elf.d main.o --output main.elf -Wl,-Map=main.map,--cref     -lm

Creating load file for Flash: main.hex
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock main.elf main.hex

Creating load file for EEPROM: main.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
    --change-section-lma .eeprom=0 --no-change-warnings -O ihex main.elf main.eep || exit 0

Creating Extended Listing: main.lss
avr-objdump -h -S -z main.elf > main.lss

Creating Symbol Table: main.sym
avr-nm -n main.elf > main.sym

Size after:
AVR Memory Usage
----------------
Device: attiny13

Program:     158 bytes (15.4% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)



-------- end --------
Прикрепленные файлы
Прикрепленный файл  timer_ms_.rar ( 14.05 килобайт ) Кол-во скачиваний: 44
 
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 10 2008, 16:28
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(singlskv @ Jun 10 2008, 18:06) *
А какая версия WinAVR ?


Все версии avr-gcc так работают.

Анатолий.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 10 2008, 17:44
Сообщение #11


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(aesok @ Jun 10 2008, 20:28) *
Все версии avr-gcc так работают.
Ну это как минимум не так smile.gif

WinAVR20060421(Gcc 3.4.6):
CODE

00000048 <timer_ms>:
register unsigned long count_ms asm("r4");
register unsigned char flag_ms asm("r8");
/////////////////////////////////////////////////////////////////////////////////////////////////
void timer_ms(unsigned long value)
{
48: b9 2f mov r27, r25
4a: a8 2f mov r26, r24
4c: 97 2f mov r25, r23
4e: 86 2f mov r24, r22
count_ms = value;
50: 48 2e mov r4, r24
52: 59 2e mov r5, r25
54: 6a 2e mov r6, r26
56: 7b 2e mov r7, r27
flag_ms = 0;
58: 88 24 eor r8, r8
while(flag_ms == 0);
5a: 88 20 and r8, r8
5c: f1 f3 breq .-4 ; 0x5a <timer_ms+0x12>
5e: 08 95 ret

00000060 <__vector_6>:
}
/////////////////////////////////////////////////////////////////////////////////////////////////
ISR(TIM0_COMPA_vect)
{
60: 1f 92 push r1
62: 0f 92 push r0
64: 0f b6 in r0, 0x3f ; 63
66: 0f 92 push r0
68: 11 24 eor r1, r1
if(count_ms){--count_ms;}
6a: 41 14 cp r4, r1
6c: 51 04 cpc r5, r1
6e: 61 04 cpc r6, r1
70: 71 04 cpc r7, r1
72: 31 f0 breq .+12 ; 0x80 <__vector_6+0x20>
74: 08 94 sec
76: 41 08 sbc r4, r1
78: 51 08 sbc r5, r1
7a: 61 08 sbc r6, r1
7c: 71 08 sbc r7, r1
7e: 02 c0 rjmp .+4 ; 0x84 <__vector_6+0x24>
else{flag_ms = 1;}
80: 88 24 eor r8, r8
82: 83 94 inc r8
84: 0f 90 pop r0
86: 0f be out 0x3f, r0 ; 63
88: 0f 90 pop r0
8a: 1f 90 pop r1
8c: 18 95 reti

0000008e <main>:
}
/////////////////////////////////////////////////////////////////////////////////////////////////
int main(void)
{
8e: cf e9 ldi r28, 0x9F ; 159
90: d0 e0 ldi r29, 0x00 ; 0
92: de bf out 0x3e, r29 ; 62
94: cd bf out 0x3d, r28 ; 61
TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(0<<COM0B1)|(0<<COM0B0)|(1<<WGM01)|(0<<WGM00); //CTC
96: 82 e0 ldi r24, 0x02 ; 2
98: 8f bd out 0x2f, r24 ; 47
TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(1<<CS01)|(0<<CS00); // FCPU/8
9a: 83 bf out 0x33, r24 ; 51
OCR0A = 149;
9c: 85 e9 ldi r24, 0x95 ; 149
9e: 86 bf out 0x36, r24 ; 54
TIMSK0 = (0<<OCIE0B)|(1<<OCIE0A)|(0<<TOIE0);
a0: 84 e0 ldi r24, 0x04 ; 4
a2: 89 bf out 0x39, r24 ; 57
sei();
a4: 78 94 sei

while(1){
timer_ms(100);
a6: 64 e6 ldi r22, 0x64 ; 100
a8: 70 e0 ldi r23, 0x00 ; 0
aa: 80 e0 ldi r24, 0x00 ; 0
ac: 90 e0 ldi r25, 0x00 ; 0
ae: cc df rcall .-104 ; 0x48 <timer_ms>
PORTB ^= 0x01;
b0: 88 b3 in r24, 0x18 ; 24
b2: 91 e0 ldi r25, 0x01 ; 1
b4: 89 27 eor r24, r25
b6: 88 bb out 0x18, r24 ; 24
b8: f6 cf rjmp .-20 ; 0xa6 <__stack+0x7>


как видно, оверхед только здесь:
Код
  48:    b9 2f           mov    r27, r25
  4a:    a8 2f           mov    r26, r24
  4c:    97 2f           mov    r25, r23
  4e:    86 2f           mov    r24, r22
и здесь:
Код
  b2:    91 e0           ldi    r25, 0x01; 1

Но при этом код абсолютно корректный !

Можно ли получить такой же компактный/быстрый код на Gcc 4.x.x ???
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 10 2008, 18:12
Сообщение #12


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(singlskv @ Jun 10 2008, 23:44) *
Можно ли получить такой же компактный/быстрый код на Gcc 4.x.x ???


Увы sad.gif

Без оптимизации выходит:
Код
void timer_ms(unsigned long value)
{
  48:    df 93           push    r29
  4a:    cf 93           push    r28
  4c:    00 d0           rcall    .+0      ; 0x4e <timer_ms+0x6>
  4e:    00 d0           rcall    .+0      ; 0x50 <timer_ms+0x8>
  50:    cd b7           in    r28, 0x3d; 61
  52:    de b7           in    r29, 0x3e; 62
  54:    69 83           std    Y+1, r22; 0x01
  56:    7a 83           std    Y+2, r23; 0x02
  58:    8b 83           std    Y+3, r24; 0x03
  5a:    9c 83           std    Y+4, r25; 0x04
    count_ms = value;
  5c:    49 80           ldd    r4, Y+1; 0x01
  5e:    5a 80           ldd    r5, Y+2; 0x02
  60:    6b 80           ldd    r6, Y+3; 0x03
  62:    7c 80           ldd    r7, Y+4; 0x04
    flag_ms = 0;
  64:    88 24           eor    r8, r8
    while(flag_ms == 0);
  66:    88 2d           mov    r24, r8
  68:    88 23           and    r24, r24
  6a:    e9 f3           breq    .-6      ; 0x66 <timer_ms+0x1e>
}
  6c:    0f 90           pop    r0
  6e:    0f 90           pop    r0
  70:    0f 90           pop    r0
  72:    0f 90           pop    r0
  74:    cf 91           pop    r28
  76:    df 91           pop    r29
  78:    08 95           ret


и так далее, а начиная с -O1:
Код
void timer_ms(unsigned long value)
{
  48:    ff cf           rjmp    .-2      ; 0x48 <timer_ms>


Это avr-gcc (GCC) 4.4.0 20080530 (experimental).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
alx2
сообщение Jun 10 2008, 19:32
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(AHTOXA @ Jun 10 2008, 23:12) *
и так далее, а начиная с -O1:
Код
void timer_ms(unsigned long value)
{
  48:    ff cf           rjmp    .-2     ; 0x48 <timer_ms>


Это avr-gcc (GCC) 4.4.0 20080530 (experimental).

gcc-4.2.2 начиная c -O1:
Код
   7:test.c        **** void timer_ms(unsigned long value)
   8:test.c        **** {
  79                    /* prologue: frame size=0 */
  80                    /* prologue end (size=0) */
   9:test.c        ****    count_ms = value;
  83 0000 2B01                  movw r4,r22
  84 0002 3C01                  movw r6,r24
  10:test.c        ****    flag_ms = 0;
  87 0004 8824                  clr r8
  88                    .L2:
  11:test.c        ****    while(flag_ms == 0);
  91 0006 8820                  tst r8
  92 0008 01F0                  breq .L2
  93                    /* epilogue: frame size=0 */
  94 000a 0895                  ret
  95                    /* epilogue end (size=1) */
  96                    /* function timer_ms size 6 (5) */
  12:test.c        **** }


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
A.l.e.x.
сообщение Jun 11 2008, 06:39
Сообщение #14


Участник
*

Группа: Свой
Сообщений: 69
Регистрация: 4-02-08
Из: Винница
Пользователь №: 34 732



Цитата(Сергей Борщ @ Jun 10 2008, 17:19) *
Конкретно в этом простом случае можно написать вставку на инлайновом ассемблере.

Можно ли подобно макросу _SFR_IO16(io_addr) расположить 32-битную переменную в область SFR?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 11 2008, 12:33
Сообщение #15


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(alx2 @ Jun 11 2008, 01:32) *
gcc-4.2.2 начиная c -O1:


Странно...
avr-gcc.exe (GCC) 4.2.2 (WinAVR 20071221):
Код
00000048 <timer_ms>:
  48:    2b 01           movw    r4, r22
  4a:    3c 01           movw    r6, r24
  4c:    88 24           eor    r8, r8
  4e:    ff cf           rjmp    .-2      ; 0x4e <timer_ms+0x6>


avr-gcc.exe (GCC) 4.1.2 (WinAVR 20070525):
Код
void timer_ms(unsigned long value)
{
  4a:    46 2e           mov    r4, r22
  4c:    57 2e           mov    r5, r23
  4e:    68 2e           mov    r6, r24
  50:    79 2e           mov    r7, r25
    count_ms = value;
    flag_ms = 0;
  52:    88 24           eor    r8, r8
  54:    ff cf           rjmp    .-2      ; 0x54 <timer_ms+0xa>


А у Вас какой GCC 4.2.2? Хочу такой жеsmile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 14:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01525 секунд с 7
ELECTRONIX ©2004-2016