Está en la página 1de 38

Embedded C

Programming
Máquina de Estados Finitos

Máquinas de Estados Finitos

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Máquinas de Estados Finitos

Una Máquina de Estado Finito (Finite State Machine), llamada también Autómata Finito es una abstracción
computacional que describe el comportamiento de un sistema reactivo mediante un número determinado de
Estados y un número determinado de Transiciones entre dicho Estados.

Una máquina de estados finitos se compone principalmente de de tres elementos:

• Estados
• Transiciones
• Acciones

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Máquinas de Estados Finitos

Una de las características universales de todas las máquinas de estado es el procesamiento de eventos Run-to-
completion (RTC). Esto significa que una máquina de estados sólo puede procesar un estado a la vez, así que el
procesamiento de un evento tiene que completarse obligatoriamente para que el siguiente evento pueda iniciar.

Ventajas de las máquinas de estado:

• Son intituivas y fáciles de utilizar


• Facilita el diseño y análisis del sistema
• Son universalmente aplicables (Se usan en diferentes aplicaciones como sistemas de transmisión de datos,
protocolos de comunicación, manejadores de eventos, diseño de máquinas industrales, etc.).
• Minimiza la tendencia a escribir “código espagueti”.

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Máquinas de Estados Finitos – Buenas prácticas

Algunos consejos para obtener el mejor rendimiento de las máquinas de estados finitos:

• No caer en el error de definir demasiados estados para el sistema, lo cual minimiza la eficiencia

• No caer en el error de definir menos estados de lo que es necesario, lo cual contradice al propósito de las FSM,
lo cual va provocar demasiado uso de sentencias condicionales y al final tener código espagueti.

• No abusar de los condicionales de protección (guard conditions) ya que el código se terminará viendo como
espagueti.

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Máquinas de Estados Finitos – Blinking LED

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Máquinas de Estados Finitos – Blinking LED

La manera más sencilla de representar todos los posibles estados que puede adoptar una máquina de estados es a
través de una enumeración.

.c
Blinking_led_fsm.c

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Máquinas de Estados Finitos – Blinking LED

.c Blinking_led_fsm.c

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Sintáxis Básica de
una Máquina de
Estados Finitos - UML

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Guard Conditions (Condicionales de Protección)


Las condicionales de protección son expresiones boleanas evaluadas en función del valor de los parámetros del
evento y/o las variables asocioadas con la máquina de estados. En UML se representa con un condicional en forma
de diamante.

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Guard Conditions
(Condicionales de
Protección) - UML
En el siguiente ejemplo el programa
hará que el LED parpadee 3 veces y
después entrará en un estado de
reposo permanente.

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Máquinas de Estados Finitos – Blinking LED con Condicional de Protección

Agregamos un estado más a la máquina de estados. El estado agregado se llama IDLE_STATE.

.c
Blinking_led_fsm.c

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Máquinas de Estados Finitos – Blinking LED con Condicional de Protección

.c Blinking_led_fsm.c

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Aplicación con una Máquina Expendedora Industrial de Horneado. (Vending Industrial


Oven Machine)

Una máquina expendedora industrial de horneado normalmente tiene un display y teclado donde el usuario
puede realizar su orden y una puerta trasera en donde se puede recoger el producto horneado.

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Sensores Fotoelectricos

Sensores electrónicos cuya función es la detección de objetos sin tener contacto físico con ellos. Por lo general
poseen alcance de centímetros a metros. Existen varios tipos, dentro de los principales destacan:

• Retro-reflective Retro-reflective Diffuse-reflective


• Diffuse-reflective
• Convergent-reflective

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

Programming
Programación en Lenguaje C - Máquina de Estados Finitos

.c oven_app.c

Programming
Programación en Lenguaje C – Manejo de Eventos

Manejo de Eventos

Muchos sistemas embebidos son sistemas reactivos, es decir, interactúan constantemente con su medio ambiente,
tiene la característica de ser conducido por eventos (event driven), la respuesta de tiempo es crítica y una vez que
el sistema se activa permanece en ese estado de manera indefinida.

En estos sistemas los eventos llegan en tiempos impredecibles y el sistema debe tener la capacidad de responder
de manera inmediata.

Estos sistemas están típicamente conectados a varios tipos de sensores y transductores de entrada encargados de
captar los estímulos del medio ambiente (temperatura, presión, luz, magnetismo, fuerza / peso, etc.). El sistema
debe de procesar dicha información y generar una respuesta del sistema hacia el medio ambiente a través de
transductores de salida y actuadores.

Programming
Programación en Lenguaje C – Manejo de Eventos

Manejo de Eventos

