Tienes razón con el # 2: se requerirán dos "hilos".
Por lo general, su rutina de interrupción guardará los caracteres en un búfer. Su programa principal leerá continuamente el búfer, llamará a detectString e implementará su lógica.
Puede usar el control de flujo de hardware si le preocupan los caracteres faltantes. Una vez que el búfer esté lleno, puede hacer que el remitente espere hasta que esté listo de nuevo.
Su FSM podría ser una declaración de cambio dentro de su bucle principal.
EDIT : Algún código:
/* UART0 Receive Interrupt Vector */
ISR(USART0_RX_vect)
{
static uint8_t tmp;
// calc next insert index & store character
tmp = (uart0_rx_insert_idx + 1) % UART0_RX_BUFFER_SIZE;
uart0_rx_buffer[uart0_rx_insert_idx] = UDR0;
// check for more room in queue
if (tmp != uart0_rx_extract_idx)
uart0_rx_insert_idx = tmp; // update insert index
}
enum fsm {
IDLE,
MAGIC,
};
int main(void) {
// setup
enum fsm state = IDLE;
uint8_t wordbuf[10];
uint8_t wordbuf_index = 0x00u;
setLed(0);
uartSetup();
//activate interrupts
sei();
// mainloop
while (1) {
switch (state) {
case IDLE:
if (characterInBuffer()) {
// if buffer is full; word still not found
// shift all characters by one
if (wordbuf_index == sizeof(wordbuf) - 1)
memcpy(&wordbuf[1], &wordbuf[0], sizeof(wordbuf));
// save current character
wordbuf[wordbuf_index] = readCharacterFromBuffer();
// increment index if not at end of buffer
if (wordbuf_index != sizeof(wordbuf) - 1)
wordbuf_index++;
if (detectString(wordbuf))
state = MAGIC;
}
if (getCharacter())
break;
case MAGIC:
setLed(1);
if (buttonPressed()) {
setLed(0);
state = IDLE;
}
break;
} /* switch */
} /* while */
return 0;
} /* main */
Esto sería para un microcontrolador Atmel AVR ATmega. Muchos microcontroladores tienen tablas de vectores estáticos que almacenan las direcciones de i nterrupt s ervice r outines (ISR, por sus siglas en inglés) que están presentes en su código.
Cuando se activa una interrupción periférica, como la interrupción de recepción UART en el ejemplo anterior, y las interrupciones globales están habilitadas (sei () call), el microcontrolador se detendrá ejecutando el código principal y < em> start ejecutando el código ISR. Cuando salga el ISR, la ejecución se reanudará en el código principal.
Hay microcontroladores que tienen un controlador programable de interrupción vectorial (VIC). Con estos, puede asignar libremente un ISR en tiempo de ejecución en lugar de tiempo de compilación (e incluso cambiar en tiempo de ejecución). La idea sigue siendo la misma:
- condición de interrupción de avisos de hardware,
- el flujo principal del programa se detiene
- se ejecuta ISR
- se reanuda el flujo principal del programa
Puede tener bloqueos mutex y bloqueos giratorios en su código. Solo debe tener cuidado con los bloqueos muertos y utilizar los tipos adecuados, es decir, los tipos atómicos.
Hay algunos sabores de microcontroladores que tienen un sistema de interrupción hiarárquica: un tipo de interrupción puede interrumpir otra interrupción. Con estos, debe tener especialmente en cuenta el uso de la exclusión mutua y la escritura correcta.
En general, se supone que los ISR son muy delgados y no deben tener piezas largas de código o bucles. El motivo es simple: mientras se ejecuta su ISR, el programa principal no lo está. Como el programa principal generalmente hace algo muy útil, no querrá que se interrumpa durante un período de tiempo prolongado.
Tener un sistema operativo (SO) en microcontroladores suele ser opcional . Ciertamente puede escribir un código C de una sola vez y terminar con él. Si le interesa la reutilización de su código o la posibilidad de utilizar un código preexistente, es posible que desee consultar ChibiOS, FreeRTOS, etc.
Los sistemas operativos normalmente encapsularán la idea de interrupciones (o incluso interrupciones vectoriales) y presentarán una interfaz común para su programa de nivel superior. Sin embargo, los trabajos "debajo del capó" son los descritos anteriormente.
Si desea hacer muchas cosas en paralelo y usar aplicaciones de subprocesos, debería buscar el código popular. Por lo general, tienen mutexes, giros de seguridad, etc. pre-hechos y listos para usar.