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 +4 -4
- data/bin/gv_fsm +16 -0
- data/lib/gv_fsm.rb +6 -1
- data/lib/templates.rb +28 -6
- data/lib/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 784139036e73fde8dd29fd8cc87228b2829241cdea0a8398cdf0cbc31d4ab385
|
4
|
+
data.tar.gz: 4d2ec2d3506a652e9db040fc4a58eb669052813837e310a3349393763a7ba207
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
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