gv_fsm 0.2.10 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf5e9e3cf0f82f27179188c0a3e994b2114278d723f4df2530b59a5ee87bdb72
4
- data.tar.gz: 6dda52c8b001d8043e888d139cca35939fb5682acb93c00f1e2a9a7373343b3b
3
+ metadata.gz: 784139036e73fde8dd29fd8cc87228b2829241cdea0a8398cdf0cbc31d4ab385
4
+ data.tar.gz: 4d2ec2d3506a652e9db040fc4a58eb669052813837e310a3349393763a7ba207
5
5
  SHA512:
6
- metadata.gz: 3fe7b3e14362c3a35692785df7fc35b1756575499b94de2c2441828096c5d479b15bfa5736ede6d7691908f646edb7f625b385b877a53d7423a27fab41adbf6b
7
- data.tar.gz: d99ed400cdc9ac9f13831952059e9b9ccd352bfd8b55f5fdc570b1667070cb6c1181ae4942e69c732eb6159639928e46f57debd3e05db969eaa99b9cc0e91a75
6
+ metadata.gz: b89e1ee3e0aadde8e3b36085759696ccb27701b02cd895f93b1e0007f238d7415ae93f5f19e47fad99b7002c2df28ff496044a5c805cf9d6c36f3679b96acd52
7
+ data.tar.gz: aa06c8df94a679aaeae10eb635a10adceacfc3e3738ed03481d75941c106da4ef91ede9a59f042f8430a62f6b4fa3acfd7d2187dc3d33fde199c11ac797c4425
data/bin/gv_fsm CHANGED
@@ -48,6 +48,10 @@ op = OptionParser.new do |parser|
48
48
  sm.syslog = false
49
49
  end
50
50
 
51
+ parser.on("-k", "--sigint STATE", "Install SIGINT handler that points to STATE") do |state|
52
+ sm.sigint = state
53
+ end
54
+
51
55
  parser.on("-h", "--help", "Prints this help") do
52
56
  puts parser
53
57
  exit
@@ -73,6 +77,11 @@ unless sm.parse(ARGV[0]) then
73
77
  exit 3
74
78
  end
75
79
 
80
+ if sm.ino && sm.sigint then
81
+ STDERR.puts "ERROR: signal handler is not supported on Arduino!\n\n"
82
+ exit 4
83
+ end
84
+
76
85
  puts "Parsed #{sm.dotfile}"
77
86
  top = sm.topology
78
87
  puts "Graph topology:"
@@ -87,11 +96,18 @@ end
87
96
  puts "Generating C functions for states: #{sm.states_list.join(", ")}."
88
97
  puts " for transition: #{sm.transition_functions_list.join(", ")}."
89
98
 
99
+ if (sm.sigint) then
100
+ puts "Installed signal handler for SIGINT in state #{top[:sources][0]}:\n stable states have emergency transition to state #{sm.sigint}"
101
+ unless top[:sinks].include? sm.sigint then
102
+ puts "WARNING: the state #{sm.sigint} is not a source, please check topology"
103
+ end
104
+ end
90
105
 
91
106
  if options[:header] then
92
107
  name = sm.generate_h
93
108
  puts "Generated header #{name}"
94
109
  end
110
+
95
111
  if options[:source] then
96
112
  name = sm.generate_c
97
113
  puts "Generated source #{name}"
data/lib/gv_fsm.rb CHANGED
@@ -10,7 +10,7 @@ require File.expand_path("../version.rb", __FILE__)
10
10
  module GV_FSM
11
11
  class FSM
12
12
  attr_reader :states, :transitions, :dotfile, :prefix, :error
13
- attr_accessor :project_name, :description, :cname, :syslog, :ino
13
+ attr_accessor :project_name, :description, :cname, :syslog, :ino, :sigint
14
14
  include GV_FSM::Templates
15
15
 
16
16
  def initialize(filename = nil)
@@ -20,6 +20,7 @@ module GV_FSM
20
20
  @error = nil
21
21
  @matrix = nil
22
22
  @nodemap = {}
23
+ @sigint = nil
23
24
  parse(filename) if filename
24
25
  end
25
26
 
@@ -85,6 +86,10 @@ module GV_FSM
85
86
  @error = "Parsing error"
86
87
  return nil
87
88
  end
89
+ if (self.sigint && !states.find {|s| s[:id] == self.sigint}) then
90
+ @error = "Missing SIGINT state #{self.sigint}"
91
+ return nil
92
+ end
88
93
  return graph
89
94
  end
90
95
 
data/lib/templates.rb CHANGED
@@ -49,7 +49,7 @@ module GV_FSM
49
49
  } <%= @prefix %>state_t;
50
50
 
