TOV0 má absolutní bitovou adresu? Optimalizace vynechává kód

Dobrý den,
potřeboval bych poradit jak upravit následující kód aby ho optimalizátor nevyhodil, nebo co dělám špatně?

jedná se o podmínky if.
Pokud to dobře vidím tak podmínka od TOV1 je jako splněna vždy a TOV0 je vynechaná úplně

optimalizace -os


typedef struct hradlovane{
	unsigned long int 	hi;		//cas hradlovani hi			
	unsigned int		lo;		//hradlovany low
	unsigned long int	rev;	//hradlovany rev
}hradlovane;

register unsigned long int	time_hi asm("r4");	//pocet pøeteèení ICR1, aktuální drobne v ICR1
register unsigned long int	gas 	asm("r8");	//pocet impulzu plynomeru
unsigned long int  			rev_imp;			//pocet impulzu z rev (dolni 8b nechan pro doplneni act rev)
hradlovane 					data_hr;			//hradlovana data od plynu


ISR(INT1_vect){ // External Interrupt Request 1
	data_hr.lo=TCNT1;
	data_hr.hi=time_hi;
	if(TOV1) data_hr.hi++;		//pokud pretekl ve stejny okamzik (INT1 ma prioritu) - korekce						
	data_hr.rev=rev_imp + TCNT0;
	if(TOV0) data_hr.rev+=256;	//pokud pretekl ve stejny okamzik (INT1 ma prioritu) - korekce
	gas++;
}

disassembler

@0000016B: __vector_2
231:      ISR(INT1_vect){ // External Interrupt Request 1
+0000016B:   921F        PUSH      R1             Push register on stack
+0000016C:   920F        PUSH      R0             Push register on stack
+0000016D:   B60F        IN        R0,0x3F        In from I/O location
+0000016E:   920F        PUSH      R0             Push register on stack
+0000016F:   2411        CLR       R1             Clear Register
+00000170:   932F        PUSH      R18            Push register on stack
+00000171:   938F        PUSH      R24            Push register on stack
+00000172:   939F        PUSH      R25            Push register on stack
+00000173:   93AF        PUSH      R26            Push register on stack
+00000174:   93BF        PUSH      R27            Push register on stack
232:      	data_hr.lo=TCNT1;
+00000175:   B58C        IN        R24,0x2C       In from I/O location
+00000176:   B59D        IN        R25,0x2D       In from I/O location
+00000177:   939002FA    STS       0x02FA,R25     Store direct to data space
+00000179:   938002F9    STS       0x02F9,R24     Store direct to data space
234:      	if(TOV1) data_hr.hi++;		//pokud pretekl ve stejny okamzik (INT1 ma prioritu) - korekce						
+0000017B:   01D3        MOVW      R26,R6         Copy register pair
+0000017C:   01C2        MOVW      R24,R4         Copy register pair
+0000017D:   9601        ADIW      R24,0x01       Add immediate to word
+0000017E:   1DA1        ADC       R26,R1         Add with carry
+0000017F:   1DB1        ADC       R27,R1         Add with carry
+00000180:   938002F5    STS       0x02F5,R24     Store direct to data space
+00000182:   939002F6    STS       0x02F6,R25     Store direct to data space
+00000184:   93A002F7    STS       0x02F7,R26     Store direct to data space
+00000186:   93B002F8    STS       0x02F8,R27     Store direct to data space
235:      	data_hr.rev=rev_imp + TCNT0;
+00000188:   B722        IN        R18,0x32       In from I/O location
+00000189:   918002F1    LDS       R24,0x02F1     Load direct from data space
+0000018B:   919002F2    LDS       R25,0x02F2     Load direct from data space
+0000018D:   91A002F3    LDS       R26,0x02F3     Load direct from data space
+0000018F:   91B002F4    LDS       R27,0x02F4     Load direct from data space
+00000191:   0F82        ADD       R24,R18        Add without carry
+00000192:   1D91        ADC       R25,R1         Add with carry
+00000193:   1DA1        ADC       R26,R1         Add with carry
+00000194:   1DB1        ADC       R27,R1         Add with carry
+00000195:   938002FB    STS       0x02FB,R24     Store direct to data space
+00000197:   939002FC    STS       0x02FC,R25     Store direct to data space
+00000199:   93A002FD    STS       0x02FD,R26     Store direct to data space
+0000019B:   93B002FE    STS       0x02FE,R27     Store direct to data space
237:      	gas++;
+0000019D:   9408        SEC                      Set Carry
+0000019E:   1C81        ADC       R8,R1          Add with carry
+0000019F:   1C91        ADC       R9,R1          Add with carry
+000001A0:   1CA1        ADC       R10,R1         Add with carry
+000001A1:   1CB1        ADC       R11,R1         Add with carry
238:      }
+000001A2:   91BF        POP       R27            Pop register from stack
+000001A3:   91AF        POP       R26            Pop register from stack
+000001A4:   919F        POP       R25            Pop register from stack
+000001A5:   918F        POP       R24            Pop register from stack
+000001A6:   912F        POP       R18            Pop register from stack
+000001A7:   900F        POP       R0             Pop register from stack
+000001A8:   BE0F        OUT       0x3F,R0        Out to I/O location
+000001A9:   900F        POP       R0             Pop register from stack
+000001AA:   901F        POP       R1             Pop register from stack
+000001AB:   9518        RETI                     Interrupt return

