<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog do Sergio Prado &#187; maquina de estados</title>
	<atom:link href="http://sergioprado.org/tag/maquina-de-estados/feed/" rel="self" type="application/rss+xml" />
	<link>http://sergioprado.org</link>
	<description>Sistemas embarcados, Linux e tecnologia</description>
	<lastBuildDate>Thu, 02 Feb 2012 19:56:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Máquina de Estados em C</title>
		<link>http://sergioprado.org/2010/02/06/maquina-de-estados-em-c/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=maquina-de-estados-em-c</link>
		<comments>http://sergioprado.org/2010/02/06/maquina-de-estados-em-c/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 03:02:01 +0000</pubDate>
		<dc:creator>Sergio Prado</dc:creator>
				<category><![CDATA[Linguagem C]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[maquina de estados]]></category>

		<guid isPermaLink="false">http://www.embarcados.com.br/blog/?p=115</guid>
		<description><![CDATA[Neste post escrevo sobre a implementação de máquina de estados em C, com dois exemplos práticos utilizando o modelo switch/case e o modelo de ponteiro para função.
Sem posts relacionados.]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Desenvolvedor de software é um ser muito ansioso. Quer logo colocar a mão na massa. E depois de 2.000 linhas de código ele resolve começar os testes. O código nem compila. E quando ele se prepara para corrigir o problema, percebe que o código está um caos total. Funções com mais de 200 linhas e mais de 5 if’s aninhados. O que parecia ser fácil no começo (e poderia ter sido) já não é mais. Tudo porque ele não tinha um plano. Nunca comece nada sem um plano, principalmente quando se trata de desenvolvimento de software. E uma boa estratégica é o uso de <a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29" target="_blank">design patterns.</a></span></span></p>
<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Design patterns, ou padrões de projeto, são soluções para problemas normalmente encontrados em projetos de software. São independentes de linguagem, e oferecem uma descrição ou template de como resolver determinado problema. Um design pattern muito conhecido e utilizado no desenvolvimento de software para sistemas embarcados é a Máquina De Estados Finita, ou <a href="http://en.wikipedia.org/wiki/Finite_state_machine" target="_blank">Finite State Machine (FSM)</a>, a qual chamaremos aqui apenas de máquina de estados.</span></span><!--[endif]--></p>
<div>
	<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Mas qual o problema que este design pattern pretende resolver?</span></span></p>
	<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Muitos dos dispositivos usados em sistemas embarcados, principalmente os de automação e controle, são dispositivos passivos. Respondem a determinadas ações do ambiente. E a saída gerada por estas ações são dependentes de seu estado atual. É exatamente aí que entra a implementação deste design pattern: qualquer dispositivo, físico ou conceitual, que possue um conjunto finito de estados e aceita um finito numero de entradas, pode produzir um finito numero de diferentes saidas. Este dispositivo deve ter uma memória que possa armazenar a sequencia de entradas recebidas, de forma que a saida seja dependente destas entradas.</span></span></p>
	<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">OK, está um pouco confuso, não é? Vamos então tentar analisar um caso prático.</span></span></p></div>
<div>
	<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">A entrada de um típico sistema de automação de estacionamentos é composta pelos seguintes elementos: um emissor de tickets, uma cancela e um ou mais loops de detecção de veículos. O loop é um sensor de chapa metálica localizado no chão e utilizado para identificar o veiculo. Para o nosso exemplo existem dois loops, um em frente ao emissor de tickets (loop A) e outro abaixo da cancela (loop B).</span></span></p></div>
<div>
	<p style="text-align: justify;"><!--[if !supportEmptyParas]--><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">As seguintes ações são realizadas na entrada de um veículo:</span></span></p>
	<ol>
		<li style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">O usuário posiciona o veículo em frente ao emissor de tickets, o loop A será acionado e uma mensagem “Pressione o botão” é emitida. </span></span></li>
		<li style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">O usuário pressiona o botão para emitir o ticket, o sistema realiza a emissão e levanta a cancela.</span></span></li>
		<li style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">O usuario passa pela cancela (loop B) e entra no estacionamento. O sistema aguarda e abaixa a cancela.</span></span></li></ol></div>
<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Pelas ações listadas acima, podemos identificar basicamente os estados abaixo, na ordem em que são executados:<br />
	</span></span></p>
<ol>
	<li style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Aguardando veículo no loop A.</span></span></li>
	<li style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Aguardando usuário pressionar o botão para emitir ticket.</span></span></li>
	<li style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Aguardando veiculo sair do loop A.</span></span></li>
	<li style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Aguardando veiculo passar pelo loop B.<br />
		</span></span></li></ol>
<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">O importante aqui é perceber que, para qualquer um dos estados acima, dependendo da entrada, a saida será diferente. Por exemplo, se você esta no estado 2 e recebe como entrada o botão pressionado você vai para o estado 3. Porém, se ao invés do botão pressionado você receber como entrada a saida de veiculo do loop A (usuário deu ré e desistiu de estacionar), você deve voltar para o estado 1.<br />
	<br />
	Este é um exemplo simples de aplicação onde cabe perfeitamente a implementação de uma máquina de estados. Além desta, existem muitas outras aplicações, como por exemplo interpretadores de comando, processadores de linguagem, tratamento de protocolos de comunicação, etc.<br />
	<br />
	Agora que conhecemos um pouco da teoria, vamos à prática.<br />
	</span></span></p>
<p style="text-align: justify;"><span style="font-size: 16px;"><strong><span style="font-family: verdana,geneva,sans-serif;">Implementação</span></strong></span></p>
<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Um problema que resolvo frequentemente com máquina de estados são rotinas de tratamento de protocolos de comunicação.<br />
	<br />
	No nosso exemplo, o protocolo de comunicação tem o seguinte formato:</span></span></p>
<p style="text-align: center;"><span style="font-family: courier new,courier,monospace;"><span style="font-size: 14px;"><em>|STX|QTD_DADOS|DADOS|CHK|ETX|</em></span></span></p>
<p style="text-align: justify;"><span style="font-family: courier new,courier,monospace;"><span style="font-size: 14px;">STX       (1 Byte)  -&gt; Inicio da transmissão (0x02)<br />
	QTD_DADOS (1 Byte)  -&gt; Quantidade de dados<br />
	DADOS     (N Bytes) -&gt; Dados<br />
	CHK       (1 Byte)  -&gt; Checksum da transmissão<br />
	ETX       (1 Byte)  -&gt; Fim da transmissão (0x03)</span><br />
	</span></p>
<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Vamos implementar aqui dois modelos diferentes, um com switch/case e outro com ponteiro para função.</span></span></p>
<p style="text-align: justify;"><span style="font-size: 16px;"><strong><span style="font-family: verdana,geneva,sans-serif;">Implementação 1: Switch/case</span></strong></span></p>
<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Esta implementação é simples e composta de apenas uma função, listada abaixo:</span></span></p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* possiveis estados */</span>
<span style="color: #993333;">typedef</span> <span style="color: #000000; font-weight: bold;">enum</span> <span style="color: #009900;">&#123;</span>
    ST_STX <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> ST_QTD<span style="color: #339933;">,</span> ST_DATA<span style="color: #339933;">,</span> ST_CHK<span style="color: #339933;">,</span> ST_ETX
<span style="color: #009900;">&#125;</span> States<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* maquina de estados */</span>
<span style="color: #993333;">void</span> handleRx<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>data<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> qtd<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">static</span> States state <span style="color: #339933;">=</span> ST_STX<span style="color: #339933;">;</span>
    <span style="color: #993333;">static</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> buffer<span style="color: #009900;">&#91;</span>MAX_BUFFER<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">static</span> <span style="color: #993333;">int</span> indBuffer <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> qtdBuffer <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">static</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> chkBuffer <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> qtd<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>state<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
            <span style="color: #b1b100;">case</span> ST_STX<span style="color: #339933;">:</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> STX<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    indBuffer <span style="color: #339933;">=</span> qtdBuffer <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
                    chkBuffer <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
                    state <span style="color: #339933;">=</span> ST_QTD<span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #b1b100;">case</span> ST_QTD<span style="color: #339933;">:</span>
                qtdBuffer <span style="color: #339933;">=</span> data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                state <span style="color: #339933;">=</span> ST_DATA<span style="color: #339933;">;</span>
                <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #b1b100;">case</span> ST_DATA<span style="color: #339933;">:</span>
                buffer<span style="color: #009900;">&#91;</span>indBuffer<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                chkBuffer <span style="color: #339933;">^=</span> data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">--</span>qtdBuffer <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    state <span style="color: #339933;">=</span> ST_CHK<span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #b1b100;">case</span> ST_CHK<span style="color: #339933;">:</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> chkBuffer<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    state <span style="color: #339933;">=</span> ST_ETX<span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
                    state <span style="color: #339933;">=</span> ST_STX<span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #b1b100;">case</span> ST_ETX<span style="color: #339933;">:</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> ETX<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    handlePackage<span style="color: #009900;">&#40;</span>buffer<span style="color: #339933;">,</span>
                        indBuffer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                state <span style="color: #339933;">=</span> ST_STX<span style="color: #339933;">;</span>
                <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>



<p><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">O uso da máquina de estados é simples. Basta chamar a função handleRx() para cada stream recebido do buffer de comunicação. Veja que ela possui algumas variáveis static para que seja possivel armazenar seu estado atual. O código-fonte completo desta implementação pode ser baixado <a href="http://www.sergioprado.org/wp-content/plugins/download-monitor/download.php?id=8" target="_blank">aqui</a>.</span></span></p>
<div>
	<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">A principal deficiência desta solução é que a função pode ficar grande e complexa demais dependendo da quantidade de estados. A melhor forma de resolver este problema é implementar usando ponteiros para função.</span></span></p></div>
<p style="text-align: justify;"><strong><span style="font-size: 16px;"><span style="font-family: verdana,geneva,sans-serif;">Implementação 2: Ponteiros de função<br />
	</span></span></strong></p>
<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Nesta forma de implementação da máquina de estados, cada ação é implementada através de uma função. Veja um trecho da implementação abaixo:</span></span></p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* possiveis estados */</span>
<span style="color: #993333;">typedef</span> <span style="color: #000000; font-weight: bold;">enum</span> <span style="color: #009900;">&#123;</span>
    ST_STX <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> ST_QTD<span style="color: #339933;">,</span> ST_DATA<span style="color: #339933;">,</span> ST_CHK<span style="color: #339933;">,</span> ST_ETX
<span style="color: #009900;">&#125;</span> States<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">struct</span> StateMachine <span style="color: #009900;">&#123;</span>
    States state<span style="color: #339933;">;</span>
    <span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> buffer<span style="color: #009900;">&#91;</span>MAX_BUFFER<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> chkBuffer<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> indBuffer<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> qtdBuffer<span style="color: #339933;">;</span>
    Action action<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> sm<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">void</span> stSTX<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> data<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>data <span style="color: #339933;">==</span> STX<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        sm.<span style="color: #202020;">indBuffer</span> <span style="color: #339933;">=</span> sm.<span style="color: #202020;">qtdBuffer</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
        sm.<span style="color: #202020;">chkBuffer</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
        sm.<span style="color: #202020;">state</span> <span style="color: #339933;">=</span> ST_QTD<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> stQtd<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> data<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    sm.<span style="color: #202020;">qtdBuffer</span> <span style="color: #339933;">=</span> data<span style="color: #339933;">;</span>
    sm.<span style="color: #202020;">state</span> <span style="color: #339933;">=</span> ST_DATA<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> stData<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> data<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    sm.<span style="color: #202020;">buffer</span><span style="color: #009900;">&#91;</span>sm.<span style="color: #202020;">indBuffer</span><span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> data<span style="color: #339933;">;</span>
    sm.<span style="color: #202020;">chkBuffer</span> <span style="color: #339933;">^=</span> data<span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">--</span>sm.<span style="color: #202020;">qtdBuffer</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        sm.<span style="color: #202020;">state</span> <span style="color: #339933;">=</span> ST_CHK<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> stChk<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> data<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>data <span style="color: #339933;">==</span> sm.<span style="color: #202020;">chkBuffer</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        sm.<span style="color: #202020;">state</span> <span style="color: #339933;">=</span> ST_ETX<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        sm.<span style="color: #202020;">state</span> <span style="color: #339933;">=</span> ST_STX<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> stETX<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> data<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>data <span style="color: #339933;">==</span> ETX<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        handlePackage<span style="color: #009900;">&#40;</span>sm.<span style="color: #202020;">buffer</span><span style="color: #339933;">,</span> sm.<span style="color: #202020;">indBuffer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    sm.<span style="color: #202020;">state</span> <span style="color: #339933;">=</span> ST_STX<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> handleRx<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>data<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> qtd<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> qtd<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
        sm.<span style="color: #202020;">action</span><span style="color: #009900;">&#91;</span>sm.<span style="color: #202020;">state</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>



<p><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">A forma de usar a máquina de estados continua a mesma. Basta chamar a função handleRx() para cada stream recebido do buffer de comunicação. Mas veja que a função diminuiu para apenas 2 linhas! O estado atual da máquina de estados fica armazenado na estrutura StateMachine. E cada trecho de código dentro de um case, no exemplo anterior, se transformou em uma função neste exemplo. O código ficou muito mais modular e de fácil manutenção. Os fontes desta implementação também estão disponíveis <a href="http://www.sergioprado.org/wp-content/plugins/download-monitor/download.php?id=8" target="_blank">aqui</a>.</span></span></p>
<div>
	<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Espero que estes dois exemplos tenham ajudado vocês a entender o mecanismo de implementação de uma máquina de estados e como esse design pattern pode ser útil no nosso dia-a-dia. Se vocês tiverem alguma outra sugestão de implementação de máquinas de estado, deixem seus comentários.</span></span></p></div>
<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Um abraço a todos,</span></span></p>
<p style="text-align: justify;"><span style="font-size: 14px;"><span style="font-family: verdana,geneva,sans-serif;">Sergio Prado</span></span></p><div class="shr-publisher-115"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><p>Sem posts relacionados.</p>]]></content:encoded>
			<wfw:commentRss>http://sergioprado.org/2010/02/06/maquina-de-estados-em-c/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

