So,
ich mache mir weitere Gedanken und fange mal an, erste "Investigations" zu posten.
Vom Prinzip her wird das so laufen, dass in einer ISR, wahrscheinlich Timer2 Match oder Timer0 OVF, am Ende der ISR der Programmcounter verbogen werden muss zu der Adresse, wo eine aufzurufende Funktion steht.
Jetzt ist es in C ja so, das der Compiler einem das sichern vom Status- und den Workingregistern abnimmt. Die erste Frage die sich also stellt ist, wie man nach seinem C-Code dem Compiler vor dem vom ihm eingefügten Rücksprung aus dem Interrupt (reti) zuvokommt.
Ich habe zunächst ein ganz simples Programm auf Basis des Timer2 Comp Match Interruptes gemacht, wo einfach nur eine globale Variable um 1 erhöht wird. Damit wollte ich erstmal ein Gefühl kriegen, was der Compiler eigentlich "normalerweise" so treibt. Dazu dann erstmal der C Code und dann der ASM Code, den ich in der Datei im Projektpfad/default in der .Iss Datei gefunden habe. (ich weiß, diese Subtrktion von 255 und test auf 0 Flag bit im ASM code ist komisch - könnte an der stdint.h liegen - bitte dieses hier nicht zu kommentieren, weil es darum nicht gehen soll).
Daraus entstandener ASM Code:Code:#include <avr/io.h> #include <avr/interrupt.h> #include <stdint.h> uint8_t cnt = 0; SIGNAL (TIMER2_COMP_vect)//TIMER1_COMPA_vect) { cnt++; } int main(void) { TCCR2 = 0b00001010; OCR2 = 100; TIMSK = 0b10000000;//input cp int enable, int on match A enable main2: goto main2; return 0; }
Mit der Anweisung "asm volatile("ret");" am ende der ISR wird der Assemblerbefehl ret vor das Restaurieren und das reti gequetscht.Code:schedule_try1.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn 0 .text 0000007c 00000000 00000000 00000074 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .bss 00000001 00800060 00800060 000000f0 2**0 ALLOC 2 .debug_aranges 00000020 00000000 00000000 000000f0 2**0 CONTENTS, READONLY, DEBUGGING 3 .debug_pubnames 00000032 00000000 00000000 00000110 2**0 CONTENTS, READONLY, DEBUGGING 4 .debug_info 000000b3 00000000 00000000 00000142 2**0 CONTENTS, READONLY, DEBUGGING 5 .debug_abbrev 00000081 00000000 00000000 000001f5 2**0 CONTENTS, READONLY, DEBUGGING 6 .debug_line 000000c5 00000000 00000000 00000276 2**0 CONTENTS, READONLY, DEBUGGING 7 .debug_frame 00000030 00000000 00000000 0000033c 2**2 CONTENTS, READONLY, DEBUGGING 8 .debug_str 0000009f 00000000 00000000 0000036c 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: 00000000 <__vectors>: 0: 12 c0 rjmp .+36 ; 0x26 <__ctors_end> 2: 21 c0 rjmp .+66 ; 0x46 <__bad_interrupt> 4: 20 c0 rjmp .+64 ; 0x46 <__bad_interrupt> 6: 20 c0 rjmp .+64 ; 0x48 <__vector_3> 8: 1e c0 rjmp .+60 ; 0x46 <__bad_interrupt> a: 1d c0 rjmp .+58 ; 0x46 <__bad_interrupt> c: 1c c0 rjmp .+56 ; 0x46 <__bad_interrupt> e: 1b c0 rjmp .+54 ; 0x46 <__bad_interrupt> 10: 1a c0 rjmp .+52 ; 0x46 <__bad_interrupt> 12: 19 c0 rjmp .+50 ; 0x46 <__bad_interrupt> 14: 18 c0 rjmp .+48 ; 0x46 <__bad_interrupt> 16: 17 c0 rjmp .+46 ; 0x46 <__bad_interrupt> 18: 16 c0 rjmp .+44 ; 0x46 <__bad_interrupt> 1a: 15 c0 rjmp .+42 ; 0x46 <__bad_interrupt> 1c: 14 c0 rjmp .+40 ; 0x46 <__bad_interrupt> 1e: 13 c0 rjmp .+38 ; 0x46 <__bad_interrupt> 20: 12 c0 rjmp .+36 ; 0x46 <__bad_interrupt> 22: 11 c0 rjmp .+34 ; 0x46 <__bad_interrupt> 24: 10 c0 rjmp .+32 ; 0x46 <__bad_interrupt> 00000026 <__ctors_end>: 26: 11 24 eor r1, r1 28: 1f be out 0x3f, r1 ; 63 2a: cf e5 ldi r28, 0x5F ; 95 2c: d4 e0 ldi r29, 0x04 ; 4 2e: de bf out 0x3e, r29 ; 62 30: cd bf out 0x3d, r28 ; 61 00000032 <__do_clear_bss>: 32: 10 e0 ldi r17, 0x00 ; 0 34: a0 e6 ldi r26, 0x60 ; 96 36: b0 e0 ldi r27, 0x00 ; 0 38: 01 c0 rjmp .+2 ; 0x3c <.do_clear_bss_start> 0000003a <.do_clear_bss_loop>: 3a: 1d 92 st X+, r1 0000003c <.do_clear_bss_start>: 3c: a1 36 cpi r26, 0x61 ; 97 3e: b1 07 cpc r27, r17 40: e1 f7 brne .-8 ; 0x3a <.do_clear_bss_loop> 42: 13 d0 rcall .+38 ; 0x6a <main> 44: 19 c0 rjmp .+50 ; 0x78 <_exit> 00000046 <__bad_interrupt>: 46: dc cf rjmp .-72 ; 0x0 <__vectors> 00000048 <__vector_3>: #include <stdint.h> uint8_t cnt = 0; SIGNAL (TIMER2_COMP_vect)//TIMER1_COMPA_vect) { 48: 1f 92 push r1 4a: 0f 92 push r0 4c: 0f b6 in r0, 0x3f ; 63 4e: 0f 92 push r0 50: 11 24 eor r1, r1 52: 8f 93 push r24 cnt++; 54: 80 91 60 00 lds r24, 0x0060 58: 8f 5f subi r24, 0xFF ; 255 5a: 80 93 60 00 sts 0x0060, r24 } 5e: 8f 91 pop r24 60: 0f 90 pop r0 62: 0f be out 0x3f, r0 ; 63 64: 0f 90 pop r0 66: 1f 90 pop r1 68: 18 95 reti 0000006a <main>: int main(void) { TCCR2 = 0b00001010; 6a: 8a e0 ldi r24, 0x0A ; 10 6c: 85 bd out 0x25, r24 ; 37 OCR2 = 100; 6e: 84 e6 ldi r24, 0x64 ; 100 70: 83 bd out 0x23, r24 ; 35 TIMSK = 0b10000000;//input cp int enable, int on match A enable 72: 80 e8 ldi r24, 0x80 ; 128 74: 89 bf out 0x39, r24 ; 57 76: ff cf rjmp .-2 ; 0x76 <main+0xc> 00000078 <_exit>: 78: f8 94 cli 0000007a <__stop_program>: 7a: ff cf rjmp .-2 ; 0x7a <__stop_program>
Warum ich hier jetzt "ret" und nicht reti verwende, dazu an anderer Stelle mehr. Hier gehts erstmal nur um Machbarkeiten.
ASM CodeCode:#include <avr/io.h> #include <avr/interrupt.h> #include <stdint.h> uint8_t cnt = 0; SIGNAL (TIMER2_COMP_vect)//TIMER1_COMPA_vect) { cnt++; asm volatile("ret"); } int main(void) { TCCR2 = 0b00001010; OCR2 = 100; TIMSK = 0b10000000;//input cp int enable, int on match A enable main2: goto main2; return 0; }
Man kann im ASM code also deutlich sehen, wo sich das händisch eingefügte "ret" auswirkt. So würde er also aus der ISR abhauen, ohne das global Interrupt enable Bit wieder zu setzten und die register zu restaurieren.Code:schedule_try2.elf: file format elf32-avr Sections: Idx Name Size VMA LMA File off Algn 0 .text 0000007e 00000000 00000000 00000074 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .bss 00000001 00800060 00800060 000000f2 2**0 ALLOC 2 .debug_aranges 00000020 00000000 00000000 000000f2 2**0 CONTENTS, READONLY, DEBUGGING 3 .debug_pubnames 00000032 00000000 00000000 00000112 2**0 CONTENTS, READONLY, DEBUGGING 4 .debug_info 000000b3 00000000 00000000 00000144 2**0 CONTENTS, READONLY, DEBUGGING 5 .debug_abbrev 00000081 00000000 00000000 000001f7 2**0 CONTENTS, READONLY, DEBUGGING 6 .debug_line 000000cd 00000000 00000000 00000278 2**0 CONTENTS, READONLY, DEBUGGING 7 .debug_frame 00000030 00000000 00000000 00000348 2**2 CONTENTS, READONLY, DEBUGGING 8 .debug_str 0000009f 00000000 00000000 00000378 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text: 00000000 <__vectors>: 0: 12 c0 rjmp .+36 ; 0x26 <__ctors_end> 2: 21 c0 rjmp .+66 ; 0x46 <__bad_interrupt> 4: 20 c0 rjmp .+64 ; 0x46 <__bad_interrupt> 6: 20 c0 rjmp .+64 ; 0x48 <__vector_3> 8: 1e c0 rjmp .+60 ; 0x46 <__bad_interrupt> a: 1d c0 rjmp .+58 ; 0x46 <__bad_interrupt> c: 1c c0 rjmp .+56 ; 0x46 <__bad_interrupt> e: 1b c0 rjmp .+54 ; 0x46 <__bad_interrupt> 10: 1a c0 rjmp .+52 ; 0x46 <__bad_interrupt> 12: 19 c0 rjmp .+50 ; 0x46 <__bad_interrupt> 14: 18 c0 rjmp .+48 ; 0x46 <__bad_interrupt> 16: 17 c0 rjmp .+46 ; 0x46 <__bad_interrupt> 18: 16 c0 rjmp .+44 ; 0x46 <__bad_interrupt> 1a: 15 c0 rjmp .+42 ; 0x46 <__bad_interrupt> 1c: 14 c0 rjmp .+40 ; 0x46 <__bad_interrupt> 1e: 13 c0 rjmp .+38 ; 0x46 <__bad_interrupt> 20: 12 c0 rjmp .+36 ; 0x46 <__bad_interrupt> 22: 11 c0 rjmp .+34 ; 0x46 <__bad_interrupt> 24: 10 c0 rjmp .+32 ; 0x46 <__bad_interrupt> 00000026 <__ctors_end>: 26: 11 24 eor r1, r1 28: 1f be out 0x3f, r1 ; 63 2a: cf e5 ldi r28, 0x5F ; 95 2c: d4 e0 ldi r29, 0x04 ; 4 2e: de bf out 0x3e, r29 ; 62 30: cd bf out 0x3d, r28 ; 61 00000032 <__do_clear_bss>: 32: 10 e0 ldi r17, 0x00 ; 0 34: a0 e6 ldi r26, 0x60 ; 96 36: b0 e0 ldi r27, 0x00 ; 0 38: 01 c0 rjmp .+2 ; 0x3c <.do_clear_bss_start> 0000003a <.do_clear_bss_loop>: 3a: 1d 92 st X+, r1 0000003c <.do_clear_bss_start>: 3c: a1 36 cpi r26, 0x61 ; 97 3e: b1 07 cpc r27, r17 40: e1 f7 brne .-8 ; 0x3a <.do_clear_bss_loop> 42: 14 d0 rcall .+40 ; 0x6c <main> 44: 1a c0 rjmp .+52 ; 0x7a <_exit> 00000046 <__bad_interrupt>: 46: dc cf rjmp .-72 ; 0x0 <__vectors> 00000048 <__vector_3>: #include <stdint.h> uint8_t cnt = 0; SIGNAL (TIMER2_COMP_vect)//TIMER1_COMPA_vect) { 48: 1f 92 push r1 4a: 0f 92 push r0 4c: 0f b6 in r0, 0x3f ; 63 4e: 0f 92 push r0 50: 11 24 eor r1, r1 52: 8f 93 push r24 cnt++; 54: 80 91 60 00 lds r24, 0x0060 58: 8f 5f subi r24, 0xFF ; 255 5a: 80 93 60 00 sts 0x0060, r24 asm volatile("ret"); 5e: 08 95 ret } 60: 8f 91 pop r24 62: 0f 90 pop r0 64: 0f be out 0x3f, r0 ; 63 66: 0f 90 pop r0 68: 1f 90 pop r1 6a: 18 95 reti 0000006c <main>: int main(void) { TCCR2 = 0b00001010; 6c: 8a e0 ldi r24, 0x0A ; 10 6e: 85 bd out 0x25, r24 ; 37 OCR2 = 100; 70: 84 e6 ldi r24, 0x64 ; 100 72: 83 bd out 0x23, r24 ; 35 TIMSK = 0b10000000;//input cp int enable, int on match A enable 74: 80 e8 ldi r24, 0x80 ; 128 76: 89 bf out 0x39, r24 ; 57 78: ff cf rjmp .-2 ; 0x78 <main+0xc> 0000007a <_exit>: 7a: f8 94 cli 0000007c <__stop_program>: 7c: ff cf rjmp .-2 ; 0x7c <__stop_program>
to be continued...







Zitieren

Lesezeichen