En nuestra aplicación de horno industrial requerimos interactuar con diversos sensores e interruptores que
complementan el sistema:

• Boton de Paro (Stop Button).


• Sensores fotoeléctricos para detección de los productos que llegan a la banda
• Sensores magnéticos que monitorean el estado de la puerta del horno
• Líneas de comunicación que interactuan con otro sub-sistema (Por ejemplo otro sistema electrónico
independiente que comunique a nuestro sistema cuando el horno se encuentra en la temperatura adecuada
para hornear).
• Sensores de temperatura, luminosidad, calidad de aire, etc.

¿Cómo interactuamos con la amplia diversidad de sensores e interruptores sin que nuestra aplicación colapse?
¿Cuál es la manera correcta de interacuar con todos los eventos que generan estos sensores e interruptores?

Programming
Programación en Lenguaje C – Manejo de Eventos

Manejo de Eventos

Para continuar con el estudio de este tema, vamos a enfocarnos en un evento puntual de nuesta aplicación.

TEMPERATURA DEL HORNO LISTA

Este evento se dispara cuando la temperatura del horno está lista para iniciar con el horneado. Este evento puede
ser disparado por nuestro sistema interactuando con un sensor de temperatura, o bien por un sistema
independiente colocado en el horno que nos avise de alguna forma cuando la temperatura este lista.

Asumamos el segundo caso: Nuestro sistema recibe en una línea de entrada digital un 0 lógico cuando la
temperatura está lista, de lo contrario recibe un 1 lógico.

Programming
Programación en Lenguaje C – Eventos Síncronos

Máquina de Estado con Eventos Síncronos

Un punto de partida es evaluar los eventos síncronos. Un evento síncrono se activa mediante una llamada a una
operación en la máquina de estados y el cliente que llama espera (se bloquea) hasta que se completa la respuesta
al evento.

Cuando se presenta un evento síncrono o se llama a una función síncrona, el flujo de ejecución no puede avanzar
hasta que se complete la respuesta al evento. A este comportamiento se le llama bloqueante (blocking functions /
blocking events).

Programming
Programación en Lenguaje C - Eventos Síncronos

Máquina de estado con Eventos Síncronos

.c oven_app.c

La linea while(oven.IsTemperatureReady(OVEN_TEMP_RDY) == false)hará que se bloque el flujo


de ejecucion hasta que el horno tenga la temperatura lista. Asuma que dicha función siempre regresará true
mientras la temperatura del horno esté lista.

Programming
Programación en Lenguaje C - Eventos Síncronos

Máquina de estado con Eventos Síncronos .c blinking_led_fsm.c


.c oven_app.c

Si existen otras tareas en la aplicación, ya sea en la misma máquina de


estados del horno u otra tarea de ejecución, se verá afectada por eventos
bloqueantes.

En nuestro ejemplo podemos observar que blinking led dejará de


funcionar hasta que el horno se encuentre en la temperatura adecuada.

Podemos concluir que todas las tareas están sincronizadas.

Programming
Programación en Lenguaje C – Eventos Asíncronos

Máquina de estados con Eventos Asíncronos

Podemos concluir que en nuestra aplicación, necesitamos que los disparadores de eventos (sensores e
interruptores) no estén sincronizados con las tareas de la aplicación. En otras palabras, requerimos que los
disparadores de eventos se ejecuten de manera independiente/asíncrona del consumidor de los eventos.

Un evento asíncrono se da cuando dicho evento se solicita bajo el mecanismo de “enviar y olvidar”. De esta forma
el flujo de ejecución puede continuar sus operaciones sin ser bloqueado.

Programming
Programación en Lenguaje C – Eventos Asíncronos

Máquina de estados con Eventos Asíncronos


Necesitamos que nuestro evento TEMPERATURA DEL HORNO LISTA se ejecute de manera asíncrona a la solicitud
del mismo recurso en nuestra aplicación.

Esto lo podemos resolver fácilmente con interrupciones: Se configura una interrupción externa con flanco de
bajada en el pin donde se recibe el 0 lógico que indica que la temperatura del horno está lista.

Sin embargo surgen nuevos desafíos:

• Comunicar a la máquina de estados que la interrupción se ha generado, por lo cual el horno tiene temperatura
lista para hornear.

• Manejar gran variedad de sensores e interruptores con líneas de interrupción.

• Manejar varios disparos del mismo evento.

• Comunicar a la aplicación datos adicionales (Ej. Valor de los sensores, timestamp, etc.)

Programming
Programación en Lenguaje C – Eventos Asíncronos

Máquina de estados con Eventos Asíncronos


