diff options
author | Richard Dzenis <rixript@gmail.com> | 2014-06-09 10:05:24 +0300 |
---|---|---|
committer | ilya <ilja@Ilyas-MacBook-Pro.local> | 2014-10-24 17:46:19 +0300 |
commit | 7cfeaa73e5f046a5dbf2b2f4f7f266145acc10d3 (patch) | |
tree | 4584eb78cc1b07b8d8d0306eda9ce5615e69a1e0 /Tools | |
parent | 6eaebe08e1aff3749075cc73b09d4ebb2c57dd5e (diff) | |
download | px4-firmware-7cfeaa73e5f046a5dbf2b2f4f7f266145acc10d3.tar.gz px4-firmware-7cfeaa73e5f046a5dbf2b2f4f7f266145acc10d3.tar.bz2 px4-firmware-7cfeaa73e5f046a5dbf2b2f4f7f266145acc10d3.zip |
Tools/fileman/ nsh scripts; writefile command.
Diffstat (limited to 'Tools')
-rwxr-xr-x | Tools/fileman/deletelogs.py | 24 | ||||
-rwxr-xr-x | Tools/fileman/delmix.py | 24 | ||||
-rwxr-xr-x | Tools/fileman/delrc.py | 24 | ||||
-rwxr-xr-x | Tools/fileman/getlog.py | 80 | ||||
-rwxr-xr-x | Tools/fileman/getmix.py | 34 | ||||
-rwxr-xr-x | Tools/fileman/getrc.py | 34 | ||||
-rwxr-xr-x | Tools/fileman/nsh.py | 222 | ||||
-rwxr-xr-x | Tools/fileman/setmix.py | 30 | ||||
-rwxr-xr-x | Tools/fileman/setrc.py | 30 |
9 files changed, 502 insertions, 0 deletions
diff --git a/Tools/fileman/deletelogs.py b/Tools/fileman/deletelogs.py new file mode 100755 index 000000000..b27b3e87b --- /dev/null +++ b/Tools/fileman/deletelogs.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# +# Logs deleter +# + +from nsh import NSH + +def main(): + try: + logs_dir = "/fs/microsd/log" + nsh = NSH() + nsh.wait_and_open_nsh() + for file in nsh.get_all_files(logs_dir): + print("Removing file: {}{}".format(logs_dir, file)) + nsh.exec_cmd("rm {}{}".format(logs_dir, file), 2.0) + for dir in nsh.get_all_dirs(logs_dir): + print("Removing dir: {}/{}".format(logs_dir, dir)) + nsh.exec_cmd("rmdir {}/{}".format(logs_dir, dir[:-1]), 1.0) + print("Done.") + finally: + nsh.close() + +if __name__ == "__main__": + main() diff --git a/Tools/fileman/delmix.py b/Tools/fileman/delmix.py new file mode 100755 index 000000000..b6b8cdd4b --- /dev/null +++ b/Tools/fileman/delmix.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# +# /fs/microsd/etc/mixers/FMU_quad_x.mix file deleter +# + +from nsh import NSH + +def main(): + fn = "/fs/microsd/etc/mixers/FMU_quad_x.mix" + + try: + nsh = NSH() + nsh.wait_and_open_nsh() + if nsh.file_exists(fn): + nsh.exec_cmd("rm {}".format(fn), 2.0) + print("Success.") + else: + print("Cannot find {}".format(fn)) + + finally: + nsh.close() + +if __name__ == "__main__": + main() diff --git a/Tools/fileman/delrc.py b/Tools/fileman/delrc.py new file mode 100755 index 000000000..3606d2bed --- /dev/null +++ b/Tools/fileman/delrc.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# +# /fs/microsd/etc/rc.txt file deleter +# + +from nsh import NSH + +def main(): + fn = "/fs/microsd/etc/rc.txt" + + try: + nsh = NSH() + nsh.wait_and_open_nsh() + if nsh.file_exists(fn): + nsh.exec_cmd("rm {}".format(fn), 2.0) + print("Success.") + else: + print("Cannot find {}".format(fn)) + + finally: + nsh.close() + +if __name__ == "__main__": + main() diff --git a/Tools/fileman/getlog.py b/Tools/fileman/getlog.py new file mode 100755 index 000000000..e3a68baac --- /dev/null +++ b/Tools/fileman/getlog.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# +# Log file downloader +# + +from nsh import NSH +from sys import argv, exit +from datetime import datetime +import re + +def main(): + if(len(argv) != 2): + print("usage: getlog [last|list|log_path]") + exit(1) + + cmd = argv[1] + logs_dir = "/fs/microsd/log" + + try: + nsh = NSH() + nsh.wait_and_open_nsh() + if cmd == "list": + for file in nsh.get_all_files(logs_dir): + print(file) + elif cmd == "all": + for file in nsh.get_all_files(logs_dir): + with open(fn[fn.rindex('/')+1:], "wb") as f: + data = nsh.download_file(logs_dir + file) + print("Writing buffer to file..") + f.write(data) + print("Success.") + elif cmd == "last": + dirs = nsh.ls_dir(logs_dir) + # Keep entries only "date/" entries + dirs = filter(lambda d: re.sub("[0-9]{4}\-[0-9]{2}\-[0-9]{2}", '', d) == "/", dirs) + if dirs: + dirs.sort(key=lambda x: datetime.strptime(x, '%Y-%m-%d/')) + + last_dir = dirs.pop() + print("Getting logs from {}/{}".format(logs_dir, last_dir)) + + logs = nsh.ls_dir(logs_dir + '/' + last_dir) + # Keep entries only which end with .bin + logs = filter(lambda l: l.endswith('.bin'), logs) + if logs: + logs.sort(key=lambda x: datetime.strptime(x, "%H_%M_%S.bin")) + + last_log = logs.pop() + data = nsh.download_file(logs_dir + '/' + last_dir + last_log) + with open(last_log, "wb") as f: + f.write(data) + + preflight = "preflight_perf" + last_log[:-3] + "txt" + if nsh.file_exists(logs_dir + '/' + last_dir + preflight): + data = nsh.download_file(logs_dir + '/' + last_dir + preflight) + with open(preflight, "wb") as f: + f.write(data) + else: + print("Cannot find {} file (ignoring it).".format(preflight)) + + print("Success.") + else: + print("Cannot find any log with timestamp!") + else: + print("Unable to find any log with date") + else: + fn = logs_dir + "/" + cmd + if nsh.file_exists(fn): + data = nsh.download_file(fn) + with open(fn[fn.rindex('/')+1:], "wb") as f: + f.write(data) + print("Success.") + else: + print("File {} does not exists!") + finally: + nsh.close() + +if __name__ == "__main__": + main() + diff --git a/Tools/fileman/getmix.py b/Tools/fileman/getmix.py new file mode 100755 index 000000000..e375c71ae --- /dev/null +++ b/Tools/fileman/getmix.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# +# /fs/microsd/etc/mixers/FMU_quad_x.mix file downloader +# + +from nsh import NSH + +def main(): + fn = "/fs/microsd/etc/mixers/FMU_quad_x.mix" + + if len(argv) == 1: + out_fn = fn[fn.rindex('/')+1:] + else: + out_fn = argv[1] + + + try: + nsh = NSH() + nsh.wait_and_open_nsh() + if nsh.file_exists(fn): + with open(out_fn, "wb") as f: + data = nsh.download_file(fn) + print("Writing buffer to file..") + f.write(data) + print("Success.") + else: + print("Cannot find {}".format(fn)) + + finally: + nsh.close() + +if __name__ == "__main__": + main() + diff --git a/Tools/fileman/getrc.py b/Tools/fileman/getrc.py new file mode 100755 index 000000000..902fe857b --- /dev/null +++ b/Tools/fileman/getrc.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# +# /fs/microsd/etc/rc.txt file downloader +# + +from nsh import NSH +from sys import argv + +def main(): + fn = "/fs/microsd/etc/rc.txt" + + if len(argv) == 1: + out_fn = fn[fn.rindex('/')+1:] + else: + out_fn = argv[1] + + try: + nsh = NSH() + nsh.wait_and_open_nsh() + if nsh.file_exists(fn): + with open(out_fn, "wb") as f: + data = nsh.download_file(fn) + print("Writing buffer to file..") + f.write(data) + print("Success.") + else: + print("Cannot find {}".format(fn)) + + finally: + nsh.close() + +if __name__ == "__main__": + main() + diff --git a/Tools/fileman/nsh.py b/Tools/fileman/nsh.py new file mode 100755 index 000000000..8336b3c50 --- /dev/null +++ b/Tools/fileman/nsh.py @@ -0,0 +1,222 @@ +import os, sys, serial, time, struct + +class NSH: + def __init__(self): + self.serial = None + + def flush(self): + self.serial.flush() + + def send(self, data): + from collections import deque + data = deque(data) + attempt = 0 + while data: + if self.serial.write(data.popleft()) == 0: + print("Failed to write {}".format(attempt)) + attempt += 1 + if attempt > 50: + raise RuntimeError("fail") + else: + attempt = 0 + self.serial.flush() + + def recv(self, size=1): + if size is not None: + attempt = 1 + data = self.serial.read(size) + if len(data) < 1: + raise RuntimeError("timeout waiting for data") + size -= len(data) + if size > 0: + #raise RuntimeError("received less data than expected ({}/{})".format(len(data), size)) + attempt += 1 + if attempt > 10: + raise RuntimeError("Couldn't receive all the data ({} bytes left)".format(size)) + return data + else: + return self.serial.read() + + def wait_for_string(self, s, timeout, debug=False): + t0 = time.time() + buf = [] + res = [] + n = 0 + if type(s) == str: + s = (s,) + maxlen = max((len(string) for string in s)) + while True: + c = self.recv(size=None) + if debug: + sys.stderr.write(c) + buf.append(c) + if len(buf) > maxlen: + res.append(buf.pop(0)) + n += 1 + if n % 10000 == 0: + sys.stderr.write(str(n) + "\n") + string = "".join(buf) + for sz in s: + index = string.find(sz) + if index != -1: + res += buf[:index] + return "".join(res) + if timeout > 0.0 and time.time() - t0 > timeout: + raise Exception("Timeout while waiting for: {}".format(s)) + + def exec_cmd(self, cmd, timeout, cmd_end_str=("nsh> \x1b[K",)): + print("nsh> {}".format(cmd)) + self.send(cmd + "\n") + self.flush() + self.wait_for_string(cmd + "\r\n", timeout) + if cmd_end_str: + return self.wait_for_string(cmd_end_str, timeout) + else: + return None + + def identify(self): + #ver hw + #PX4FMU_V2 + return self.exec_cmd("ver hw", 1.0).startswith("PX4FMU_V2") + + def ls_dir(self, dir, timeout=1.0): + res = [] + dir = dir.rstrip("/") + for line in self.exec_cmd("ls " + dir, timeout).splitlines()[1:]: + res.append(line[1:]) + return res + + def get_dir_files(self, directory="/"): + res = [] + for f in self.ls_dir(directory): + if f[-1] != '/': #is file + res.append(f) + return f + + def get_all_files(self, basedir="/", subdir="/"): + dir = basedir + subdir + res = [] + for d in self.ls_dir(dir): + if d[-1] == '/': + res += self.get_all_files(basedir, subdir + d) + else: + res.append(subdir + d) + return res + + def get_all_dirs(self, basedir="/", subdir="/"): + dir = basedir + subdir + res = [] + for d in self.ls_dir(dir): + if d[-1] == '/': + res += self.get_all_files(basedir, subdir + d) + res.append(d) + return res + + def file_exists(self, fn): + rslash = fn.rindex("/") + dir = fn[:rslash] + fn = fn[rslash+1:] + found = False + for file in self.ls_dir(dir): + if file == fn: + return True + return False + + def download_file(self, fn): + res = self.exec_cmd("dumpfile " + fn, 1.0, ("\n",)) + data = [] + if res.startswith("OK"): + size = int(res.split()[1]) + block_size = 1024 * 16 + print("Reading file {}:".format(fn)) + while size > 0: + buf = self.recv(min(size, block_size)) + data.append(buf) + size -= len(buf) + print("Read {} bytes / {} left".format(len(buf), size)) + sys.stdout.flush() + print("Successfully read file {}".format(fn)) + else: + raise Exception("Error downloading file (not exists?)") + self.wait_for_string("nsh> \x1b[K", 2.0) + return "".join(data) + + def random_str(self, length): + from random import shuffle + from math import ceil + abc = ''.join([chr(c) for c in range(ord('a'), ord('z') + 1)]) + ABC = ''.join([chr(c) for c in range(ord('A'), ord('Z') + 1)]) + num = '0123456789' + string = abc + ABC + num + mul = int(ceil(float(length) / len(string))) + res = list(string * mul) + shuffle(res) + return ''.join(res[:length]) + + def upload_file(self, out_fn, in_fn): + f = open(in_fn, 'rb') + filedata = f.read() + f.close() + + szOK = "OK\r\n" + szDEFEND = "nsh> \x1b[K" + + while True: + tmp_fn = '/fs/microsd/' + self.random_str(14) + '.tmp' + if not self.file_exists(tmp_fn): + break + + res = self.exec_cmd("writefile {} {}".format(tmp_fn, len(filedata)), 1.0, (szDEFEND, szOK)) + if len(res) == 0: #szOK found + self.flush() + print("Writing file {}".format(tmp_fn)) + self.send(filedata) + self.wait_for_string("nsh> \x1b[K", 2.0) + print("Deleting {}".format(out_fn)) + self.exec_cmd("rm {}".format(out_fn), 2.0) + print("Coping {} to {}".format(tmp_fn, out_fn)) + self.exec_cmd("cp {} {}".format(tmp_fn, out_fn), 2.0) + print("Removing temponary file {}".format(tmp_fn)) + self.exec_cmd("rm {}".format(tmp_fn), 2.0) + return True + else: #nsh> found + print("Error occured during the file upload (`{}` < `{}`)".format(out_fn, in_fn)) + print(res) + return False + + def wait_and_open_nsh(self): + print("Waiting for the device.. (Press Ctrl+C to stop)") + while True: + if os.name == 'nt': + port_list = ['COM32', 'COM31', 'COM30', 'COM29', 'COM28', 'COM27', 'COM26', 'COM25', 'COM24', 'COM23', 'COM22', 'COM21', 'COM20', 'COM19', 'COM18', 'COM17', 'COM16', 'COM15', 'COM14', 'COM13', 'COM12', 'COM11', 'COM10', 'COM9', 'COM8', 'COM7', 'COM6', 'COM5', 'COM4', 'COM3', 'COM2', 'COM1', 'COM0'] + else: + from glob import glob + port_list = glob("/dev/serial/by-id/usb-3D_Robotics*") #linux + port_list += glob("/dev/tty.usbmodem*") #mac + + for port in port_list: + try: + self.serial = serial.Serial(port, 57600, timeout=0.5) + except serial.SerialException: + #open failed, rate-limit our attempts + time.sleep(0.05) + # and loop to the next port + continue + + # port is open, try talking to it + # identify the bootloader + if self.identify(): + print("Found device on port {}".format(port)) + return + else: + print("Ignoring invalid board on port {}".format(port)) + self.close() + continue + + def close(self): + if self.serial is not None: + self.serial.close() + +if __name__ == "__main__": + print("This is class file. It does nothing.") + diff --git a/Tools/fileman/setmix.py b/Tools/fileman/setmix.py new file mode 100755 index 000000000..d010596c8 --- /dev/null +++ b/Tools/fileman/setmix.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# +# /fs/microsd/etc/mixers/FMU_quad_x.mix file uploader +# + +from nsh import NSH + +from os import path +from sys import argv, exit + +def main(): + if len(argv) != 2: + print("usage: setmix <path to FMU_quad_x.mix>") + exit(1) + + rc_path = argv[1] + if not path.isfile(rc_path): + print("cannot find file {}".format(rc_path)) + exit(2) + + try: + nsh = NSH() + nsh.wait_and_open_nsh() + if nsh.upload_file("/fs/microsd/etc/mixers/FMU_quad_x.mix", rc_path): + print("Success.") + finally: + nsh.close() + +if __name__ == "__main__": + main() diff --git a/Tools/fileman/setrc.py b/Tools/fileman/setrc.py new file mode 100755 index 000000000..13088f721 --- /dev/null +++ b/Tools/fileman/setrc.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# +# /fs/microsd/etc/rc.txt file uploader +# + +from nsh import NSH + +from os import path +from sys import argv, exit + +def main(): + if len(argv) != 2: + print("usage: setrc <path to rc.txt>") + exit(1) + + rc_path = argv[1] + if not path.isfile(rc_path): + print("cannot find file {}".format(rc_path)) + exit(2) + + try: + nsh = NSH() + nsh.wait_and_open_nsh() + if nsh.upload_file("/fs/microsd/etc/rc.txt", rc_path): + print("Success.") + finally: + nsh.close() + +if __name__ == "__main__": + main() |