From d7a44a5a719b86eba7526a48462d0f08d1f74691 Mon Sep 17 00:00:00 2001 From: sailoog Date: Wed, 24 Nov 2021 19:55:27 +0100 Subject: [PATCH] add firmware updating --- openplotterMaiana/data/file.png | Bin 0 -> 6334 bytes openplotterMaiana/fwupdate.py | 137 +++++++++++++++++++++++++ openplotterMaiana/openplotterMaiana.py | 32 +++++- 3 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 openplotterMaiana/data/file.png create mode 100644 openplotterMaiana/fwupdate.py diff --git a/openplotterMaiana/data/file.png b/openplotterMaiana/data/file.png new file mode 100644 index 0000000000000000000000000000000000000000..c73060142d4e6bae67e752bcbaf88decdb1d3fdb GIT binary patch literal 6334 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 ewQXZz39`8fN`9O6hBX0Mfh 0: + #print s + tokens = s.split(',') + if len(tokens) > 3: + return True + return False + +def drain_port(): + s = port.readline() + while len(s) > 0: + s = port.readline() + +def enable_dfu(): + if is_unit_running(): + print(_("Unit is running, switching to DFU mode")) + port.write(b'dfu\r\n') + drain_port() + + for x in range(5): + port.write(b'\r\n') + s = port.readline().strip() + if s.find(b"MAIANA bootloader") >= 0: + return True + + return False + + + +def begin_transfer(): + command = "load {0} {1:x}\r\n".format(filesize, crc32).encode('utf-8') + port.write(command) + + s = port.readline().strip() + return s == b"READY" + +def startSK(): + subprocess.call(['systemctl', 'start', 'signalk.socket']) + subprocess.call(['systemctl', 'start', 'signalk.service']) + +if __name__ == '__main__': + try: + if len(sys.argv) < 3: + print(_("Usage: {0} port imagefile".format(sys.argv[0]))) + sys.exit(1) + + subprocess.call(['systemctl', 'stop', 'signalk.service']) + subprocess.call(['systemctl', 'stop', 'signalk.socket']) + time.sleep(1) + + portname = sys.argv[1] + filename = sys.argv[2] + + port = serial.Serial(portname, 38400, timeout=2) + if not port.is_open: + print(_("Unable to open serial port")) + startSK() + sys.exit(2) + + file = None + + try: + file = open(filename, "rb") + except: + print(_("Unable to open file")+"{0}".format(filename)) + startSK() + sys.exit(2) + + filesize = os.stat(filename).st_size + #print filesize + data = file.read() + crc32 = (binascii.crc32(data) & 0xFFFFFFFF) + file.seek(0) + + print(_("File size:")+" {0}, CRC32: 0x{1:x}".format(filesize, crc32)) + + + if not enable_dfu(): + print (_("Could not get unit into DFU mode")) + startSK() + sys.exit(3) + + print(_("Unit is in DFU mode")) + + + if not begin_transfer(): + print(_("Unable to begin transfer, restart the unit and retry")) + startSK() + sys.exit(3) + + print(_("Starting transfer")) + + bytes = file.read(2048) + resp = '' + while len(bytes) > 0: + port.write(bytes) + #print "Sent {0} bytes".format(len(bytes)) + sys.stdout.write('.') + sys.stdout.flush() + resp = port.readline().strip() + if resp.find(b"OK") < 0: + break + #print s + bytes = file.read(2048) + + print() + print(resp.decode('utf-8')) + startSK() + except Exception as e: + print(_('FAILED: ')+str(e)) + startSK() \ No newline at end of file diff --git a/openplotterMaiana/openplotterMaiana.py b/openplotterMaiana/openplotterMaiana.py index 3b343ca..f1fedf9 100644 --- a/openplotterMaiana/openplotterMaiana.py +++ b/openplotterMaiana/openplotterMaiana.py @@ -201,8 +201,8 @@ class MyFrame(wx.Frame): ser.write('station?\r\n'.encode("utf-8")) ser.write('tx?\r\n'.encode("utf-8")) time.sleep(0.5) - resp = requests.get(self.platform.http+'localhost:'+self.platform.skPort+'/signalk/v1/api/vessels/self/MAIANA/', verify=False) try: + resp = requests.get(self.platform.http+'localhost:'+self.platform.skPort+'/signalk/v1/api/vessels/self/MAIANA/', verify=False) data = ujson.loads(resp.content) except: data = {} @@ -546,7 +546,9 @@ class MyFrame(wx.Frame): self.toolbar2 = wx.ToolBar(self.firmware, style=wx.TB_TEXT) toolRefresh = self.toolbar2.AddTool(201, _('Refresh'), wx.Bitmap(self.currentdir+"/data/refresh.png")) self.Bind(wx.EVT_TOOL, self.OnToolRefresh, toolRefresh) - + self.toolbar2.AddSeparator() + toolFile= self.toolbar2.AddTool(202, _('Update firmware'), wx.Bitmap(self.currentdir+"/data/file.png")) + self.Bind(wx.EVT_TOOL, self.OnToolFile, toolFile) self.logger = rt.RichTextCtrl(self.firmware, style=wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_DONTWRAP|wx.LC_SORT_ASCENDING) self.logger.SetMargins((10,10)) @@ -556,6 +558,32 @@ class MyFrame(wx.Frame): self.firmware.SetSizer(vbox) + def OnToolFile(self,e): + file_path = False + dlg = wx.FileDialog(self, message=_('Choose a file'), defaultDir='~', defaultFile='', wildcard=_('bin files') + ' (*.bin)|*.bin|' + _('All files') + ' (*.*)|*.*', style=wx.FD_OPEN | wx.FD_CHANGE_DIR) + if dlg.ShowModal() == wx.ID_OK: + file_path = dlg.GetPath() + dlg.Destroy() + if file_path: + dlg = wx.MessageDialog(None, _( + 'Your MAIANA device firmware will be updated, please do not disconnect or tamper with it during the update.\n\nDo you want to go ahead?'), + _('Question'), wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) + if dlg.ShowModal() == wx.ID_YES: + self.logger.Clear() + self.logger.WriteText(_("Stopping Signal K server")) + self.logger.Newline() + command = self.platform.admin+' python3 '+self.currentdir+'/fwupdate.py '+self.device+' '+file_path + popen = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=True) + for line in popen.stdout: + if not 'Warning' in line and not 'WARNING' in line: + self.logger.WriteText(line) + self.ShowStatusBarYELLOW(_('Updating firmware, please wait... ')+line) + self.logger.ShowPosition(self.logger.GetLastPosition()) + self.logger.WriteText(_("Starting Signal K server")) + self.SetStatusText('') + dlg.Destroy() + + ################################################################################ def main():