Procházet zdrojové kódy

[FL-3180] OTP programmer: return exit code based on error type (#2504)

Sergey Gavrilov před 2 roky
rodič
revize
6ec62f48f9
2 změnil soubory, kde provedl 45 přidání a 21 odebrání
  1. 20 7
      scripts/flipper/utils/programmer_openocd.py
  2. 25 14
      scripts/otp.py

+ 20 - 7
scripts/flipper/utils/programmer_openocd.py

@@ -1,6 +1,7 @@
 import logging
 import logging
 import os
 import os
 import typing
 import typing
+from enum import Enum
 
 
 from flipper.utils.programmer import Programmer
 from flipper.utils.programmer import Programmer
 from flipper.utils.openocd import OpenOCD
 from flipper.utils.openocd import OpenOCD
@@ -8,6 +9,14 @@ from flipper.utils.stm32wb55 import STM32WB55
 from flipper.assets.obdata import OptionBytesData
 from flipper.assets.obdata import OptionBytesData
 
 
 
 
+class OpenOCDProgrammerResult(Enum):
+    Success = 0
+    ErrorGeneric = 1
+    ErrorAlignment = 2
+    ErrorAlreadyWritten = 3
+    ErrorValidation = 4
+
+
 class OpenOCDProgrammer(Programmer):
 class OpenOCDProgrammer(Programmer):
     def __init__(
     def __init__(
         self,
         self,
@@ -199,18 +208,18 @@ class OpenOCDProgrammer(Programmer):
 
 
         return True
         return True
 
 
-    def otp_write(self, address: int, file_path: str) -> bool:
+    def otp_write(self, address: int, file_path: str) -> OpenOCDProgrammerResult:
         # Open file, check that it aligned to 8 bytes
         # Open file, check that it aligned to 8 bytes
         with open(file_path, "rb") as f:
         with open(file_path, "rb") as f:
             data = f.read()
             data = f.read()
             if len(data) % 8 != 0:
             if len(data) % 8 != 0:
                 self.logger.error(f"File {file_path} is not aligned to 8 bytes")
                 self.logger.error(f"File {file_path} is not aligned to 8 bytes")
-                return False
+                return OpenOCDProgrammerResult.ErrorAlignment
 
 
         # Check that address is aligned to 8 bytes
         # Check that address is aligned to 8 bytes
         if address % 8 != 0:
         if address % 8 != 0:
             self.logger.error(f"Address {address} is not aligned to 8 bytes")
             self.logger.error(f"Address {address} is not aligned to 8 bytes")
-            return False
+            return OpenOCDProgrammerResult.ErrorAlignment
 
 
         # Get size of data
         # Get size of data
         data_size = len(data)
         data_size = len(data)
@@ -218,7 +227,7 @@ class OpenOCDProgrammer(Programmer):
         # Check that data size is aligned to 8 bytes
         # Check that data size is aligned to 8 bytes
         if data_size % 8 != 0:
         if data_size % 8 != 0:
             self.logger.error(f"Data size {data_size} is not aligned to 8 bytes")
             self.logger.error(f"Data size {data_size} is not aligned to 8 bytes")
-            return False
+            return OpenOCDProgrammerResult.ErrorAlignment
 
 
         self.logger.debug(f"Writing {data_size} bytes to OTP at {address:08X}")
         self.logger.debug(f"Writing {data_size} bytes to OTP at {address:08X}")
         self.logger.debug(f"Data: {data.hex().upper()}")
         self.logger.debug(f"Data: {data.hex().upper()}")
@@ -241,14 +250,14 @@ class OpenOCDProgrammer(Programmer):
                     self.logger.error(
                     self.logger.error(
                         f"OTP memory at {address + i:08X} is not empty: {device_word:08X}"
                         f"OTP memory at {address + i:08X} is not empty: {device_word:08X}"
                     )
                     )
-                    raise Exception("OTP memory is not empty")
+                    return OpenOCDProgrammerResult.ErrorAlreadyWritten
 
 
                 if device_word != file_word:
                 if device_word != file_word:
                     already_written = False
                     already_written = False
 
 
             if already_written:
             if already_written:
                 self.logger.info(f"OTP memory is already written with the given data")
                 self.logger.info(f"OTP memory is already written with the given data")
-                return True
+                return OpenOCDProgrammerResult.Success
 
 
             self.reset(self.RunMode.Stop)
             self.reset(self.RunMode.Stop)
             stm32.clear_flash_errors(oocd)
             stm32.clear_flash_errors(oocd)
@@ -278,4 +287,8 @@ class OpenOCDProgrammer(Programmer):
             stm32.reset(oocd, stm32.RunMode.Run)
             stm32.reset(oocd, stm32.RunMode.Run)
             oocd.stop()
             oocd.stop()
 
 
-        return validation_result
+        return (
+            OpenOCDProgrammerResult.Success
+            if validation_result
+            else OpenOCDProgrammerResult.ErrorValidation
+        )

+ 25 - 14
scripts/otp.py

@@ -34,8 +34,16 @@ OTP_DISPLAYS = {
 }
 }
 
 
 from flipper.app import App
 from flipper.app import App
-from flipper.cube import CubeProgrammer
-from flipper.utils.programmer_openocd import OpenOCDProgrammer
+from flipper.utils.programmer_openocd import OpenOCDProgrammer, OpenOCDProgrammerResult
+
+
+class OTPException(Exception):
+    def __init__(self, message: str, result: OpenOCDProgrammerResult):
+        self.message = message
+        self.result = result
+
+    def get_exit_code(self) -> int:
+        return int(self.result.value)
 
 
 
 
 class Main(App):
 class Main(App):
@@ -183,13 +191,14 @@ class Main(App):
                 self.args.serial,
                 self.args.serial,
             )
             )
 
 