děkuji

:arrow_right: administrator: přejmenováno z "proč optimalizace vynechává kód?"

if (TIFR & _BV(TOV1)) data_hr.hi++; 
if (TIFR & _BV(TOV0)) data_hr.rev+=256;

Samostatné TOV0 má totiž (pravděpodobně) hodnotu 0, tak se pak nediv,
že ti to překladač vynechá. :smiling_imp:

Jé to jsem pako… dluho jsem nic nedělal a myslel jsem že TOV0 má absolutní bitovou adresu. To ale v avr asi vůbec není :smiley: myslet znamená h… vědět :smiley:
podobnou hloupost jsem čekal.

Dík

výsledný kód tak nabobtnal o 100bajtů v asm by to bylo o dost méně :frowning:

Pochybuji, že choděj impulzy tak rychle, že by bylo třeba umisťovat nějaké proměnné natvrdo do registrů. Navíc jak si můžeš všimnout, time_hi se stejně nejdřív kopíruje a teprve pak se s ní provedou požadované operace.

Proměnné, se kterými se pracuje v přerušení (struktura) a nejsou v registrech(tady si nejsem jistej jesli to pro ně taky neplatí), musejí být VOLATILE.

Seš si jistej, že je dobrej nápad mít jméno struktury a z ní vytvořený datový typ stejné?

Zjišťuješ tu přetečení timeru, ale flag neresetuješ. Seš si jistej, že se ti to někde jinde nepřičte ještě jednou?

Piity: šlo mě hlavně o délku kódu v přerušení a takhle vycházel nejkratší. Jinak toho kopíroval mnohem víc a navíc ty registry pushoval. Tím že jsem obsadil nějaké registry tak se zkrátili kódy všech přerušení. měřím desetiny mikrosekund. s time_hi se pracuje ještě v jiném přerušení.

flag neresetuji příslušné přerušení se po tom provede. zde to přičítám k jiné proměnné. mohl bych si v tomto náhodném případě ušetřit jedno následné přerušení ale za cenu delšího tohohle přerušení vždy.

Tu strukturu opravím ať to tedy trochu vypadá :slight_smile:

volatile řeší problém “šahání” do paměti z více míst a zajišťuje úplnost vícebytových proměnných? jinak volatile asi platí obecně ne? v asm to pak vypadá stejně.

dík za rady a postřehy. těch problému bude opět asi víc a hlavně mezi židlí a klávesnicí :smiley:

Když vynecháš volatile, může se ti stát, že překladač odoptimalizuje části kódu, kde se k proměnné přistupuje vícekrát, přičemž mezi jednotlivými přístupy může zasáhnout přerušení. O tom totiž bez volatile překladač neví a takový přístup odstraní jako zbytečné zpomalení kódu. Typicky na to narazíš, když v nekonečný smyčce mainu čekáš na proměnnou, která se změní v přerušení. Optimalizátor pak kontrolu provede jen 1x místo každého průchodu smyčkou a pak se člověk diví a diví a nadává… :slight_smile:
Zkrátka proměnná použitá v přerušení a zároveň mimo něj -> volatile.

To si budu muset někam napsat. Chtělo by to sbírku pouček :smiley:. co kdy kde bezmyšlenkovitě použít aby to bylo bez problémů. Dal jsem to tam. Program funguje stejně a zase o několik bytu delší. až bude čas, schválně se podívám co v asm spáchal… :slight_smile: