CORRECCIÓN: Como han señalado Ben (y otros comentaristas), borrar el indicador de estado en el código principal es un problema. Las escrituras en los campos de bits se implementan normalmente como una lectura-modificación-escritura, donde (en su caso) se lee el byte completo, luego se establece o se borra un bit, luego se escribe la escritura del byte modificado. En el pseudocódigo, ISRstatus.ISR0 = 0 se convertiría en:
char temp = ISRstatus;
temp &= ~0x01;
ISRstatus = temp;
El problema aquí es que una interrupción puede venir en medio de esta secuencia. Por ejemplo, digamos que el indicador ISR0 está establecido e ingresa la interrupción 5. Lo que sucede es:
<interrupt 0>
ISRstatus |= 0x01; //Not really atomic, but it doesn't matter here
<exit interrupt 0>
if (ISRstatus.ISR0)
{
temp = ISRstatus;
temp &= 0x01;
<interrupt 5>
ISRstatus |= 0x20; //Not really atomic, but it doesn't matter here
<exit interrupt 5>
ISRstatus = temp;
}
En este ejemplo, ISRstatus debe ser igual a 0x20 después de la instrucción if, pero en cambio es igual a 0x00. La bandera ISR5 se perdió.
La forma de solucionar este problema es deshabilitar las interrupciones al escribir en la variable global en su código principal. (Las lecturas son seguras siempre y cuando toda la estructura se cargue a la vez, lo que debería ser para una estructura de 8 bits).
El estándar C no garantiza ningún pedido o empaquetamiento particular de los campos de bits. Esto significa que el uso de campos de bits para acceder a los datos almacenados en un formato específico (como los campos de registro o encabezado de paquete) no es portátil. Si solo hay un compilador para su CPU, la portabilidad no será un problema, por lo que puede salirse con la suya.
Mi lectura del estándar es que los campos de bits están diseñados para ser utilizados exactamente de la forma en que los estás utilizando. Solo ten en cuenta las limitaciones.
EDIT v2: El compilador probablemente no permitirá que un solo campo de bits cruce un límite de unidad de almacenamiento. El manual de su compilador debería tener más información, pero puede tomar un poco de prueba y error para resolver los casos de borde. Ya que todo lo que te importa es la información en los campos individuales y no su disposición dentro de la unidad de almacenamiento, esto no debería importar.
Dicho todo esto, la portabilidad generalmente no es una gran preocupación para el código de interrupción, y es poco probable que un compilador cambie la forma en que maneja los campos de bits en una versión más reciente.