Skip to content

Instantly share code, notes, and snippets.

@erpalma
Created July 3, 2016 15:57
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save erpalma/9f3e74b0f81384a558cb08e5e4c7b48e to your computer and use it in GitHub Desktop.
Fast python script to download blackbox log in cleanflight / betaflight / iNav.
import re, argparse, sys, time
from serial import Serial
'''
Cleanflight/betaflight/iNav blackbox dumper.
WARNING: the target bust be compiled with USE_FLASH_TOOLS defined.
'''
CLI_DELIMITER = '# '
class TimeoutException(Exception):
pass
def recv_until(ser, delimiter):
recv_buf = ''
while not delimiter in recv_buf:
b = ser.read(1)
if not b:
raise TimeoutException('Timeout while waiting for a reponse from FC. Powercycle the FC and retry.')
recv_buf += b
return recv_buf
def drawProgressBar(percent, speed, eta, barLen = 50):
sys.stdout.write("\r")
progress = ""
for i in range(barLen):
if i < int(barLen * percent):
progress += "="
else:
progress += " "
sys.stdout.write("[ %s ] %.2f%% - %.1f KB/s - ETA: %ds" % (progress, percent * 100, speed / 1024, eta) + ' ' * 10)
sys.stdout.flush()
def main():
parser = argparse.ArgumentParser(description='iNav blackbox dumper')
parser.add_argument('port', help='the serial port iNav is connected to')
parser.add_argument('baudrate', type=int, help='the baudrate of the serial port')
parser.add_argument('output_file', help='the file to write the blackbox dump to')
args = parser.parse_args()
ser = Serial(args.port, args.baudrate, timeout=1)
try:
print('Entering CLI...')
ser.write('#')
recv_until(ser, CLI_DELIMITER)
print('Getting flash size...')
ser.write('flash_info\n')
flash_info = recv_until(ser, CLI_DELIMITER)
used_size = int(re.findall(r'usedSize=([0-9]+)', flash_info)[0])
ser.write('flash_read 0 {:d}\n'.format(used_size))
try:
print('Dumping...')
recv_until(ser, 'flash_read 0 {size}\r\nReading {size} bytes at 0:\r\n'.format(size=used_size))
dump = ''
start_t = time.time()
for i in xrange(used_size):
b = ser.read(1)
if not b:
break
dump += b
if i and i % 10240 == 0:
percent = float(i) / used_size
speed = i / (time.time() - start_t)
eta = (used_size - i) / speed
drawProgressBar(percent, speed, eta)
print('Done! Writing to disk...')
dump = dump[dump.index('H Product:Blackbox'):]
try:
with open(args.output_file,'wb') as outfile:
outfile.write(dump)
except IOError:
print('Unable to write to the output file!')
except TimeoutException:
print('Something went wrong while reading the blackbox dump.')
except TimeoutException as e:
print(e)
except KeyboardInterrupt:
pass
ser.write('exit\n')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment