You are on page 1of 59

Máquinas de estado Diagramas de estado

Fundamentos de programación de Sistemas Embebidos


Máquinas de estado y diagramas de estado.

Mg. Ing. E. Sergio Burgos

Universidad Nacional de Entre Rı́os


Facultad de Ingenierı́a
Especialización en Sistemas Embebidos

28/09/2018

1 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Un problema simple
Se requiere realizar una implementación de un software para un sistema embebido que encienda y
apague un led a intervalos de 500 ms. ¿Cómo lo implementarı́a? ¿Cómo lo representarı́a?

Diagrama de Flujo

2 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Un problema simple
Se requiere realizar una implementación de un software para un sistema embebido que encienda y
apague un led a intervalos de 500 ms. ¿Cómo lo implementarı́a? ¿Cómo lo representarı́a?

Diagrama de Flujo Diagrama de transición de estados


(aproximación)

2 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Máquinas de estado finito


Aparece la idea de estados en un sistema digital. Un estado es un conjunto identificable y
único de mediciones en un sistema.
El funcionamiento de un sistema a lo largo del tiempo se representa utilizando estados y sus
transiciones.
Las transiciones se dan alcanzarse una determinada condición.
Las transiciones pueden realizarse entre estados diferentes o hacia el mismo estado.

3 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Máquinas de Moore y Mealy


Existen dos modelos:
Máquina de Moore: las salidas se establecen según el estado actual. Las transiciones se dan
en función de las entradas.

Esta representación puede leerse como: en el estado 0 se tendrá una salida 0, la transición al
estado 1 (que producirá la salida 1) se dará cuando se produzca la entrada x.
Máquina de Mealy: en este modelo la actualización de las salidas se produce durante la
transición de estados.

Aquı́, a partir del estado 0, cuando se produzca la entrada x se producirá la salida y al-
canzándose el estado 1.

4 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Ejemplo
Se requiere diseñar un sistema digital que determine la presencia de la secuencia 110. El sistema
tendrá una entrada en cada ciclo de reloj y deberá producir una salida que representa la identificación
del valor anterior (1 en caso que se lo haya detectado o 0 en caso contrario) .

5 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Ejemplo
Se requiere diseñar un sistema digital que determine la presencia de la secuencia 110. El sistema
tendrá una entrada en cada ciclo de reloj y deberá producir una salida que representa la identificación
del valor anterior (1 en caso que se lo haya detectado o 0 en caso contrario) .

5 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Ejemplo
Se requiere diseñar un sistema digital que determine la presencia de la secuencia 110. El sistema
tendrá una entrada en cada ciclo de reloj y deberá producir una salida que representa la identificación
del valor anterior (1 en caso que se lo haya detectado o 0 en caso contrario) .

6 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Máquinas de estado y software


Las máquinas de Moore y Maely son utilizadas en el diseño de circuitos digitales. Estableciendo
una metodologı́a de diseño para los mismos.

Permiten una representación de alto nivel del diseño del sistema.

Estos modelos pueden utilizarse (directamente o con variantes) para la implementación de aplica-
ciones para sistemas embebidos.
Permiten describir el software desde la perspectiva de un modelo. Indicando su funcionamiento
más que su implementación.
Denotan el mecanismo de funcionamiento de un modo claro, que permite el trabajo en grupos
y el intercambio de ideas.

7 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Implementación de Máquinas de Maely

while (! exit ) void InputAction_i ( input )


{ {
input = readInput (); switch ( input )
switch ( state ) {
{ case Input_0 :
case State_0 : DoAction_0 ();
InputAction_0 ( input ); break ;
break ; ...
... case Input_M :
case State_N : DoAction_M ();
InputAction_N ( input ); break ;
break ; default :
default : E r r o r _ U n e x p e c t e d I n p u t ();
E r r o r _ U n e x p e c t e d S t a t e (); break ;
break ; }
} }
ChangeState ( state , input );
}

8 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Implementación de Máquinas de Moore

while (! exit ) void Do_EntryAction ( stateType state )


{ {
input = readInput (); switch ( state )
next_state = ChangeState ( state , input ); {
if ( next_state != state ) case State_0 :
{ EntryAction_0 ;
Do_En tryAction ( next_state ); break ;
state = next_state ; ...
} case State_M :
} EntryAction_K ;
break ;
default :
E r r o r _ U n e x p e c t e d S t a t e ();
break ;
}
}

