[FL-3180] OTP programmer: return exit code based on error type (#2504)
This commit is contained in:
parent
7de7fa293b
commit
6ec62f48f9
@ -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
|
||||||
|
)
|
||||||
|
@ -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, OpenOCDProgrammerResult
|
||||||
from flipper.utils.programmer_openocd import OpenOCDProgrammer
|
|
||||||
|
|
||||||
|
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):
|
programmer_result = openocd.otp_write(0x1FFF7000, filename)
|
||||||
raise Exception("Failed to flash OTP")
|
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):
|
programmer_result = openocd.otp_write(0x1FFF7010, filename)
|
||||||
raise Exception("Failed to flash OTP")
|
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):
|
programmer_result = openocd.otp_write(0x1FFF7000, filename)
|
||||||
raise Exception("Failed to flash OTP")
|
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)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user