From d0018c6726a85c2867788a3f9a60dc7c24417d90 Mon Sep 17 00:00:00 2001 From: andreas Date: Sun, 5 Nov 2023 16:26:19 +0100 Subject: [PATCH] make configs without sensors working again --- lib/iictask/GwIicTask.cpp | 1 - tools/flashtool/flashtool.py | 240 +++++++++++++++++++---------------- 2 files changed, 134 insertions(+), 107 deletions(-) diff --git a/lib/iictask/GwIicTask.cpp b/lib/iictask/GwIicTask.cpp index 889d5391..51f36334 100644 --- a/lib/iictask/GwIicTask.cpp +++ b/lib/iictask/GwIicTask.cpp @@ -31,7 +31,6 @@ static SensorList sensors; void initIicTask(GwApi *api){ GwLog *logger=api->getLogger(); #ifndef _GWIIC - vTaskDelete(NULL); return; #else bool addTask=false; diff --git a/tools/flashtool/flashtool.py b/tools/flashtool/flashtool.py index 47f6d504..9f0c0480 100755 --- a/tools/flashtool/flashtool.py +++ b/tools/flashtool/flashtool.py @@ -18,9 +18,130 @@ from tkinter import filedialog as FileDialog import builtins +import esptool + +VERSION="Version 2.0" +class Flasher(): + def getVersion(self): + return ("Version %s, esptool %s"%(VERSION,str(esptool.__version__))) + + UPDATE_ADDR = 0x10000 + HDROFFSET = 288 + VERSIONOFFSET = 16 + NAMEOFFSET = 48 + IDOFFSET=12 #2 byte chipid + MINSIZE = HDROFFSET + NAMEOFFSET + 32 + CHECKBYTES = { + 288: 0x32, # app header magic + 289: 0x54, + 290: 0xcd, + 291: 0xab + } + #flash addresses for full images based on chip id + FLASH_ADDR={ + 0: 0x1000, + 9: 0 + } + def getString(self,buffer, offset, len): + return buffer[offset:offset + len].rstrip(b'\0').decode('utf-8') + def getFirmwareInfo(self,filename,isFull): + with open(filename,"rb") as ih: + buffer = ih.read(self.MINSIZE) + if len(buffer) != self.MINSIZE: + return self.setErr("invalid image file %s, to short"%filename) + if buffer[0] != 0xe9: + return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0]) + chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1] + flashoffset=self.FLASH_ADDR.get(chipid) + if flashoffset is None: + return self.setErr("unknown chip id in image %d",chipid); + if isFull: + offset=self.UPDATE_ADDR-flashoffset; + offset-=self.MINSIZE + ih.seek(offset,os.SEEK_CUR) + buffer=ih.read(self.MINSIZE) + if len(buffer) != self.MINSIZE: + return self.setErr("invalid image file %s, to short"%filename) + if buffer[0] != 0xe9: + return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0]) + for k, v in self.CHECKBYTES.items(): + if buffer[k] != v: + return self.setErr("invalid magic at %d, expected %d got %d" + % (k+offset, v, buffer[k])) + name = self.getString(buffer, self.HDROFFSET + self.NAMEOFFSET, 32) + version = self.getString(buffer, self.HDROFFSET + self.VERSIONOFFSET, 32) + chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1] + flashoffset=flashoffset if isFull else self.UPDATE_ADDR + return { + 'error':False, + 'info':"%s:%s"%(name,version), + 'chipid':chipid, + 'flashbase':flashoffset + } + def setErr(self,err): + return {'error':True,'info':err} + def checkImageFile(self,filename,isFull): + if not os.path.exists(filename): + return self.setErr("file %s not found"%filename) + return self.getFirmwareInfo(filename,isFull) + + def checkSettings(self,port,fileName,isFull): + if port is None: + print("ERROR: no com port selected") + return + if fileName is None or fileName == '': + print("ERROR: no filename selected") + return + info = self.checkImageFile(fileName, isFull) + if info['error']: + print("ERROR: %s" % info['info']) + return + return {'fileName': fileName,'port':port,'isFull':isFull,'info':info} + def runEspTool(self,command): + print("run esptool: %s" % " ".join(command)) + try: + esptool.main(command) + print("esptool done") + return True + except Exception as e: + print("Exception in esptool %s" % e) + def verifyChip(self,param): + if not param: + print("check failed") + return + imageChipId=param['info']['chipid'] + chip=esptool.ESPLoader.detect_chip(param['port']) + print("Detected chip %s, id=%d"%(chip.CHIP_NAME,chip.IMAGE_CHIP_ID)) + if (chip.IMAGE_CHIP_ID != imageChipId): + print("##Error: chip id in image %d does not match detected chip"%imageChipId) + return + print("Checks OK") + param['chipname']=chip.CHIP_NAME + return param + def runCheck(self,port,fileName,isFull): + param = self.checkSettings(port,fileName,isFull) + if not param: + return + print("Settings OK") + param=self.verifyChip(param) + if not param: + print("Check Failed") + return + print("flashbase=0x%x"%param['info']['flashbase']) + return param + def runFlash(self,param): + if not param: + return + if param['isFull']: + command=['--chip',param['chipname'],'--port',param['port'],'write_flash',str(param['info']['flashbase']),param['fileName']] + self.runEspTool(command) + else: + command=['--chip',param['chipname'],'--port',param['port'],'erase_region','0xe000','0x2000'] + self.runEspTool(command) + command = ['--chip', param['chipname'], '--port', param['port'], 'write_flash', str(param['info']['flashbase']), param['fileName']] + self.runEspTool(command) def main(): - VERSION="Version 2.0, esptool 3.2" oldprint=builtins.print def print(*args, **kwargs): @@ -32,6 +153,7 @@ def print(*args, **kwargs): class App: def __init__(self, root): + self.flasher=Flasher() root.title("ESP32 NMEA2000 Flash Tool") root.geometry("800x600") root.resizable(width=True, height=True) @@ -47,7 +169,7 @@ def __init__(self, root): frame.columnconfigure(1, weight=3) tk.Label(frame,text="ESP32 NMEA2000 Flash Tool").grid(row=row,column=0,columnspan=2,sticky='ew') row+=1 - tk.Label(frame, text=VERSION).grid(row=row,column=0,columnspan=2,sticky="ew",pady=10) + tk.Label(frame, text=self.flasher.getVersion()).grid(row=row,column=0,columnspan=2,sticky="ew",pady=10) row+=1 self.mode=tk.IntVar() self.mode.set(1) @@ -108,7 +230,7 @@ def fileDialog(self,ev): fn=FileDialog.askopenfilename() if fn: self.filename.set(fn) - info=self.checkImageFile(fn,self.mode.get() == 1) + info=self.flasher.checkImageFile(fn,self.mode.get() == 1) if info['error']: self.fileInfo.set("***ERROR: %s"%info['info']) else: @@ -141,68 +263,6 @@ def addText(self,*args,**kwargs): self.interrupt=False raise Exception("User cancel") - UPDATE_ADDR = 0x10000 - HDROFFSET = 288 - VERSIONOFFSET = 16 - NAMEOFFSET = 48 - IDOFFSET=12 #2 byte chipid - MINSIZE = HDROFFSET + NAMEOFFSET + 32 - CHECKBYTES = { - 288: 0x32, # app header magic - 289: 0x54, - 290: 0xcd, - 291: 0xab - } - #flash addresses for full images based on chip id - FLASH_ADDR={ - 0: 0x1000, - 9: 0 - } - - def getString(self,buffer, offset, len): - return buffer[offset:offset + len].rstrip(b'\0').decode('utf-8') - - def getFirmwareInfo(self,filename,isFull): - with open(filename,"rb") as ih: - buffer = ih.read(self.MINSIZE) - if len(buffer) != self.MINSIZE: - return self.setErr("invalid image file %s, to short"%filename) - if buffer[0] != 0xe9: - return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0]) - chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1] - flashoffset=self.FLASH_ADDR.get(chipid) - if flashoffset is None: - return self.setErr("unknown chip id in image %d",chipid); - if isFull: - offset=self.UPDATE_ADDR-flashoffset; - offset-=self.MINSIZE - ih.seek(offset,os.SEEK_CUR) - buffer=ih.read(self.MINSIZE) - if len(buffer) != self.MINSIZE: - return self.setErr("invalid image file %s, to short"%filename) - if buffer[0] != 0xe9: - return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0]) - for k, v in self.CHECKBYTES.items(): - if buffer[k] != v: - return self.setErr("invalid magic at %d, expected %d got %d" - % (k+offset, v, buffer[k])) - name = self.getString(buffer, self.HDROFFSET + self.NAMEOFFSET, 32) - version = self.getString(buffer, self.HDROFFSET + self.VERSIONOFFSET, 32) - chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1] - return { - 'error':False, - 'info':"%s:%s"%(name,version), - 'chipid':chipid, - 'flashbase':flashoffset if isFull else self.UPDATE_ADDR - } - - def setErr(self,err): - return {'error':True,'info':err} - def checkImageFile(self,filename,isFull): - if not os.path.exists(filename): - return self.setErr("file %s not found"%filename) - return self.getFirmwareInfo(filename,isFull) - def runCheck(self): self.text_widget.delete("1.0", "end") idx = self.port.current() @@ -212,63 +272,31 @@ def runCheck(self): return port = self.serialDevices[idx] fn = self.filename.get() - if fn is None or fn == '': - self.addText("ERROR: no filename selected") - return - info = self.checkImageFile(fn, isFull) - if info['error']: - print("ERROR: %s" % info['info']) - return - return {'port':port,'isFull':isFull,'info':info} + param = self.flasher.runCheck(port,fn,isFull) + return param - def runEspTool(self,command): + def runFlash(self,param): for b in self.actionButtons: b.configure(state=tk.DISABLED) self.cancelButton.configure(state=tk.NORMAL) - print("run esptool: %s" % " ".join(command)) root.update() root.update_idletasks() - try: - esptool.main(command) - print("esptool done") - except Exception as e: - print("Exception in esptool %s" % e) + self.flasher.runFlash(param) for b in self.actionButtons: b.configure(state=tk.NORMAL) self.cancelButton.configure(state=tk.DISABLED) - def verifyChip(self): - param = self.runCheck() - if not param: - print("check failed") - return - imageChipId=param['info']['chipid'] - chip=esptool.ESPLoader.detect_chip(param['port']) - print("Detected chip %s, id=%d"%(chip.CHIP_NAME,chip.IMAGE_CHIP_ID)) - if (chip.IMAGE_CHIP_ID != imageChipId): - print("##Error: chip id in image %d does not match detected chip"%imageChipId) - return - print("Checks OK") - param['chipname']=chip.CHIP_NAME - return param + def buttonCheck(self): - param = self.verifyChip() + param = self.runCheck() def buttonFlash(self): - param=self.verifyChip() + param=self.runCheck() if not param: return - if param['isFull']: - command=['--chip',param['chipname'],'--port',param['port'],'write_flash',str(param['info']['flashbase']),self.filename.get()] - self.runEspTool(command) - else: - command=['--chip',param['chipname'],'--port',param['port'],'erase_region','0xe000','0x2000'] - self.runEspTool(command) - command = ['--chip', param['chipname'], '--port', param['port'], 'write_flash', str(param['info']['flashbase']), self.filename.get()] - self.runEspTool(command) - - + self.runFlash(param) + def buttonCancel(self): self.interrupt=True