9 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Ejemplo de implementación
Se desea implementar una aplicación para un sistema embebido que proceses paquetes de datos
recibidos a través de una interfaz serie. El protocolo se ha implementado utilizando 5 bytes.
Donde:
b0: primer byte, valor constante igual a 0x0B.
b1 y b2: es la carga útil de información en cada paquete. En el caso de aplicación el b1
está asociado a un número de led (0 - 4) y b2 representa el estado del mismo (0 o 1).
b3: suma de comprobación en 8 bits de todos los valores del paquete recibidos hasta el mo-
mento.
b4: valor constante igual a 0xB0
La implementación debe lograrse de tal modo que, en caso de recibirse un byte erróneo, debe
reiniciar el procesamiento.

10 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Una solución posible


En este diagrama ch representa el dato recibido desde la interfaz serie. El valor de salida de la
máquina indicará si se ha alcanzado un paquete válido y debe ejecutarse una acción (modificarse
el estado de un led) o no.

¿Cómo lo podrı́amos implementar en lenguaje C (además de la implementación vista)?

11 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

package.h

/* D e f i n i c i ó n asociada a typedef uint8_t (* stFunctions )(


un paquete de datos */ statePkg * , uint8_t );
typedef struct {
uint8_t header ; /* I n i c i a l i z a la e s t r u c t u r a */
uint8_t ledId ; void stateInit ( statePkg *);
uint8_t onOff ;
uint8_t scRcv ; /* F u n c i o n e s para conmutar de estado */
uint8_t scCalc ; uint8_t stateHeader ( statePkg * , uint8_t );
uint8_t footer ; uint8_t stateLedId ( statePkg * , uint8_t );
} pkgData ; uint8_t stateOnOff ( statePkg * , uint8_t );
uint8_t stateSum ( statePkg * , uint8_t );
/* D e c l a r a c i ó n de los uint8_t stateFooter ( statePkg * , uint8_t );
estados posibles */
typedef enum { /* D e c l a r a c i o n e s a s o c i a d a s a las acciones */
stHeader = 0 , stLedId = 1 , typedef void (* pkgAction )( pkgData *);
stOnOff = 2 , stSum = 3 ,
stFooter = 4 void doLed0 ( pkgData *);
} stEnum ; void doLed1 ( pkgData *);
void doLed2 ( pkgData *);
typedef struct { void doLed3 ( pkgData *);
pkgData data ;
stEnum actState ; void processPackage ( uint8_t data );
} statePkg ;

12 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

package.c

const stFunctions stTrans [] = { uint8_t stateLedId ( statePkg * stPkg ,


stateHeader , stateLedId , uint8_t newData ){
stateOnOff , stateSum , stPkg - > data . scCalc += newData ;
stateFooter if (( newData >= 0) && ( newData < 4))
}; stPkg - > actState = stOnOff ;
else
void stateInit ( statePkg * stPkg ){ stPkg - > actState = stHeader ;
stPkg - > actState = stHeader ; return 0;
} }

uint8_t stateHeader ( statePkg * stPkg , uint8_t stateOnOff ( statePkg * stPkg ,


uint8_t newData ){ uint8_t newData ){
if ( newData == headerVal ) stPkg - > data . scCalc += newData ;
{ if (( newData == 0) || ( newData == 1))
stPkg - > data . header = headerVal ; stPkg - > actState = stSum ;
stPkg - > data . scCalc = headerVal ; else
stPkg - > actState = stLedId ; stPkg - > actState = stHeader ;
} return 0;
return 0; }
}
uint8_t stateFooter ( statePkg * stPkg ,
uint8_t stateSum ( statePkg * stPkg , uint8_t newData ){
uint8_t newData ){ uint8_t ret = 0;
stPkg - > data . scRcv = newData ; stPkg - > data . footer = newData ;
if ( stPkg - > data . scCalc == newData ) if ( newData == footerVal )
stPkg - > actState = stFooter ; ret = 1;
else stPkg - > actState = stHeader ;
stPkg - > actState = stHeader ; return ret ;
return 0; }
}

13 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

package.c

