ob.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #!/usr/bin/env python3
  2. import logging
  3. import argparse
  4. import subprocess
  5. import sys
  6. import os
  7. class Main:
  8. def __init__(self):
  9. # command args
  10. self.parser = argparse.ArgumentParser()
  11. self.parser.add_argument("-d", "--debug", action="store_true", help="Debug")
  12. self.subparsers = self.parser.add_subparsers(help="sub-command help")
  13. self.parser_check = self.subparsers.add_parser(
  14. "check", help="Check Option Bytes"
  15. )
  16. self.parser_check.add_argument(
  17. "--port", type=str, help="Port to connect: swd or usb1", default="swd"
  18. )
  19. self.parser_check.set_defaults(func=self.check)
  20. self.parser_set = self.subparsers.add_parser("set", help="Set Option Bytes")
  21. self.parser_set.add_argument(
  22. "--port", type=str, help="Port to connect: swd or usb1", default="swd"
  23. )
  24. self.parser_set.set_defaults(func=self.set)
  25. # logging
  26. self.logger = logging.getLogger()
  27. # OB
  28. self.ob = {}
  29. def __call__(self):
  30. self.args = self.parser.parse_args()
  31. if "func" not in self.args:
  32. self.parser.error("Choose something to do")
  33. # configure log output
  34. self.log_level = logging.DEBUG if self.args.debug else logging.INFO
  35. self.logger.setLevel(self.log_level)
  36. self.handler = logging.StreamHandler(sys.stdout)
  37. self.handler.setLevel(self.log_level)
  38. self.formatter = logging.Formatter("%(asctime)s [%(levelname)s] %(message)s")
  39. self.handler.setFormatter(self.formatter)
  40. self.logger.addHandler(self.handler)
  41. # execute requested function
  42. self.loadOB()
  43. return_code = self.args.func()
  44. if isinstance(return_code, int):
  45. return return_code
  46. else:
  47. self.logger.error(f"Forgotten return code")
  48. return 255
  49. def loadOB(self):
  50. self.logger.info(f"Loading Option Bytes data")
  51. file_path = os.path.join(os.path.dirname(sys.argv[0]), "ob.data")
  52. file = open(file_path, "r")
  53. for line in file.readlines():
  54. k, v, o = line.split(":")
  55. self.ob[k.strip()] = v.strip(), o.strip()
  56. def check(self):
  57. self.logger.info(f"Checking Option Bytes")
  58. try:
  59. output = subprocess.check_output(
  60. [
  61. "STM32_Programmer_CLI",
  62. "-q",
  63. "-c",
  64. f"port={self.args.port}",
  65. "-ob displ",
  66. ]
  67. )
  68. assert output
  69. except subprocess.CalledProcessError as e:
  70. self.logger.error(e.output.decode())
  71. self.logger.error(f"Failed to call STM32_Programmer_CLI")
  72. return 127
  73. except Exception as e:
  74. self.logger.error(f"Failed to call STM32_Programmer_CLI")
  75. self.logger.exception(e)
  76. return 126
  77. ob_correct = True
  78. for line in output.decode().split("\n"):
  79. line = line.strip()
  80. if not ":" in line:
  81. self.logger.debug(f"Skipping line: {line}")
  82. continue
  83. key, data = line.split(":", 1)
  84. key = key.strip()
  85. data = data.strip()
  86. if not key in self.ob.keys():
  87. self.logger.debug(f"Skipping key: {key}")
  88. continue
  89. self.logger.debug(f"Processing key: {key} {data}")
  90. value, comment = data.split(" ", 1)
  91. value = value.strip()
  92. comment = comment.strip()
  93. if self.ob[key][0] != value:
  94. self.logger.error(
  95. f"Invalid OB: {key} {value}, expected: {self.ob[key][0]}"
  96. )
  97. ob_correct = False
  98. if ob_correct:
  99. self.logger.info(f"OB Check OK")
  100. return 0
  101. else:
  102. self.logger.error(f"OB Check FAIL")
  103. return 255
  104. def set(self):
  105. self.logger.info(f"Setting Option Bytes")
  106. options = []
  107. for key, (value, attr) in self.ob.items():
  108. if "w" in attr:
  109. options.append(f"{key}={value}")
  110. try:
  111. output = subprocess.check_output(
  112. [
  113. "STM32_Programmer_CLI",
  114. "-q",
  115. "-c",
  116. f"port={self.args.port}",
  117. "-ob",
  118. *options,
  119. ]
  120. )
  121. assert output
  122. self.logger.info(f"Success")
  123. except subprocess.CalledProcessError as e:
  124. self.logger.error(e.output.decode())
  125. self.logger.error(f"Failed to call STM32_Programmer_CLI")
  126. return 125
  127. except Exception as e:
  128. self.logger.error(f"Failed to call STM32_Programmer_CLI")
  129. self.logger.exception(e)
  130. return 124
  131. return 0
  132. if __name__ == "__main__":
  133. return_code = Main()()
  134. exit(return_code)