gv_fsm 0.2.10 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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