Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ardupilot
GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Tools/scripts/decode_watchdog.py
9383 views
1
#!/usr/bin/env python3
2
3
'''
4
decode an watchdog message
5
6
/Tools/scripts/decode_watchdog.py "WDOG, 2641424, -3, 0, 0, 0, 0, 0, 0, 122, 3, 0, 181, 4196355, 135203219, SPI1"
7
8
AP_FLAKE8_CLEAN
9
'''
10
11
import re
12
import sys
13
import optparse
14
from collections import OrderedDict
15
16
import decode_ICSR
17
18
19
class DecodeWatchDog(object):
20
21
class Component(object):
22
def __init__(self, value):
23
self.value = value
24
25
def prefix(self):
26
m = re.match(".*Component([A-Z]+)", str(type(self)))
27
return m.group(1)
28
29
def decode(self):
30
return "?????"
31
32
def string_value(self):
33
return str(self.value)
34
35
def print_decoded(self):
36
print("%5s %25s: %12s: %s" % (
37
self.prefix(),
38
self.expansion(),
39
self.string_value(),
40
self.decode()
41
))
42
43
class ComponentT(Component):
44
45
def expansion(self):
46
return "Scheduler Task"
47
48
def decode(self):
49
if int(self.value) == -3:
50
return "Waiting for sample"
51
if int(self.value) == -1:
52
return "Pre-loop"
53
if int(self.value) == -2:
54
return "Fast loop"
55
return self.value
56
57
class ComponentSL(Component):
58
59
def expansion(self):
60
return "Semaphore Line"
61
62
def decode(self):
63
if int(self.value) == 0:
64
return "Not waiting on semaphore"
65
return self.value
66
67
class ComponentFL(Component):
68
def expansion(self):
69
return "Fault Line"
70
71
class ComponentFT(Component):
72
73
def expansion(self):
74
return "Fault Type"
75
76
def decode(self):
77
x = int(self.value)
78
# this list taken from AP_HAL_ChibiOS/system.cpp
79
fault_types = {
80
1: "Reset",
81
2: "NMI",
82
3: "HardFault",
83
4: "MemManage",
84
5: "BusFault",
85
6: "UsageFault",
86
}
87
if x in fault_types:
88
return fault_types[x]
89
return super(DecodeWatchDog.ComponentFT, self).decode()
90
91
class ComponentFA(Component):
92
93
def expansion(self):
94
return "Fault Address"
95
96
def string_value(self):
97
return hex(int(self.value, 16))
98
99
class ComponentFTP(Component):
100
101
def expansion(self):
102
return "Fault Thread Priority"
103
104
class ComponentFLR(Component):
105
106
def expansion(self):
107
return "Fault Long Return Address" # ?? FIXME: is this really what LR stands for?
108
109
def string_value(self):
110
return "0x" + self.value
111
112
class ComponentFICSR(Component):
113
114
def expansion(self):
115
return "Fault ICS Register" # ?? FIXME: expand further
116
117
def string_value(self):
118
return hex(int(self.value, 16))
119
120
def decode(self):
121
return "[Below]"
122
123
def print_decoded(self):
124
super(DecodeWatchDog.ComponentFICSR, self).print_decoded()
125
decoder = decode_ICSR.DecodeICSR()
126
text = decoder.string(int(self.value))
127
sys.stdout.write(re.sub("^", " ", text, flags=re.M))
128
129
class ComponentMM(Component):
130
131
def expansion(self):
132
return "MAVLink Message"
133
134
def decode(self):
135
if int(self.value) == 0:
136
return "[None]"
137
return super(DecodeWatchDog.ComponentMM, self).decode()
138
139
class ComponentMC(Component):
140
141
def expansion(self):
142
return "MAVLink Command"
143
144
def decode(self):
145
if int(self.value) == 0:
146
return "[None]"
147
return super(DecodeWatchDog.ComponentMC, self).decode()
148
149
class ComponentIE(Component):
150
151
def expansion(self):
152
return "Internal Error Mask"
153
154
class ComponentIEHex(ComponentIE):
155
156
def expansion(self):
157
return "Internal Error Mask"
158
159
def string_value(self):
160
return hex(int(self.value, 16))
161
162
class ComponentIEC(Component):
163
164
def expansion(self):
165
return "Internal Error Count"
166
167
def decode(self):
168
return self.value
169
170
class ComponentIEL(Component):
171
172
def expansion(self):
173
return "Internal Error Line"
174
175
def decode(self):
176
return self.value
177
178
class ComponentTN(Component):
179
180
def expansion(self):
181
return "Thread name"
182
183
def __init__(self):
184
self.components = OrderedDict()
185
self.components["T"] = DecodeWatchDog.ComponentT
186
self.components["SL"] = DecodeWatchDog.ComponentSL
187
self.components["FL"] = DecodeWatchDog.ComponentFL
188
self.components["FT"] = DecodeWatchDog.ComponentFT
189
self.components["FA"] = DecodeWatchDog.ComponentFA
190
self.components["FTP"] = DecodeWatchDog.ComponentFTP
191
self.components["FLR"] = DecodeWatchDog.ComponentFLR
192
self.components["FICSR"] = DecodeWatchDog.ComponentFICSR
193
self.components["MM"] = DecodeWatchDog.ComponentMM
194
self.components["MC"] = DecodeWatchDog.ComponentMC
195
self.components["IE"] = DecodeWatchDog.ComponentIEHex
196
self.components["IEC"] = DecodeWatchDog.ComponentIEC
197
self.components["TN"] = DecodeWatchDog.ComponentTN
198
199
self.df_components = {}
200
self.df_components["Task"] = DecodeWatchDog.ComponentT
201
self.df_components["Tsk"] = DecodeWatchDog.ComponentT
202
self.df_components["IErr"] = DecodeWatchDog.ComponentIE
203
self.df_components["IE"] = DecodeWatchDog.ComponentIE
204
self.df_components["IEC"] = DecodeWatchDog.ComponentIEC
205
self.df_components["IEL"] = DecodeWatchDog.ComponentIEL
206
self.df_components["MavMsg"] = DecodeWatchDog.ComponentMM
207
self.df_components["MvMsg"] = DecodeWatchDog.ComponentMM
208
self.df_components["MvCmd"] = DecodeWatchDog.ComponentMC
209
self.df_components["SemLine"] = DecodeWatchDog.ComponentSL
210
self.df_components["SmLn"] = DecodeWatchDog.ComponentSL
211
self.df_components["FL"] = DecodeWatchDog.ComponentFL
212
self.df_components["FT"] = DecodeWatchDog.ComponentFT
213
self.df_components["FA"] = DecodeWatchDog.ComponentFA
214
self.df_components["FP"] = DecodeWatchDog.ComponentFTP
215
self.df_components["LR"] = DecodeWatchDog.ComponentFLR
216
self.df_components["ICSR"] = DecodeWatchDog.ComponentFICSR
217
self.df_components["TN"] = DecodeWatchDog.ComponentTN
218
219
def run(self, text):
220
221
# see if the supplied string is a statustext message:
222
re_string = "(?:APM: )?WDG:"
223
for component in self.components.keys():
224
re_string += " %s(?P<%s>[^ ]+)" % (component, component)
225
226
# print("string: %s" % text)
227
# print("re_string: %s" % re_string)
228
229
wdg_re = re.compile(re_string)
230
231
m = wdg_re.match(text)
232
if m is not None:
233
comp = []
234
for group in m.groupdict():
235
comp.append(self.components[group](m.group(group)))
236
for c in comp:
237
c.print_decoded()
238
return
239
240
# not a statustext message; see if it a WDOG dataflash message
241
df_re = re.compile("WDOG {(.*)}")
242
m = df_re.match(text)
243
if m is not None:
244
pairs = m.group(1).split(",")
245
for pair in pairs:
246
(name, value) = pair.split(":")
247
name = name.strip()
248
if name == "TimeUS":
249
continue
250
value = value.strip()
251
# print("(%s)=(%s)" % (name, value))
252
if name in ["LR", "FICSR", "FA"]:
253
value = int(value, 10)
254
value = hex(value)
255
value = value[2:]
256
if name not in self.df_components:
257
raise KeyError(name)
258
self.df_components[name](value).print_decoded()
259
return
260
261
# not a statustext message and not a mavlogdump dump of a WDOG
262
# dataflash message. See if it is a .log-style CSV line
263
log_re = re.compile(r"WDOG, (\d+), ([-\d]+), ([-\d]+), ([-\d]+), ([-\d]+), ([-\d]+), ([-\d]+), ([-\d]+), ([-\d]+), "
264
r"([-\d]+), ([-\d]+), ([-\d]+), ([-\d]+), ([-\d]+), (\w+)")
265
column_names = "TimeUS,Tsk,IE,IEC,IEL,MvMsg,MvCmd,SmLn,FL,FT,FA,FP,ICSR,LR,TN"
266
cols = column_names.split(",")
267
m = log_re.match(text)
268
if m is not None:
269
for i in range(0, len(cols)):
270
name = cols[i]
271
if name == 'TimeUS':
272
continue
273
value = m.group(i+1)
274
# convert some things from base10 to hex:
275
if name in ["LR", "FICSR", "FA"]:
276
value = int(value, 10)
277
value = hex(value)
278
value = value[2:]
279
if name not in self.df_components:
280
raise KeyError(name)
281
self.df_components[name](value).print_decoded()
282
return
283
284
raise ValueError("Text not recognised")
285
286
# 2020-06-10 17:20:08.45: WDOG {TimeUS : 949568, Task : -2, IErr : 0, IErrCnt : 0, MavMsg : 0, MavCmd : 0, SemLine : 0, FL : 100, FT : 3, FA : 404947019, FP : 183, ICSR : 4196355} # NOQA
287
288
# APM: WDG: T-3 SL0 FL122 FT3 FA0 FTP177 FLR80CBB35 FICSR4196355 MM0 MC0 IE67108864 IEC12353 TN:rcin
289
290
# FMT, 254, 47, WDOG, QbIHHHHHHHIBIIn, TimeUS,Tsk,IE,IEC,IEL,MvMsg,MvCmd,SmLn,FL,FT,FA,FP,ICSR,LR,TN
291
# WDOG, 2641424, -3, 0, 0, 0, 0, 0, 0, 122, 3, 0, 181, 4196355, 135203219, SPI1
292
293
294
if __name__ == '__main__':
295
296
parser = optparse.OptionParser(__file__)
297
298
opts, args = parser.parse_args()
299
300
if len(args) == 0:
301
print("Usage: %s" % parser.usage)
302
sys.exit(0)
303
304
text = args[0]
305
306
decoder = DecodeWatchDog()
307
decoder.run(text)
308
309