CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

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