È necessario disattivare gli interrupt per garantire l'accesso atomico. Non vuoi che nessun altro processo acceda e potenzialmente modifichi quella variabile mentre la stai leggendo.
Da Introduction to Embedded Computing:
la necessità di accesso atomica
Immaginate questo scenario: programma in primo piano, in esecuzione su un 8-bit uC, necessità di esaminare una variabile a 16 bit, lo chiamano X Quindi carica il byte alto e quindi carica il byte basso (o viceversa, l'ordine non ha importanza), quindi esamina il valore a 16 bit. Ora immagina un interrupt con un ISR associato che modifica quella variabile a 16 bit. Inoltre, immagina che il valore della variabile sia 0x1234 a in un dato momento nell'esecuzione del programma. Qui è la cosa molto brutta che può accadere:
- carichi in primo piano byte alto (0x12)
- ISR si verifica, modifica X per 0xABCD
- carichi di primo piano byte basso (0xCD)
- programma in primo piano vede un valore a 16 bit di 0x12CD.
Il problema è che un pezzo apparentemente inscindibile di dati, il nostro variabili X, è stato effettivamente modificato nel processo di accedervi, perché le istruzioni della CPU di accedere alla variabile erano divisibili. E quindi il nostro carico della variabile X è stato corrotto. Puoi vedere che l'ordine della variabile letto non ha importanza. Se l'ordine fosse invertito nel nostro esempio, la variabile sarebbe stata erroneamente letta come 0xAB34 invece di 0x12CD. In entrambi i casi, il valore letto non è né il vecchio valore valido (0x1234) né il nuovo valore valido (0xABCD).
La scrittura di dati con riferimento ISR non è migliore. Questa volta supponiamo che il programma in primo piano abbia scritto, a beneficio dell'ISR, il valore precedente 0x1234 , e quindi debba scrivere un nuovo valore 0xABCD.In questo caso, la VBT è la seguente:
- negozi di primo piano nuovo massimo di byte (0xAB)
- ISR si verifica, si legge X come 0xAB34
- negozi in primo piano nuovo byte basso (0xCD)
Ancora una volta il codice (questa volta l'ISR) non visualizza né il valore valido di 0x1234, né il nuovo valore valido di 0xABCD, ma piuttosto il valore non valido di 0xAB34.
Mentre spiTxRxByteCount &= ~0x0100;
può sembrare una singola istruzione in C, in realtà sono diverse istruzioni per la CPU. Compilato nel GCC, la quotazione di montaggio si presenta in questo modo:
57:atomic.c **** spiTxRxByteCount &= ~0x0100;
68 .loc 1 57 0
69 004d A1000000 movl _spiTxRxByteCount, %eax
69 00
70 0052 80E4FE andb $254, %ah
71 0055 A3000000 movl %eax, _spiTxRxByteCount
71 00
Se un interrupt arriva nel mezzo di dette istruzioni e modifica dei dati, il vostro primo ISR può potenzialmente leggere il valore errato. Quindi è necessario disabilitare gli interrupt prima di operare su di esso e dichiarare anche la variabile volatile
.
Se si dispone di un RTOS, perché non utilizzare un mutex? –
@ [Operazione di semaforo implementata in questo modo in ambiente operativo] (http://www.mpi-sws.org/~druschel/courses/os/lectures/proc4.pdf) –