|
@@ -0,0 +1,46 @@
|
|
|
+#!/usr/bin/env python3
|
|
|
+import argparse
|
|
|
+import struct
|
|
|
+import os, sys
|
|
|
+
|
|
|
+from lib.dump import DUMP_MAGIC, DUMP_OFFSET, DUMP_SIZE
|
|
|
+
|
|
|
+
|
|
|
+def error(msg):
|
|
|
+ print(msg, file=sys.stderr)
|
|
|
+
|
|
|
+def main():
|
|
|
+ # parse the arguments
|
|
|
+ ap = argparse.ArgumentParser(description="""
|
|
|
+ Extract a crash dump from an external flash image and output
|
|
|
+ the same format produced by the D21 g-code.
|
|
|
+ """)
|
|
|
+ ap.add_argument('image')
|
|
|
+ args = ap.parse_args()
|
|
|
+
|
|
|
+ # read the image
|
|
|
+ off = DUMP_OFFSET
|
|
|
+ with open(args.image, 'rb') as fd:
|
|
|
+ fd.seek(off)
|
|
|
+ data = fd.read(DUMP_SIZE)
|
|
|
+ if len(data) != DUMP_SIZE:
|
|
|
+ error('incorrect image size')
|
|
|
+ return os.EX_DATAERR
|
|
|
+
|
|
|
+ # check for magic header
|
|
|
+ magic, = struct.unpack('<L', data[:4])
|
|
|
+ if magic != DUMP_MAGIC:
|
|
|
+ error('invalid dump magic or no dump')
|
|
|
+ return os.EX_DATAERR
|
|
|
+
|
|
|
+ # output D21 dump
|
|
|
+ print('D21 - read crash dump', end='')
|
|
|
+ for i in range(len(data)):
|
|
|
+ if i % 16 == 0:
|
|
|
+ print('\n{:06x} '.format(off + i), end='')
|
|
|
+ print(' {:02x}'.format(data[i]), end='')
|
|
|
+ print('\nok')
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == '__main__':
|
|
|
+ exit(main())
|