const pkgAction pkgActions [] = void doLed2 ( pkgData * pkg ){


{ if ( pkg - > onOff )
doLed0 , doLed1 , ledOn (2);
doLed2 , doLed3 else
}; ledOff (2);
}
void doLed0 ( pkgData * pkg ){
if ( pkg - > onOff ) void doLed3 ( pkgData * pkg ){
ledOn (0); if ( pkg - > onOff )
else ledOn (3);
ledOff (0); else
} ledOff (3);
}
void doLed1 ( pkgData * pkg ){
if ( pkg - > onOff ) /* C o n m u t a c i ó n de estados */
ledOn (1); void processPackage ( uint8_t data ){
else static statePkg pkg ;
ledOff (1); static uint8_t firstTime = 1;
} if ( firstTime ){
stateInit (& pkg );
firstTime = ! firstTime ;
}
if ( stTrans [ pkg . actState ](& pkg , data ))
pkgActions [ pkg . data . ledId ](& pkg . data );
}

14 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Conclusiones
La implementación presentada verifica la estructura de los paquetes entrando en sincronismo
de modo automático e indica la presencia de un conjunto de datos válidos.

En esta implementación la carga útil de cada paquete es pequeña, podrı́a utilizarse un paquete
de datos de mayor tamaño definiendo un estado que almacene los valores en un arreglo. Este
serı́a un campo de la estructura pkgData.

Del mismo modo podrı́a implementarse el procesamiento de paquetes de longitud variable.

Si la comunicación se basa en comandos, y estos se definen de modo correlativo, la ejecución


de los mismos se puede implementar a través de un arreglo.

15 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Diagramas de estado de Harel: Máquinas de estado 2.0