Revisemos más a detalle los desafíos:

Comunicar a la máquina de estados que la interrupción se ha generado, por lo cual el horno tiene temperatura
lista para hornear:

Esto es sumamente importante ya que la máquina de estados hará una transición al siguiente estado una vez que
la temperatura del horno esté lista, por lo tanto una vez generada la interrupción, la máquina de estados deberá
pasar al siguiente estado. Pero ¿cómo notificamos desde una ISR a nuestra máquina de estados que la
temperatura se encuentra lista?

Programming
Programación en Lenguaje C – Eventos Asíncronos

Máquina de estados con Eventos Asíncronos

.c ext_int.c

¿Cómo notificamos desde la parte más


cercana al hardware hasta la capa de
aplicación?

.c app_oven.c

Programming
Programación en Lenguaje C – Eventos Asíncronos

Máquina de estados con Eventos Asíncronos


Comunicar a la máquina de estados que la interrupción se ha generado, por lo cual el horno tiene temperatura
lista para hornear:

Podemos utilizar banderas/flags que cambien su estado en cada evento de interrupción, y monitorear los flagas en
nuesta máquina de estados.

Sin embargo abordando este escenario caemos otra vez en ejecuciones bloqueantes ya que debemos de estar
continuamente monitoreando el estado del flag en la máquina de estados. De igual forma este escenario hace más
complejo manejar los demás desafíos planteados.

Otro escenario puede ser volver de alcance global los estados de la máquina de estados. De esta forma poder
cambiar el estado desde el archivo de interrupción. Sin embargo, ¿es buena idea que se pueda cambiar el estado
de la máquina de estados desde cualquier parte del programa? La respuesta es no. Después de todo no se espera
que las capas más cercanas al hardware, toquen objetos que pertenecen a la capa de aplicación. Es una pésima
práctica…

Programming
Programación en Lenguaje C – Eventos Asíncronos

Máquina de estados con Eventos Asíncronos


Comunicar a la máquina de estados que la interrupción se ha generado, por lo cual el horno tiene temperatura
lista para hornear:

Un escenario más viable es utilizar un puntero a función que se llame desde el archivo de interrupción, de esta
forma se puede disparar una función que se ejecute en la aplicación y cambie el estado de la máquina de estados.
Esto obedece al patrón de diseño observador.

Programming
Programación en Lenguaje C – Eventos Asíncronos

Máquina de estados con Eventos Asíncronos


Manejar gran variedad de sensores e interruptores con líneas de interrupción:

Esto vuelve más complejo la solución final ya que son diferentes fuentes que pueden disparar un evento, por lo
que nuestro programa necesita una forma inteligente de manejarlo. Si, la respuesta es un manejador de eventos
(EventHandler).

Programming
Programación en Lenguaje C – Eventos Asíncronos

Máquina de estados con Eventos Asíncronos


Manejar varios disparos del mismo evento:

Es común que un mismo evento se puede disparar más de una vez antes de que podamos antenderlo. Para cuando
podamos atenderlo debemos de conocer la información que generó en cada uno de los eventos pasados.

Para esto debemos de utilizar colas (Event Queuing) en donde cada evento disparado se irá guardando en la cola
de eventos. De esta forma cuando podamos atender un evento, realmente estaremos leyendo la cola pendiente
de eventos que tenemos por atender.

Programming
Programación en Lenguaje C – Eventos Asíncronos

Máquina de estados con Eventos Asíncronos


Comunicar a la aplicación datos adicionales:

Cuando un evento se dispare probablemente dicho evento tenga información adicional que ofrecernos. Por
ejemplo cuando se dispare el evento TEMPERATURA DEL HORNO LISTA, probablemente ese evento también nos
ofrezca la temperatura del horno, el estado actual del horno, un timestamp, etc.

Traer toda esta información a la capa de aplicación debe de hacerse de manera organizada y bien estructurada.

Programming
Programación en Lenguaje C – Eventos Asíncronos

Conclusión final, por ahora…


Es probable que necesitemos reconsiderar la estructura de nuestra aplicación para poder satisfacer los desafíos
anteriores. Lo anterior se le conoce como cambio de paradigma.

Podemos darnos cuenta que nuestra aplicación obedece a una estructura de ejecución secuencial tradicional, por
lo que esperamos que los eventos se disparen también de manera secuencial. Sin embargo los eventos realmente
llegan en tiempos impredecibles y eso no se lleva muy bien con la ejecución secuencial.

Afortunadamente hay un paradigma de programación que nos puede ayudar, su nombre es:

Event-Driven Programming (Programación Conducida por Eventos).

Programming

También podría gustarte