-            if not openocd.otp_write(0x1FFF7000, filename):
-                raise Exception("Failed to flash OTP")
+            programmer_result = openocd.otp_write(0x1FFF7000, filename)
+            if programmer_result != OpenOCDProgrammerResult.Success:
+                raise OTPException("Failed to flash OTP", programmer_result)
 
 
             self.logger.info(f"Flashed Successfully")
             self.logger.info(f"Flashed Successfully")
-        except Exception as e:
+        except OTPException as e:
             self.logger.exception(e)
             self.logger.exception(e)
-            return 1
+            return e.get_exit_code()
         finally:
         finally:
             os.remove(filename)
             os.remove(filename)
 
 
@@ -215,13 +224,14 @@ class Main(App):
                 self.args.serial,
                 self.args.serial,
             )
             )
 
 
-            if not openocd.otp_write(0x1FFF7010, filename):
-                raise Exception("Failed to flash OTP")
+            programmer_result = openocd.otp_write(0x1FFF7010, filename)
+            if programmer_result != OpenOCDProgrammerResult.Success:
+                raise OTPException("Failed to flash OTP", programmer_result)
 
 
             self.logger.info(f"Flashed Successfully")
             self.logger.info(f"Flashed Successfully")
-        except Exception as e:
+        except OTPException as e:
             self.logger.exception(e)
             self.logger.exception(e)
-            return 1
+            return e.get_exit_code()
         finally:
         finally:
             os.remove(filename)
             os.remove(filename)
 
 
@@ -249,13 +259,14 @@ class Main(App):
                 self.args.serial,
                 self.args.serial,
             )
             )
 
 
-            if not openocd.otp_write(0x1FFF7000, filename):
-                raise Exception("Failed to flash OTP")
+            programmer_result = openocd.otp_write(0x1FFF7000, filename)
+            if programmer_result != OpenOCDProgrammerResult.Success:
+                raise OTPException("Failed to flash OTP", programmer_result)
 
 
             self.logger.info(f"Flashed Successfully")
             self.logger.info(f"Flashed Successfully")
-        except Exception as e:
+        except OTPException as e:
             self.logger.exception(e)
             self.logger.exception(e)
-            return 1
+            return e.get_exit_code()
         finally:
         finally:
             os.remove(filename)
             os.remove(filename)