Las máquinas de estado y los diagramas de transición de estados son previos a los diagramas
de estado de Harel. Estos extienden las ideas originales agregando jerarquı́a, concurrencia y
comunicación.
Los diagramas de estado están incluidos en UML como una forma de representar el compor-
tamiento de sistemas o modelos.
En los diagramas de estado, se transita por estados como respuesta a eventos de diferente
tipo a lo largo de la vida de la aplicación.
Existen diferentes frameworks que permiten realizar implementaciones de diagramas de es-
tados para aplicaciones de escritorio y/o sistemas embebidos. Entre ellos RKH (http://
rkh-reactivesys.sourceforge.net) y Quantum Leap (http://www.state-machine.com/).
De modo similar, existen también herramientas CASE que permiten mantener el modelo del
sistema, simularlo y generar el código asociado a su implementación. Una de ellas es Yakindu
SCT (https://www.itemis.com/en/yakindu/state-machine/). Esta herramienta se integra
como un pluggin en Eclipse a partir del cual es posible diseñar diagramas de estados.

16 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Diagramas de estado de Harel


Los diagramas de estado de Harel agregan al modelo de máquinas de estado clásico nuevos ele-
mentos:
Estados compuestos y regiones
Historia permitiendo ingresar a una región o estado compuesto desde el último estado alcan-
zado.
Estados ortogonales que permiten la ejecución concurrente de máquinas de estado
Eventos permitiendo la comunicación entre estados ortogonales.
Variables para permitir ‘recordar’ valores.
Acciones que pueden ocurrir más allá de las transiciones, particularmente en los estados.
Actividades (operaciones) que permiten interactuar con el mundo real.

17 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT
Es una herramienta para el desarrollo de diagramas de estado con diferentes tipos de licencia-
miento (gratuita para uso no comercial).
Entre las funcionalidades que incorpora permite verificar el modelo, simularlo y generar código
fuente en lenguaje C, C++ y Java.
Para comenzar a trabajar con esta herramienta el primer paso es instalar el pluggin en Eclipse.
Para esto, dentro de Eclipse, seleccionar Help/Install new software y desde allı́ agregar
como nuevo repositorio http://updates.yakindu.org/sct/releases/.
Hecho esto, es posible agregar a un proyecto un nuevo diagrama de estados
(File/New/Other... - YAKINDU SCT/Statechart Model)

18 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso.


Consideremos un caso simple de uso para analizar la metodologı́a de trabajo con esta herramienta.
Deseamos desarrollar una aplicación que permita, al presionar el pulsador 1 de la EDU-CIAA que
se altere el estado del led 1. Para esto, partiremos de un proyecto base que incluya los drivers para
los periféricos existentes en la placa.

En el crearemos una carpeta para almacenar el diagrama de estados (State Chart).

Luego agregaremos al proyecto un nuevo diagrama de estados.

19 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

20 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso


El nombre del diagrama de estados es significativo en el ámbito del proyecto de diferentes puntos
de vista. Uno de ellos es que el nombre que establezcamos será utilizado como prefijo tipos de
datos y funciones.

21 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

22 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

23 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

24 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

Diseño
El primer paso en el diseño es es definir los estados. En nuestro caso, solo tendremos dos estados:
Led apagado
Led encendido
Los estados pueden tener comportamiento, el cuál está dado por reacciones. Las reacciones no
solo se asocian a estados sino que además pueden estar asociadas a transiciones. La diferencia es
que mientras que una transición está asociada necesariamente a una reacción, un estado puede
tener un comportamiento definido por varias reacciones.
La sintaxis utilizada por Yakindu para la definición de reacciones es:

trigger [guard] / effect

Una reacción puede incluir un trigger que dispara la ejecución de la misma. Este puede ser
una palabra clave o un evento.
Es posible indicar en una reacción un condición (guard), de indicarse es necesario que la
condición sea verdadera al momento de producirse la reacción.
El tercer elemento effect constituye una acción. Puede indicarse una operación o múltiples
separadas por el carácter ‘,’.

25 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Diseño
Una reacción puede ser producida a partir de un evento. Si este es el caso, el evento debe definirse
como tal. Posteriormente podrá ser invocado como una función en el momento que corresponda
desde el código fuente de la aplicación.
Otras alternativas para disparar una reacción son ciertas palabras claves definidas como parte de
los diagramas de estados:
after: dispara una reacción luego de pasado un perı́odo de tiempo
every: dispara una reacción a intervalos regulares de tiempo
always, oncycle: dispara una reacción por cada ciclo de ejecución de la máquina de estados.
entry: dispara la ejecución de una reacción al momento de ingresar a una máquina o estado.
exit: de modo análogo al anterior, dispara una reacción al salir de una máquina o estado.
Las unidades de tiempo reconocidas son s, ms, ns y us.

26 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Diseño
Volviendo a nuestro caso de estudio, al ingresar al estado “Led Apagado” deberı́a apagarse el led,
mientras que deberı́a operarse de modo análogo al ingresar al estado “Led Encendido”.
Las operaciones requeridas para apagar y encender el led deben definirse como operaciones en
Yakindu, siendo necesario agregar su definición en la interfase del diagrama. Por ejemplo:

operation ledOn()
operation ledOff()

Las operaciones son implementadas como funciones, pudiendo tomar argumentos y retornar va-
lores. Los tipos de datos reconocidos son integer, real, boolean, string y void. De esto son
declaraciones de operaciones válidas:

operation getSensor(sensorId: integer):real


operation dacValue(x: integer)

27 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

28 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Eventos
El siguiente paso es definir los eventos que, en este caso particular, producirán las transiciones entre
estados. Al igual que las operaciones estos deben definirse.
Los eventos pueden ser de dos tipos:
Eventos internos: que se producen solo en el ámbito de la máquina de estados.

Eventos externos: son estı́mulos que se producen desde el exterior a la máquina de estados.
Estos, a su vez, pueden ser de dos tipos:

Eventos de entrada (in event): se producen desde el exterior de la máquina de estados.

Eventos de salida (out event): se producen desde la máquina de estados hacia el exterior.

Al igual que las operaciones, los eventos pueden tener valores asociados. Si este es el caso, en su
definición, debe indicarse su tipo. El valor puede ser accedido a través de la función valueof.

in event sensorDisparado: integer

/* Uso en una transición */


sensorDisparado [valueOf(sensorDisparado) == 2]

29 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

30 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Simulación
Una vez definido el evento al que reaccionará nuestra máquina de estados, nuestro modelo ha
sido completado. Entre las posibilidades ofrecidas por Yakindu está la simulación. Para iniciar

esta perspectiva y comenzar la simulación deberemos seleccionar, del menú contextual asociado al
archivo que representa el modelo en el proyecto la opción Run as/Statechart Simulation.

31 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

32 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

33 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

34 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

35 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

36 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

37 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

38 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Generación del código fuente


Habiendo comprobado el correcto funcionamiento de la máquina de estados, el siguiente paso es
generar el código fuente asociado a la misma.

Esto se realiza agregando al proyecto un ‘generador’ de código que forma parte del pluggin de Yakin-
du. Para esto, con la carpeta donde se almacenó el archivo que representa el modelo seleccionada,
debemos seleccionar File/New/Other... - Yakindu SCT/Code Generator Model.

39 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

40 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

41 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

42 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Generación del código fuente


Una vez agregado el nuevo componente al proyecto, se hará visible un archivo donde se indica
targetProject: nombre del proyecto vinculado al generador de código fuente.
targetFolder: carpeta del proyecto donde se alojarán los archivos de código fuente asociados
a la máquina de estado.
libraryTargetFolder: carpeta donde se agregarán archivos con definiciones propios de Ya-
kindu.
A los fines de simplificar la integración con el proyecto en lenguaje C existente, es conveniente
establecer como carpetas de salida src.

Debido a que en esta carpeta habrá por lo menos un header, debe incluirse en el path de búsqueda
de headers en el makefile del proyecto.

Por defecto se generará el código fuente asociado al modelo, sin embargo puede ser necesario en
algunos casos forzar la generación del mismo. Para esto deberemos seleccionar del menú contextual
del archivo asociado al generador de código fuente la opción Generate Code Artifacts.

43 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

44 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

45 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Yakindu SCT: un ejemplo de uso

46 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Integración con la aplicación


Una vez generado el código fuente asociado a la máquina de estado encontraremos 4 archivos que
se han agregado a la carpeta src:
LedOnOff.h y LedOnOff.c: contienen la implementación de la máquina de estado propiamente
dicha.
LedOnOffRequired.h: prototipos de las funciones cuya implementación es requerida para la
construcción de la aplicación. En nuestro caso, los prototipos se corresponden con la declara-
ción de dos operaciones, para encender y apagar el led.
sc types.h: definiciones de tipos de datos requeridos por el código generado.

47 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

sysUtils.c

static uint8_t keyPressed = 0;

void GPIO0_IRQHandler ( void ){


keyPressed = 1;
C h i p _ P I N I N T _ C l e a r I n t S t a t u s ( LPC_GPIO_PIN_INT , PININTCH (0));
}

uint8_t getKeyPressed ( void ){


return keyPressed ;
}

void rstKeyPressed ( void ){


keyPressed = 0;
}

void ledOn ( uint8_t ledNro ){


C h i p _ G P I O _ S e t P i n O u t H i g h ( LPC_GPIO_PORT , leds [ ledNro ]. gpioPort ,
leds [ ledNro ]. gpioPin );
}

void ledOff ( uint8_t ledNro ){


Chip_GPIO_SetPinOutLow (
LPC_GPIO_PORT , leds [ ledNro ]. gpioPort , leds [ ledNro ]. gpioPin );
}

48 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

main.c

# include < stdint .h > int main ( void ){


# include " sysUtils . h "
# include " chip . h " LedOnOff estados ;
# include " sc_types . h " sysInit ();
# include " LedOnOff . h " ledOnOff_init (& estados );
ledOnOff_enter (& estados );
void l e d O n O f f I f a c e _ l e d O n (
const LedOnOff * handle ) while (1){
{ __WFI ();
ledOn (0); if ( getKeyPressed () == 1){
} l e d O n O f f I f a c e _ r a i s e _ k e y P r e s s (& estados );
rstKeyPressed ();
void l e d O n O f f I f a c e _ l e d O f f ( }
const LedOnOff * handle ) le dOn Off_ run Cyc le (& estados );
{ }
ledOff (0); return 0;
} }

49 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Ejemplo 2.0
Consideremos ahora la siguiente modificación: en vez de alterarse el estado del led al presionar el
botón, deseamos que parpadee a intervalos regulares de 250 ms (esté encendido 250 ms y apagado
durante el mismo tiempo).

Esta modificación requiere:


Mantener los estados (ledEncendido y ledApagado)
Mantener las operaciones (ledOn y ledOff)
Reemplazar el evento keyPres por la palabra clave after.

50 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Ejemplo 2.0

51 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

sysUtils.c

void sysInit ( void ) void ledOn ( uint8_t ledNro ){


{ C h i p _ G P I O _ S e t P i n O u t H i g h ( LPC_GPIO_PORT ,
int i ; leds [ ledNro ]. gpioPort ,
C h i p _ S e t u p X t a l C l o c k i n g (); leds [ ledNro ]. gpioPin );
S y s t e m C o r e C l o c k U p d a t e (); }

fpuInit (); void ledOff ( uint8_t ledNro ){


Chip_ GPIO_Init ( LPC_GPIO_PORT ); C h i p _ G P I O _ S e t P i n O u t L o w ( LPC_GPIO_PORT ,
leds [ ledNro ]. gpioPort ,
for ( i = 0; leds [ ledNro ]. gpioPin );
i < sizeof ( leds )/ sizeof ( digitalIO ); }
i ++)
{ static uint8_t sysTickEv = 0;
C h i p _ S C U _ P i nM u xS e t ( leds [ i ]. hwPort ,
leds [ i ]. hwPin , leds [ i ]. modo ); void SysTick_Handler ( void ){
C h i p _ G P I O _ S e t P i n D I R O u t p u t ( LPC_GPIO_PORT , sysTickEv = 1;
leds [ i ]. gpioPort , leds [ i ]. gpioPin ); }
C h i p _ G P I O _ S e t P i n O u t L o w ( LPC_GPIO_PORT ,
leds [ i ]. gpioPort , leds [ i ]. gpioPin ); uint8_t getSysTickEv ( void ){
} return sysTickEv ;
SysTi ck_Config ( SystemCoreClock / 1000); }
}
void rstSysTickEv ( void ){
sysTickEv = 0;
}

52 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

main.c (1/2)

# include < stdint .h >


# include " sysUtils . h "
# include " chip . h "
# include " sc_types . h "
# include " LedOnOff . h "
# include " timerTicks . h "

# define NOF_TIMERS \
( sizeof ( L ed O nO f fT im e Ev e nt s )/ sizeof ( sc_boolean ))

static TimerTicks ticks [ NOF_TIMERS ];

void led OnO ff_ setT ime r ( LedOnOff * handle ,


const sc_eventid evid , const sc_integer time_ms ,
const sc_boolean periodic ){
SetNewTimerTick ( ticks , NOF_TIMERS , evid , time_ms , periodic );
}

void l e d O n O f f _u n s e t T i m e r ( LedOnOff * handle ,


const sc_eventid evid ){
UnsetTimerTick ( ticks , NOF_TIMERS , evid );
}

void l e d O n O f f If a c e _ l e d O n (
const LedOnOff * handle ){
ledOn (0);
}

53 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

main.c (2/2)

void l e d O n O f f I f a c e _ l e d O f f (
const LedOnOff * handle ){
ledOff (0);
}

int main ( void )


{
int i ;
LedOnOff estados ;
sysInit ();
ledOnOff_init (& estados );
ledOnOff_enter (& estados );

while (1){
__WFI ();
if ( getSysTickEv ()){
rstSysTickEv ();
UpdateTimers ( ticks , NOF_TIMERS );
for ( i = 0; i < NOF_TIMERS ; i ++){
if ( IsPendEvent ( ticks , NOF_TIMERS , ticks [ i ]. evid )){
l e d O n O f f _ r a i s e T i m e E v e n t (& estados , ticks [ i ]. evid );
MarkAsAttEvent ( ticks , NOF_TIMERS , ticks [ i ]. evid );
}
}
}
le dOn Off_ run Cy c le (& estados );
}
return 0;
}

54 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Ejemplo 3.0
El objetivo ahora es que el led0 (color azul rgb) parpadee 4 veces, a intervalos de 250 ms. Al
presionar una tecla, parpadee 4 veces el led 3 a intervalos de 250 ms. El ciclo debe volver a
comenzar con el led0 al presionar una tecla.

Si bien es posible implementar la solución utilizando estados de la misma jerarquı́a, una solución más
comprensible podrı́a lograrse utilizando estados compuestos. Los estados compuestos son estados
que contienen diagramas de estados. Como tales, tendrán un punto de entrada y pueden tener un
estado final.

El control de la cantidad de veces que se enciende un led puede realizarse utilizando una variable
interna y reacciones con condiciones asociadas.

55 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Ejemplo 3.0

56 / 57 Máquinas de estado y diagramas de estado


Máquinas de estado Diagramas de estado

Fin Módulo 11

57 / 57 Máquinas de estado y diagramas de estado

You might also like