51
51
  // State human-readable names
52
- extern const char *state_names[];
52
+ extern const char *<%= @prefix %>state_names[];
53
53
 
54
54
  <% if transition_functions_list.count > 0 then %>
55
55
  // State function and state transition prototypes
@@ -110,12 +110,25 @@ module GV_FSM
110
110
  <% end %>
111
111
  #include "<%= File::basename(@cname) %>.h"
112
112
 
113
+ <% if sigint then %>// Install signal handler:
114
+ // SIGINT requests a transition to state <%= self.sigint %>
115
+ #include <signal.h>
116
+ static int _exit_request = 0;
117
+ static void signal_handler(int signal) {
118
+ if (signal == SIGINT) {
119
+ _exit_request = 1;<% if log == :syslog then %>
120
+ syslog(LOG_WARNING, "[FSM] SIGINT transition to <%= sigint %>");<% elsif log == :ino then %>
121
+ Serial.println("[FSM] SIGINT transition to <%= sigint %>");<% end %>
122
+ }
123
+ }
124
+
125
+ <% end %>
113
126
  <% placeholder = "Your Code Here" %>
114
127
  // SEARCH FOR <%= placeholder %> FOR CODE INSERTION POINTS!
115
128
 
116
129
  // GLOBALS
117
130
  // State human-readable names
118
- const char *state_names[] = {<%= states_list.map {|sn| '"'+sn+'"'}.join(", ") %>};
131
+ const char *<%= @prefix %>state_names[] = {<%= states_list.map {|sn| '"'+sn+'"'}.join(", ") %>};
119
132
 
120
133
  // List of state functions
121
134
  <% fw = state_functions_list.max {|a, b| a.length <=> b.length}.length %>
@@ -153,6 +166,7 @@ module GV_FSM
153
166
  // |_| \\__,_|_| |_|\\___|\\__|_|\\___/|_| |_|___/
154
167
  //
155
168
  <% dest = destinations.dup %>
169
+ <% topo = self.topology %>
156
170
  <% @states.each do |s| %>
157
171
  <% stable = true if dest[s[:id]].include? s[:id] %>
158
172
  <% dest[s[:id]].map! {|n| (@prefix+"STATE_"+n).upcase} %>
@@ -161,9 +175,13 @@ module GV_FSM
161
175
  end %>
162
176
  // Function to be executed in state <%= s[:id] %>
163
177
  // valid return states: <%= dest[s[:id]].join(", ") %>
178
+ <% if sigint && stable && topo[:sources][0] != s[:id] then %>
179
+ // SIGINT triggers an emergency transition to <%= self.sigint %>
180
+ <% end %>
164
181
  <%= @prefix %>state_t <%= s[:function] %>(<%= @prefix %>state_data_t *data) {
165
182
  <%= @prefix %>state_t next_state = <%= dest[s[:id]].first %>;
166
-
183
+ <% if sigint && topo[:sources][0] == s[:id] then %>signal(SIGINT, signal_handler);
184
+ <% end %>
167
185
  <% if log == :syslog then %>
168
186
  syslog(LOG_INFO, "[FSM] In state <%= s[:id] %>");
169
187
  <% elsif log == :ino then %>
@@ -178,14 +196,18 @@ module GV_FSM
178
196
  break;
179
197
  default:
180
198
  <% if log == :syslog then %>
181
- syslog(LOG_WARNING, "[FSM] Cannot pass from <%= s[:id] %> to %s, remaining in this state", state_names[next_state]);
199
+ syslog(LOG_WARNING, "[FSM] Cannot pass from <%= s[:id] %> to %s, remaining in this state", <%= @prefix %>state_names[next_state]);
182
200
  <% elsif log == :ino then %>
183
201
  Serial.print("[FSM] Cannot pass from <%= s[:id] %> to ");
184
- Serial.print(state_names[next_state]);
202
+ Serial.print(<%= @prefix %>state_names[next_state]);
185
203
  Serial.println(", remaining in this state");
186
204
  <% end %>
187
205
  next_state = <%= @prefix.upcase %>NO_CHANGE;
188
206
  }
207
+ <% if sigint && stable && topo[:sources][0] != s[:id] then %>
208
+ // SIGINT transition override
209
+ if (_exit_request) next_state = <%= (@prefix+"STATE_"+self.sigint ).upcase %>;
210
+ <% end %>
189
211
  return next_state;
190
212
  }
191
213
 
@@ -282,4 +304,4 @@ module GV_FSM
282
304
  <% end %>
283
305
  EOC
284
306
  end
285
- end
307
+ end
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module GV_FSM
2
- VERSION = "0.2.10"
2
+ VERSION = "0.3.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gv_fsm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.10
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paolo Bosetti