¿Programa de manejo de interrupciones simple?

0

Soy nuevo en la programación incrustada y estoy tratando de entender cómo funcionan los manejadores de interrupciones en diferentes contextos / escenarios. Solo quiero saber cómo funcionaría un controlador de interrupciones en el siguiente escenario.

Tenemos un flujo de datos proveniente de una interfaz RS232 que se procesa mediante un microcontrolador. Un manejador de interrupciones (de tipo vacío) tiene una función de lectura () que lee los bytes de datos entrantes. Si se detecta un carácter, el controlador de interrupciones invoca una función llamada detectString () que devuelve VERDADERO si la cadena coincide con la cadena de referencia que está "ENCENDIDA". Si detectString () devuelve Boolean TRUE, invoca una función llamada LED_ON () que debería encender un LED durante 1 minuto. Si devuelve falso, debe apagar el LED. Digamos que el microcontrolador tiene una frecuencia de reloj de 20MHz y una operación de adición realizada 5 ciclos de reloj.

Mis preguntas son las siguientes

  1. ¿Cómo abordamos este problema con un FSM?
  2. La interfaz RS232 sigue transmitiendo datos incluso después de encender el LED. Entonces, ¿estoy en lo cierto al suponer que el controlador de interrupciones debería funcionar con un solo hilo y las funciones que invoca deberían funcionar desde un hilo diferente?
  3. ¿Cómo sería un programa esquelético que implementa este FSM? (pseudocódigo puede ayudar realmente a entender la columna vertebral del diseño)
pregunta Naveen

1 respuesta

2

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.

    
respondido por el FRob

Lea otras preguntas en las etiquetas