Newsgroup: it.hobby.elettronica.digitale
Titolo: Come disabilitate gli interrupt?

Fino a qualche giorno fa ero solito disabilitare gli interrupt (per 
esempio, per entrare in una sezione critica del codice) utilizzando la 
macro apposita (se esiste nelle librerie della CPU in uso) o l'inline 
assembler che resetta il flag di abilitazione globale degli interrupt.
 
disableInterrupts();
... critical section ...
enableInterrupts();
 
Ho capito che fatto proprio così, senza preoccuparsi di altro, è 
parecchio rischioso, soprattutto se è attivo l'ottimizzatore del 
compilatore che può mescolare le istruzioni a suo piacimento, quindi 
portando alcune istruzioni della sezione critica prima della 
disabilitazione o dopo l'abilitazione degli interrupt.
 
Vi siete mai fatti questo problema? Per me, dopo anni di sviluppo 
embedded, è una scoperta a dir poco sbalorditiva :-)


 
il programmatore dell'ottimizzatore che permetterebbe una cosa del 
genere ( spostare istruzioni da dentro a fuori quella sezione)  , 
******in presenza di dis/abilitazione di interrupts******* ...
 
andrebbe radiato ... dalla faccia della terra ;-)
 


Il compilatore non ha idea che stai disabilitando gli interrupt.
 
Prendiamo gli AVR, per disabilitare gli interrupt c'è una istruzione 
macchina CLI, per l'abilitazione c'è SEI. Se ti limiti a fare:
 
asm("CLI");
/* Critical section code */
asm("SEI");
 
come fa il compilatore (avr-gcc) a sapere che quell'istruzione assembler 
è una disabilitazione degli interrupt? Per lui è un'istruzione assembler 
che potrebbe fare qualsiasi cosa.
 
Allo stesso modo per i Cortex-Mx dove la disabilitazione dell'interrupt 
avviene con l'istruzione assembler "CPSID i".
 
 
Almeno mi consolo, non ero l'unico a non conoscere questo aspetto...
 


 
non sono d'accordo
 
l'ottimizzatore deve valutare i casi 'estremi' che gli debbono far 
prendere una strada piuttosto che un'alttra
 
ed il caso di istruzioni 'sensibili' va messa come condizione da 
valutare a parte [ 'basta' scandagliare l'intero listato e vedere se se 
in presenza di "un ciclo" come nel tuo caso, oppure vengano disabilitati 
e basta; 'valutare' se una 'asm' esegua codice 'sensibile' , come nel 
tuo caso che diabilita gli interrupt, secondo me è uno di quei casi che 
va 'soppesata' opportunamente]
 
altrimenti è solo una stronzata
 
"ti piace vincere facile, eh" gli direi al sedicente 'programmatore' che 
ha scritto quell'OTTIMIZZATORE del cavolo che non tiene conto di questa 
tipologia di casi estremi !!



Beh, allora quelli del gcc sono "sedicenti programmatori" :-)
 
	x = 5;
	asm ("cli");
	x += 5;
 
      c34:	f8 94       	cli
      c36:	8a e0       	ldi	r24, 0x0A	; 10
      c38:	80 93 a4 02 	sts	0x02A4, r24
 
Qui l'ottimizzatore non si preoccupa molto che ci sia un *pericoloso* 
cli, si preoccupa solo di ottimizzare, anche spostando l'istruzione asm.
 
 
 

Un bel giorno pozz digitò:

In molti contesti di certificazione del software l'utilizzo
dell'ottimizzatore non è proprio consentito, per questo e altri motivi, per
cui io se non sono obbligato tendo a non attivare ottimizzazioni spinte del
compilatore.
 
In ogni caso solitamente per risolvere questo problema è possibile usare il
meccanismo delle "memory barrier":
 
https://en.wikipedia.org/wiki/Memory_barrier
 
 
In molti casi (ma non tutti) è sufficiente inserire il codice di
disattivazione/attivazione degli interrupt in una funzione separata,
assicurandosi che il compilatore non la ottimizzi a sua volta come inline
(altrimenti sei al punto di partenza). Però anche in questo caso esistono
trappole. In sostanza è un argomento che merita molto approfondimento.
Caveat emptor! :-)
 
-- 
Fletto i muscoli e sono nel vuoto.

 Caveat emptor! :-)
 
Per me è stato incredibile imparare un argomento di cui ignoravo 
completamente l'esistenza, pur essendo così fondamentale nella 
programmazione embedded.
 
 
Gli effetti dell'ottimizzatore coinvolgono anche altri aspetti. Per esempio:
http://www.atmel.com/webdoc/AVRLibcReferenceManual/optimization_1optim_code_reorder.html
 
 
 

 piacimento
 
motivo per cui preferisco l'assembler
 
..


 > ...
 
Per fare cosa? Un device driver oppure un'intera applicazione?
 
Me la vedo dura fare una intera applicazione, anche se relativamente 
semplice, tutta in assembler...
 

 per alcune parti del codice o, almeno, per una determinata funzione.
 
Beh, quasi tutti i compilatori permettono di disattivare l'ottimizzazione
per determinati file. E' sufficiente mettere le funzioni che non vuoi
ottimizzare (o viceversa quelle che vuoi ottimizzare) in file separati.
 
Alcuni compilatori dispongono anche di #pragma specifiche per selezionare
singole funzioni, ma questo è molto meno comune.



ci sono applicazioni ad alto livello e applicazioni a basso livello.
Trattare applicazioni a basso livello con linguaggi ad alto livello 
comporta più svantaggi che vantaggi.
 
..

 singole funzioni, ma questo è molto meno comune.
 
Hai idea se questa cosa si può fare con il gcc?
 
 

 Hai idea se questa cosa si puň fare con il gcc?
 
Col #pragma non so, ma sicuramente agendo sul makefile si puň fare! Puoi
specificare flag specifici da passare al compilatore (inclusa
l'ottimizzazione) per ogni file sorgente.
