В проекте имеется файл hal.c (абстрагирование от аппаратного уровня), в котором определены функции обработчики двух прерываний -- от таймера и от UART-а.
CODE
// Прерываение случается каждую миллисекунду
ISR (USART_RXC_vect)
{
uint8_t data;
uint8_t status;
status = UCSRA;
data = UDR;
if ((status & (_BV(FE) | _BV(DOR) | _BV(PE))) == 0) // (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)
{
// Байт принят без апаратных ошибок
_pack = data;
postmessage((msg_t) MSG_PACK); // Тоби пакет!
}
else
postmessage((msg_t) MSG_BADPACK); // Пакет принят с ошибкой
}
// Прерываение случается каждые 10 миллисекунд
ISR (TIMER2_COMP_vect)
{
static uint8_t _timer_200ms;
static uint8_t _key_prevstate;
uint8_t key_currstate;
// Таймер 200 мс
if (++_timer_200ms >= 20)
{
_timer_200ms = 0;
postmessage(MSG_TIMER200MS);
}
// Отработка таймеров
if (_timer_buzzer != 0)
if (--_timer_buzzer == 0)
BUZZER_OFF;
if (_timer_led0 != 0)
if (--_timer_led0 == 0)
LED0_OFF;
if (_timer_led1 != 0)
if (--_timer_led1 == 0)
LED1_OFF;
if (_timer_led2 != 0)
if (--_timer_led2 == 0)
LED2_OFF;
if (_timer_led3 != 0)
if (--_timer_led3 == 0)
LED3_OFF;
// проверка нажатия кнопки
if ((PINC & _BV(KEY)) == 0)
key_currstate = 1; // Кнопка нажата
else
key_currstate = 0; // Кнопка отпущена
if ((key_currstate == 1) && (_key_prevstate == 0))
postmessage(MSG_KEY);
_key_prevstate = key_currstate;
}
Вот как это сделал gcc:
CODE
00000130 <__vector_3>:
130: 1f 92 push r1
132: 0f 92 push r0
134: 0f b6 in r0, 0x3f; 63
136: 0f 92 push r0
138: 11 24 eor r1, r1
13a: 2f 93 push r18
13c: 3f 93 push r19
13e: 4f 93 push r20
140: 5f 93 push r21
142: 6f 93 push r22
144: 7f 93 push r23
146: 8f 93 push r24
148: 9f 93 push r25
14a: af 93 push r26
14c: bf 93 push r27
14e: ef 93 push r30
150: ff 93 push r31
152: 80 91 d3 00 lds r24, 0x00D3
156: 8f 5f subi r24, 0xFF; 255
158: 80 93 d3 00 sts 0x00D3, r24
15c: 84 31 cpi r24, 0x14; 20
15e: 20 f0 brcs .+8 ; 0x168 <__vector_3+0x38>
160: 10 92 d3 00 sts 0x00D3, r1
164: 84 e0 ldi r24, 0x04; 4
166: c8 df rcall .-112; 0xf8 <postmessage>
168: 80 91 e0 00 lds r24, 0x00E0
16c: 88 23 and r24, r24
16e: 51 f0 breq .+20 ; 0x184 <__vector_3+0x54>
170: 80 91 e0 00 lds r24, 0x00E0
174: 81 50 subi r24, 0x01; 1
176: 80 93 e0 00 sts 0x00E0, r24
17a: 80 91 e0 00 lds r24, 0x00E0
17e: 88 23 and r24, r24
180: 09 f4 brne .+2 ; 0x184 <__vector_3+0x54>
182: ad 98 cbi 0x15, 5; 21
184: 80 91 de 00 lds r24, 0x00DE
188: 88 23 and r24, r24
18a: 51 f0 breq .+20 ; 0x1a0 <__vector_3+0x70>
18c: 80 91 de 00 lds r24, 0x00DE
190: 81 50 subi r24, 0x01; 1
192: 80 93 de 00 sts 0x00DE, r24
196: 80 91 de 00 lds r24, 0x00DE
19a: 88 23 and r24, r24
19c: 09 f4 brne .+2 ; 0x1a0 <__vector_3+0x70>
19e: a8 98 cbi 0x15, 0; 21
1a0: 80 91 df 00 lds r24, 0x00DF
1a4: 88 23 and r24, r24
1a6: 51 f0 breq .+20 ; 0x1bc <__vector_3+0x8c>
1a8: 80 91 df 00 lds r24, 0x00DF
1ac: 81 50 subi r24, 0x01; 1
1ae: 80 93 df 00 sts 0x00DF, r24
1b2: 80 91 df 00 lds r24, 0x00DF
1b6: 88 23 and r24, r24
1b8: 09 f4 brne .+2 ; 0x1bc <__vector_3+0x8c>
1ba: a9 98 cbi 0x15, 1; 21
1bc: 80 91 e3 00 lds r24, 0x00E3
1c0: 88 23 and r24, r24
1c2: 51 f0 breq .+20 ; 0x1d8 <__vector_3+0xa8>
1c4: 80 91 e3 00 lds r24, 0x00E3
1c8: 81 50 subi r24, 0x01; 1
1ca: 80 93 e3 00 sts 0x00E3, r24
1ce: 80 91 e3 00 lds r24, 0x00E3
1d2: 88 23 and r24, r24
1d4: 09 f4 brne .+2 ; 0x1d8 <__vector_3+0xa8>
1d6: aa 98 cbi 0x15, 2; 21
1d8: 80 91 e1 00 lds r24, 0x00E1
1dc: 88 23 and r24, r24
1de: 51 f0 breq .+20 ; 0x1f4 <__vector_3+0xc4>
1e0: 80 91 e1 00 lds r24, 0x00E1
1e4: 81 50 subi r24, 0x01; 1
1e6: 80 93 e1 00 sts 0x00E1, r24
1ea: 80 91 e1 00 lds r24, 0x00E1
1ee: 88 23 and r24, r24
1f0: 09 f4 brne .+2 ; 0x1f4 <__vector_3+0xc4>
1f2: ab 98 cbi 0x15, 3; 21
1f4: 9c 9b sbis 0x13, 4; 19
1f6: 02 c0 rjmp .+4 ; 0x1fc <__vector_3+0xcc>
1f8: 80 e0 ldi r24, 0x00; 0
1fa: 07 c0 rjmp .+14 ; 0x20a <__vector_3+0xda>
1fc: 80 91 d2 00 lds r24, 0x00D2
200: 88 23 and r24, r24
202: 11 f4 brne .+4 ; 0x208 <__vector_3+0xd8>
204: 81 e0 ldi r24, 0x01; 1
206: 78 df rcall .-272; 0xf8 <postmessage>
208: 81 e0 ldi r24, 0x01; 1
20a: 80 93 d2 00 sts 0x00D2, r24
20e: ff 91 pop r31
210: ef 91 pop r30
212: bf 91 pop r27
214: af 91 pop r26
216: 9f 91 pop r25
218: 8f 91 pop r24
21a: 7f 91 pop r23
21c: 6f 91 pop r22
21e: 5f 91 pop r21
220: 4f 91 pop r20
222: 3f 91 pop r19
224: 2f 91 pop r18
226: 0f 90 pop r0
228: 0f be out 0x3f, r0; 63
22a: 0f 90 pop r0
22c: 1f 90 pop r1
22e: 18 95 reti
00000230 <__vector_11>:
230: 1f 92 push r1
232: 0f 92 push r0
234: 0f b6 in r0, 0x3f; 63
236: 0f 92 push r0
238: 11 24 eor r1, r1
23a: 2f 93 push r18
23c: 3f 93 push r19
23e: 4f 93 push r20
240: 5f 93 push r21
242: 6f 93 push r22
244: 7f 93 push r23
246: 8f 93 push r24
248: 9f 93 push r25
24a: af 93 push r26
24c: bf 93 push r27
24e: ef 93 push r30
250: ff 93 push r31
252: 8b b1 in r24, 0x0b; 11
254: 9c b1 in r25, 0x0c; 12
256: 8c 71 andi r24, 0x1C; 28
258: 21 f4 brne .+8 ; 0x262 <__vector_11+0x32>
25a: 90 93 e2 00 sts 0x00E2, r25
25e: 82 e0 ldi r24, 0x02; 2
260: 01 c0 rjmp .+2 ; 0x264 <__vector_11+0x34>
262: 83 e0 ldi r24, 0x03; 3
264: 49 df rcall .-366; 0xf8 <postmessage>
266: ff 91 pop r31
268: ef 91 pop r30
26a: bf 91 pop r27
26c: af 91 pop r26
26e: 9f 91 pop r25
270: 8f 91 pop r24
272: 7f 91 pop r23
274: 6f 91 pop r22
276: 5f 91 pop r21
278: 4f 91 pop r20
27a: 3f 91 pop r19
27c: 2f 91 pop r18
27e: 0f 90 pop r0
280: 0f be out 0x3f, r0; 63
282: 0f 90 pop r0
284: 1f 90 pop r1
286: 18 95 reti
А вот так отработал IAR:
CODE
26 __interrupt void _usart_rxc_isr(void)
\ _usart_rxc_isr:
27 {
\ 00000000 .... RCALL ?Subroutine0
\ ??CrossCallReturnLabel_0:
\ 00000002 B78F IN R24, 0x3F
28 uint8_t data;
29 uint8_t status;
30
31 status = UCSRA;
\ 00000004 B10B IN R16, 0x0B
32 data = UDR;
\ 00000006 B11C IN R17, 0x0C
33 if ((status & (_BV(FE) | _BV(DOR) | _BV(PE))) == 0) // (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)
\ 00000008 710C ANDI R16, 0x1C
\ 0000000A F421 BRNE ??_usart_rxc_isr_0
34 {
35 // Байт принят без апаратных ошибок
36 _pack = data;
\ 0000000C 9310.... STS _pack, R17
37 postmessage((msg_t) MSG_PACK); // Тоби пакет!
\ 00000010 E002 LDI R16, 2
\ 00000012 C001 RJMP ??_usart_rxc_isr_1
38 }
39 else
40 postmessage((msg_t) MSG_BADPACK); // Пакет принят с ошибкой
\ ??_usart_rxc_isr_0:
\ 00000014 E003 LDI R16, 3
\ ??_usart_rxc_isr_1:
\ 00000016 .... RCALL postmessage
41 }
\ 00000018 BF8F OUT 0x3F, R24
\ 0000001A .... RCALL ?Subroutine1
\ ??CrossCallReturnLabel_2:
\ 0000001C 9518 RETI
\ 0000001E REQUIRE _A_UCSRA
\ 0000001E REQUIRE _A_UDR
\ In segment CODE, align 2, keep-with-next
\ ?Subroutine1:
\ 00000000 9109 LD R16, Y+
\ 00000002 9119 LD R17, Y+
\ 00000004 9129 LD R18, Y+
\ 00000006 9139 LD R19, Y+
\ 00000008 9149 LD R20, Y+
\ 0000000A 9159 LD R21, Y+
\ 0000000C 9169 LD R22, Y+
\ 0000000E 9179 LD R23, Y+
\ 00000010 9009 LD R0, Y+
\ 00000012 9019 LD R1, Y+
\ 00000014 9029 LD R2, Y+
\ 00000016 9039 LD R3, Y+
\ 00000018 91E9 LD R30, Y+
\ 0000001A 91F9 LD R31, Y+
\ 0000001C 9189 LD R24, Y+
\ 0000001E 9508 RET
\ In segment CODE, align 2, keep-with-next
\ ?Subroutine0:
\ 00000000 938A ST -Y, R24
\ 00000002 93FA ST -Y, R31
\ 00000004 93EA ST -Y, R30
\ 00000006 923A ST -Y, R3
\ 00000008 922A ST -Y, R2
\ 0000000A 921A ST -Y, R1
\ 0000000C 920A ST -Y, R0
\ 0000000E 937A ST -Y, R23
\ 00000010 936A ST -Y, R22
\ 00000012 935A ST -Y, R21
\ 00000014 934A ST -Y, R20
\ 00000016 933A ST -Y, R19
\ 00000018 932A ST -Y, R18
\ 0000001A 931A ST -Y, R17
\ 0000001C 930A ST -Y, R16
\ 0000001E 9508 RET
42
43
44 // Прерываение случается каждые 10 миллисекунд
45 // ISR (TIMER2_COMP_vect)
46 #pragma vector = TIMER2_COMP_vect
\ In segment CODE, align 2, keep-with-next
47 __interrupt void _timer2_comp_isr(void)
\ _timer2_comp_isr:
48 {
\ 00000000 939A ST -Y, R25
\ 00000002 .... RCALL ?Subroutine0
\ ??CrossCallReturnLabel_1:
\ 00000004 B79F IN R25, 0x3F
49 static uint8_t _timer_200ms;
50 static uint8_t _key_prevstate;
51
52 uint8_t key_currstate;
53
54 // Таймер 200 мс
55 if (++_timer_200ms >= 20)
\ 00000006 .... LDI R30, LOW(_timer_led0)
\ 00000008 .... LDI R31, (_timer_led0) >> 8
\ 0000000A 8105 LDD R16, Z+5
\ 0000000C 9503 INC R16
\ 0000000E 8305 STD Z+5, R16
\ 00000010 3104 CPI R16, 20
\ 00000012 F020 BRCS ??_timer2_comp_isr_0
56 {
57 _timer_200ms = 0;
\ 00000014 E000 LDI R16, 0
\ 00000016 8305 STD Z+5, R16
58 postmessage(MSG_TIMER200MS);
\ 00000018 E004 LDI R16, 4
\ 0000001A .... RCALL postmessage
59 }
60
61 // Отработка таймеров
62 if (_timer_buzzer != 0)
\ ??_timer2_comp_isr_0:
\ 0000001C 9100.... LDS R16, (_timer_led0 + 4)
\ 00000020 2300 TST R16
\ 00000022 F039 BREQ ??_timer2_comp_isr_1
63 if (--_timer_buzzer == 0)
\ 00000024 9100.... LDS R16, (_timer_led0 + 4)
\ 00000028 950A DEC R16
\ 0000002A 9300.... STS (_timer_led0 + 4), R16
\ 0000002E F409 BRNE ??_timer2_comp_isr_1
64 BUZZER_OFF;
\ 00000030 98AD CBI 0x15, 0x05
65
66 if (_timer_led0 != 0)
\ ??_timer2_comp_isr_1:
\ 00000032 9100.... LDS R16, _timer_led0
\ 00000036 2300 TST R16
\ 00000038 F039 BREQ ??_timer2_comp_isr_2
67 if (--_timer_led0 == 0)
\ 0000003A 9100.... LDS R16, _timer_led0
\ 0000003E 950A DEC R16
\ 00000040 9300.... STS _timer_led0, R16
\ 00000044 F409 BRNE ??_timer2_comp_isr_2
68 LED0_OFF;
\ 00000046 98A8 CBI 0x15, 0x00
69
70 if (_timer_led1 != 0)
\ ??_timer2_comp_isr_2:
\ 00000048 9100.... LDS R16, (_timer_led0 + 1)
\ 0000004C 2300 TST R16
\ 0000004E F039 BREQ ??_timer2_comp_isr_3
71 if (--_timer_led1 == 0)
\ 00000050 9100.... LDS R16, (_timer_led0 + 1)
\ 00000054 950A DEC R16
\ 00000056 9300.... STS (_timer_led0 + 1), R16
\ 0000005A F409 BRNE ??_timer2_comp_isr_3
72 LED1_OFF;
\ 0000005C 98A9 CBI 0x15, 0x01
73
74 if (_timer_led2 != 0)
\ ??_timer2_comp_isr_3:
\ 0000005E 9100.... LDS R16, (_timer_led0 + 2)
\ 00000062 2300 TST R16
\ 00000064 F039 BREQ ??_timer2_comp_isr_4
75 if (--_timer_led2 == 0)
\ 00000066 9100.... LDS R16, (_timer_led0 + 2)
\ 0000006A 950A DEC R16
\ 0000006C 9300.... STS (_timer_led0 + 2), R16
\ 00000070 F409 BRNE ??_timer2_comp_isr_4
76 LED2_OFF;
\ 00000072 98AA CBI 0x15, 0x02
77
78 if (_timer_led3 != 0)
\ ??_timer2_comp_isr_4:
\ 00000074 9100.... LDS R16, (_timer_led0 + 3)
\ 00000078 2300 TST R16
\ 0000007A F039 BREQ ??_timer2_comp_isr_5
79 if (--_timer_led3 == 0)
\ 0000007C 9100.... LDS R16, (_timer_led0 + 3)
\ 00000080 950A DEC R16
\ 00000082 9300.... STS (_timer_led0 + 3), R16
\ 00000086 F409 BRNE ??_timer2_comp_isr_5
80 LED3_OFF;
\ 00000088 98AB CBI 0x15, 0x03
81
82 // проверка нажатия кнопки
83
84 if ((PINC & _BV(KEY)) == 0)
85 key_currstate = 1; // Кнопка нажата
\ ??_timer2_comp_isr_5:
\ 0000008A 999C SBIC 0x13, 0x04
\ 0000008C C002 RJMP ??_timer2_comp_isr_6
\ 0000008E E001 LDI R16, 1
\ 00000090 C001 RJMP ??_timer2_comp_isr_7
\ ??_timer2_comp_isr_6:
\ 00000092 E000 LDI R16, 0
\ ??_timer2_comp_isr_7:
\ 00000094 2F80 MOV R24, R16
86 else
87 key_currstate = 0; // Кнопка отпущена
88
89 if ((key_currstate == 1) && (_key_prevstate == 0))
\ 00000096 3001 CPI R16, 1
\ 00000098 F431 BRNE ??_timer2_comp_isr_8
\ 0000009A 9100.... LDS R16, (_timer_led0 + 6)
\ 0000009E 2300 TST R16
\ 000000A0 F411 BRNE ??_timer2_comp_isr_8
90 postmessage(MSG_KEY);
\ 000000A2 E001 LDI R16, 1
\ 000000A4 .... RCALL postmessage
91 _key_prevstate = key_currstate;
\ ??_timer2_comp_isr_8:
\ 000000A6 9380.... STS (_timer_led0 + 6), R24
92 }
\ 000000AA BF9F OUT 0x3F, R25
\ 000000AC .... RCALL ?Subroutine1
\ ??CrossCallReturnLabel_3:
\ 000000AE 9199 LD R25, Y+
\ 000000B0 9518 RETI
\ 000000B2 REQUIRE _A_PINC
\ 000000B2 REQUIRE _A_PORTC
93
Фейерическое растранжиривание памяти компилятором gcc видите?
Что-нибудь можно предпринять на уровне компилятора или для gcc это фатально?