7403 0 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба Помогите разобраться с WINAVR. При размещении переменных в регистрах компилятор ведёт себя подозрительно: сокращает функции, в которых они используются. :07: Но при обычном объявлении всё работает. Подскажите, где может быть ошибка? #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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aesok 0 10 июня, 2008 Опубликовано 10 июня, 2008 (изменено) · Жалоба Регистровые volatile переменные в GCC не работают. Анатолий AVRGCC ignores "volatile" keyword for "register" variables http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17336 Изменено 10 июня, 2008 пользователем aesok Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
7403 0 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба Регистровые volatile переменные в GCC не работают. Анатолий AVRGCC ignores "volatile" keyword for "register" variables http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17336 И каков же выход? Использовать IAR? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба И каков же выход? Использовать IAR? Используйте GPIO0, GPIO1, GPIO2. В принципе можно даже использовать любые незадействованные SFR с адресом 0х00 - 0х1F Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба И каков же выход?Просто уберите volatile при объявлении регистровой переменной, все должно скомпилится правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
7403 0 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба Используйте GPIO0, GPIO1, GPIO2. В принципе можно даже использовать любые незадействованные SFR с адресом 0х00 - 0х1F Если не трудно, подскажите как использовать SFR в дипазоне 0x09...0x13 (записать/прочитать данные 2-х или 4-х байтные)? Просто уберите volatile при объявлении регистровой переменной, все должно скомпилится правильно. Скомпилировалось, но не правильно. Можете сами проверить, в архиве весь проект... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба Скомпилировалось, но не правильно. Можете сами проверить, в архиве весь проект...А какая версия WinAVR ? Скомпилируйте с листингом и покажите его. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба И каков же выход?Конкретно в этом простом случае можно написать вставку на инлайновом ассемблере. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
7403 0 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба А какая версия 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aesok 0 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба А какая версия WinAVR ? Все версии avr-gcc так работают. Анатолий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба Все версии avr-gcc так работают.Ну это как минимум не так :) WinAVR20060421(Gcc 3.4.6): 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 ??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба Можно ли получить такой же компактный/быстрый код на Gcc 4.x.x ??? Увы :( Без оптимизации выходит: 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). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 10 июня, 2008 Опубликовано 10 июня, 2008 · Жалоба и так далее, а начиная с -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 **** } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
7403 0 11 июня, 2008 Опубликовано 11 июня, 2008 · Жалоба Конкретно в этом простом случае можно написать вставку на инлайновом ассемблере. Можно ли подобно макросу _SFR_IO16(io_addr) расположить 32-битную переменную в область SFR? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 11 июня, 2008 Опубликовано 11 июня, 2008 · Жалоба 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? Хочу такой же:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться