Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

Re: [AVR-Chat] State Table Compiler

2009-09-16 by Ned Konz

On Sep 16, 2009, at 9:47 AM, Ned Konz wrote:

>
> On Sep 15, 2009, at 6:42 PM, Chuck Hackett wrote:
>
>>> From: Ned Konz
>>> ....
>>> I prefer the Quantum Platform package; it supports hierarchical  
>>> state
>>> machines, has an AVR port available, and skips the separate
>>> representation of the state machine (i.e. it is not table based). So
>>> its RAM footprint is very small.
>>>
>>> http://state-machine.com
>>> ....
>>
>> In my current need, the SMs are table based and (possibly) changed
>> at run
>> time.
>>
>> I've noted it for future reference ... thanks.
>
> Do you need:
>
>  - hierarchical states?
>
>  - Actions on transitions?
>
> - Guards on transitions? (of course, this can be put in external code)
>
>  - Arbitrary code executed for actions, or could you call pre-
> existing functions with arguments of your specification?
>
>  - "do" actions (periodically, while in a state)? Or could these be a
> response to a timer event?
>
>
> You might look at: Micah Martin's Statemachine framework for Ruby http://statemachine.rubyforge.org
> and at http://blog.8thlight.com/articles/2006/11/17/understanding-statemachines-part-1-states-and-transitions
>
> This can be installed (once you have Ruby installed) by just saying:
>
> gem install statemachine
>
> This will let you skip the yacc/lex stuff, and just use Ruby as the
> interpreter and compiler.
>
> The package provides:
>
>   - hierarchical state machine definition
>   - entry and exit actions for states
>   - default action for states
>   - states and events are just names
>   - actions are just names
>
> The attached is an example of generation (in this case, it makes C
> structure definitions, but it could easily make any binary format you
> want).


Of course, the attached file got removed.

Here is the source:

require 'rubygems'
require 'statemachine'

$vending_machine = Statemachine.build do
   trans :waiting, :dollar, :paid, :indicatePaid
   trans :paid, :selection, :waiting, :vend
   trans :waiting, :selection, :waiting
   trans :paid, :dollar, :paid
end

$stateIds = { :root => 1, :waiting => 2, :paid => 3 }
$stateIds.default = 0
$eventIds = { :dollar => 1, :selection => 2 }
$eventIds.default = 0
$actionIds = { :indicatePaid => 1, :vend => 2 }
$actionIds.default = 0


module Statemachine
   class Transition
     def dumpCCode
       puts "\t\t// transition on event #{@event} from #{@origin_id}  
to #{@destination_id} (action=#{@action})"
       puts "\t\t{ .event = #{$eventIds[@event]}, .destination_id =  
#{$stateIds[@destination_id]}, .action = #{$actionIds[@action]} },"
     end
   end

   class State
     def stateid
       @id
     end

     def dumpCCode
       puts "\t// state #{@id}, super #{@superstate.stateid}"
       puts "\t{ .id = #{$stateIds[@id]}, .superstate =  
#{$stateIds[@superstate.stateid]},"
       puts "\t.entry_action =  
#{$actionIds[@entry_action]}, .exit_action #{$actionIds[@exit_action]},"
       puts "\t// transitions"
       puts "\t.transitions = {"
       # pp @transitions
       @transitions.each_value { |tr| tr.dumpCCode }
       puts "\t}},"
     end
   end

   class Statemachine
     def dumpCCode
       puts "struct state states[] = {"
       @states.each_value { |st| st.dumpCCode }
       puts "}"
     end
   end
end

$vending_machine.dumpCCode

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.