esptool 4.8.dev3__tar.gz → 4.8.dev4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. {esptool-4.8.dev3/esptool.egg-info → esptool-4.8.dev4}/PKG-INFO +1 -1
  2. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/base_fields.py +18 -4
  3. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/base_operations.py +52 -29
  4. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c5/mem_definition.py +1 -1
  5. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c5/operations.py +9 -2
  6. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c5beta3/operations.py +9 -2
  7. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c61/mem_definition.py +2 -1
  8. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c61/operations.py +1 -1
  9. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32h2beta1/mem_definition.py +2 -1
  10. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32p4/mem_definition.py +2 -1
  11. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/mem_definition_base.py +5 -4
  12. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/__init__.py +2 -2
  13. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/bin_image.py +29 -16
  14. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/cmds.py +96 -54
  15. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/loader.py +18 -3
  16. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32c5.py +2 -0
  17. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32h2beta1.py +3 -1
  18. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32s3.py +10 -0
  19. {esptool-4.8.dev3 → esptool-4.8.dev4/esptool.egg-info}/PKG-INFO +1 -1
  20. {esptool-4.8.dev3 → esptool-4.8.dev4}/LICENSE +0 -0
  21. {esptool-4.8.dev3 → esptool-4.8.dev4}/MANIFEST.in +0 -0
  22. {esptool-4.8.dev3 → esptool-4.8.dev4}/README.md +0 -0
  23. {esptool-4.8.dev3 → esptool-4.8.dev4}/esp_rfc2217_server.py +0 -0
  24. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/__init__.py +0 -0
  25. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/__main__.py +0 -0
  26. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/__init__.py +0 -0
  27. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/emulate_efuse_controller_base.py +0 -0
  28. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32/__init__.py +0 -0
  29. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32/emulate_efuse_controller.py +0 -0
  30. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32/fields.py +0 -0
  31. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32/mem_definition.py +0 -0
  32. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32/operations.py +0 -0
  33. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c2/__init__.py +0 -0
  34. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c2/emulate_efuse_controller.py +0 -0
  35. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c2/fields.py +0 -0
  36. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c2/mem_definition.py +0 -0
  37. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c2/operations.py +0 -0
  38. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c3/__init__.py +0 -0
  39. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c3/emulate_efuse_controller.py +0 -0
  40. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c3/fields.py +0 -0
  41. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c3/mem_definition.py +0 -0
  42. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c3/operations.py +0 -0
  43. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c5/__init__.py +0 -0
  44. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c5/emulate_efuse_controller.py +0 -0
  45. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c5/fields.py +0 -0
  46. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c5beta3/__init__.py +0 -0
  47. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c5beta3/emulate_efuse_controller.py +0 -0
  48. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c5beta3/fields.py +0 -0
  49. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c5beta3/mem_definition.py +0 -0
  50. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c6/__init__.py +0 -0
  51. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c6/emulate_efuse_controller.py +0 -0
  52. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c6/fields.py +0 -0
  53. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c6/mem_definition.py +0 -0
  54. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c6/operations.py +0 -0
  55. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c61/__init__.py +0 -0
  56. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c61/emulate_efuse_controller.py +0 -0
  57. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32c61/fields.py +0 -0
  58. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32h2/__init__.py +0 -0
  59. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32h2/emulate_efuse_controller.py +0 -0
  60. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32h2/fields.py +0 -0
  61. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32h2/mem_definition.py +0 -0
  62. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32h2/operations.py +0 -0
  63. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32h2beta1/__init__.py +0 -0
  64. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py +0 -0
  65. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32h2beta1/fields.py +0 -0
  66. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32h2beta1/operations.py +0 -0
  67. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32p4/__init__.py +0 -0
  68. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32p4/emulate_efuse_controller.py +0 -0
  69. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32p4/fields.py +0 -0
  70. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32p4/operations.py +0 -0
  71. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s2/__init__.py +0 -0
  72. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s2/emulate_efuse_controller.py +0 -0
  73. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s2/fields.py +0 -0
  74. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s2/mem_definition.py +0 -0
  75. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s2/operations.py +0 -0
  76. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s3/__init__.py +0 -0
  77. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s3/emulate_efuse_controller.py +0 -0
  78. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s3/fields.py +0 -0
  79. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s3/mem_definition.py +0 -0
  80. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s3/operations.py +0 -0
  81. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s3beta2/__init__.py +0 -0
  82. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py +0 -0
  83. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s3beta2/fields.py +0 -0
  84. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s3beta2/mem_definition.py +0 -0
  85. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/esp32s3beta2/operations.py +0 -0
  86. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse/util.py +0 -0
  87. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32.yaml +0 -0
  88. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32c2.yaml +0 -0
  89. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32c3.yaml +0 -0
  90. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32c5.yaml +0 -0
  91. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32c5beta3.yaml +0 -0
  92. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32c6.yaml +0 -0
  93. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32c61.yaml +0 -0
  94. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32h2.yaml +0 -0
  95. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32p4.yaml +0 -0
  96. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32s2.yaml +0 -0
  97. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse/efuse_defs/esp32s3.yaml +0 -0
  98. {esptool-4.8.dev3 → esptool-4.8.dev4}/espefuse.py +0 -0
  99. {esptool-4.8.dev3 → esptool-4.8.dev4}/espsecure/__init__.py +0 -0
  100. {esptool-4.8.dev3 → esptool-4.8.dev4}/espsecure/__main__.py +0 -0
  101. {esptool-4.8.dev3 → esptool-4.8.dev4}/espsecure/esp_hsm_sign/__init__.py +0 -0
  102. {esptool-4.8.dev3 → esptool-4.8.dev4}/espsecure/esp_hsm_sign/exceptions.py +0 -0
  103. {esptool-4.8.dev3 → esptool-4.8.dev4}/espsecure.py +0 -0
  104. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/__main__.py +0 -0
  105. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/config.py +0 -0
  106. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/reset.py +0 -0
  107. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/__init__.py +0 -0
  108. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32.py +0 -0
  109. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32c2.py +0 -0
  110. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32c3.py +0 -0
  111. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32c5beta3.py +0 -0
  112. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32c6.py +0 -0
  113. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32c61.py +0 -0
  114. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32c6beta.py +0 -0
  115. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32h2.py +0 -0
  116. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32h2beta2.py +0 -0
  117. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32p4.py +0 -0
  118. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32s2.py +0 -0
  119. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp32s3beta2.py +0 -0
  120. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/esp8266.py +0 -0
  121. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32.json +0 -0
  122. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32c2.json +0 -0
  123. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32c3.json +0 -0
  124. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32c5beta3.json +0 -0
  125. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32c6.json +0 -0
  126. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32c6beta.json +0 -0
  127. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32h2.json +0 -0
  128. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32h2beta1.json +0 -0
  129. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32h2beta2.json +0 -0
  130. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32p4.json +0 -0
  131. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32s2.json +0 -0
  132. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32s3.json +0 -0
  133. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_32s3beta2.json +0 -0
  134. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/targets/stub_flasher/stub_flasher_8266.json +0 -0
  135. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/uf2_writer.py +0 -0
  136. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool/util.py +0 -0
  137. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool.egg-info/SOURCES.txt +0 -0
  138. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool.egg-info/dependency_links.txt +0 -0
  139. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool.egg-info/requires.txt +0 -0
  140. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool.egg-info/top_level.txt +0 -0
  141. {esptool-4.8.dev3 → esptool-4.8.dev4}/esptool.py +0 -0
  142. {esptool-4.8.dev3 → esptool-4.8.dev4}/setup.cfg +0 -0
  143. {esptool-4.8.dev3 → esptool-4.8.dev4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: esptool
3
- Version: 4.8.dev3
3
+ Version: 4.8.dev4
4
4
  Summary: A serial utility to communicate & flash code to Espressif chips.
5
5
  Home-page: https://github.com/espressif/esptool/
6
6
  Author: Fredrik Ahlberg (themadinventor) & Angus Gratton (projectgus) & Espressif Systems
@@ -12,6 +12,7 @@ from bitstring import BitArray, BitStream, CreationError
12
12
  import esptool
13
13
 
14
14
  from . import util
15
+ from typing import List
15
16
 
16
17
 
17
18
  class CheckArgValue(object):
@@ -227,13 +228,14 @@ class EfuseBlockBase(EfuseProtectBase):
227
228
 
228
229
  return [self.parent.read_reg(offs) for offs in get_offsets(self)]
229
230
 
230
- def read(self):
231
+ def read(self, print_info=True):
231
232
  words = self.get_words()
232
233
  data = BitArray()
233
234
  for word in reversed(words):
234
235
  data.append("uint:32=%d" % word)
235
236
  self.bitarray.overwrite(data, pos=0)
236
- self.print_block(self.bitarray, "read_regs")
237
+ if print_info:
238
+ self.print_block(self.bitarray, "read_regs")
237
239
 
238
240
  def print_block(self, bit_string, comment, debug=False):
239
241
  if self.parent.debug or debug:
@@ -385,6 +387,18 @@ class EfuseBlockBase(EfuseProtectBase):
385
387
  )
386
388
  break
387
389
  if not self.fail and self.num_errors == 0:
390
+ self.read(print_info=False)
391
+ if self.wr_bitarray & self.bitarray != self.wr_bitarray:
392
+ # if the required bits are not set then we need to re-burn it again.
393
+ if burns < 2:
394
+ print(
395
+ f"\nRepeat burning BLOCK{self.id} (#{burns + 2}) because not all bits were set"
396
+ )
397
+ continue
398
+ else:
399
+ print(
400
+ f"\nAfter {burns + 1} attempts, the required data was not set to BLOCK{self.id}"
401
+ )
388
402
  break
389
403
 
390
404
  def burn(self):
@@ -441,8 +455,8 @@ class EspEfusesBase(object):
441
455
  """
442
456
 
443
457
  _esp = None
444
- blocks = []
445
- efuses = []
458
+ blocks: List[EfuseBlockBase] = []
459
+ efuses: List = []
446
460
  coding_scheme = None
447
461
  force_write_always = None
448
462
  batch_mode_cnt = 0
@@ -65,12 +65,11 @@ def add_common_commands(subparsers, efuses):
65
65
  )
66
66
  burn.add_argument(
67
67
  "name_value_pairs",
68
- help="Name of efuse register and New value pairs to burn",
68
+ help="Name of efuse field and new value pairs to burn. EFUSE_NAME: "
69
+ "[{}].".format(", ".join([e.name for e in efuses.efuses])),
69
70
  action=ActionEfuseValuePair,
70
71
  nargs="+",
71
- metavar="[EFUSE_NAME VALUE] [{} VALUE".format(
72
- " VALUE] [".join([e.name for e in efuses.efuses])
73
- ),
72
+ metavar="[EFUSE_NAME VALUE]",
74
73
  efuse_choices=[e.name for e in efuses.efuses]
75
74
  + [name for e in efuses.efuses for name in e.alt_names if name != ""],
76
75
  efuses=efuses,
@@ -183,7 +182,7 @@ def add_common_commands(subparsers, efuses):
183
182
  summary_cmd.add_argument(
184
183
  "--format",
185
184
  help="Select the summary format",
186
- choices=["summary", "json"],
185
+ choices=["summary", "json", "value_only"],
187
186
  default="summary",
188
187
  )
189
188
  summary_cmd.add_argument(
@@ -192,6 +191,11 @@ def add_common_commands(subparsers, efuses):
192
191
  type=argparse.FileType("w"),
193
192
  default=sys.stdout,
194
193
  )
194
+ summary_cmd.add_argument(
195
+ "efuses_to_show",
196
+ help="The efuses to show. If not provided, all efuses will be shown.",
197
+ nargs="*",
198
+ )
195
199
 
196
200
  execute_scripts = subparsers.add_parser(
197
201
  "execute_scripts", help="Executes scripts to burn at one time."
@@ -246,14 +250,21 @@ def add_show_sensitive_info_option(p):
246
250
 
247
251
 
248
252
  def summary(esp, efuses, args):
249
- """Print a human-readable summary of efuse contents"""
253
+ """Print a human-readable or json summary of efuse contents"""
250
254
  ROW_FORMAT = "%-50s %-50s%s = %s %s %s"
251
- human_output = args.format == "summary"
255
+ human_output = args.format in ["summary", "value_only"]
256
+ value_only = args.format == "value_only"
257
+ if value_only and len(args.efuses_to_show) != 1:
258
+ raise esptool.FatalError(
259
+ "The 'value_only' format can be used exactly for one efuse."
260
+ )
261
+ do_filtering = bool(args.efuses_to_show)
252
262
  json_efuse = {}
263
+ summary_efuse = []
253
264
  if args.file != sys.stdout:
254
265
  print("Saving efuse values to " + args.file.name)
255
- if human_output:
256
- print(
266
+ if human_output and not value_only:
267
+ summary_efuse.append(
257
268
  ROW_FORMAT.replace("-50", "-12")
258
269
  % (
259
270
  "EFUSE_NAME (Block)",
@@ -262,13 +273,12 @@ def summary(esp, efuses, args):
262
273
  "[Meaningful Value]",
263
274
  "[Readable/Writeable]",
264
275
  "(Hex Value)",
265
- ),
266
- file=args.file,
276
+ )
267
277
  )
268
- print("-" * 88, file=args.file)
278
+ summary_efuse.append("-" * 88)
269
279
  for category in sorted(set(e.category for e in efuses), key=lambda c: c.title()):
270
- if human_output:
271
- print("%s fuses:" % category.title(), file=args.file)
280
+ if human_output and not value_only:
281
+ summary_efuse.append(f"{category.title()} fuses:")
272
282
  for e in (e for e in efuses if e.category == category):
273
283
  if e.efuse_type.startswith("bytes"):
274
284
  raw = ""
@@ -297,8 +307,12 @@ def summary(esp, efuses, args):
297
307
  value = "".join(v)
298
308
  else:
299
309
  value = value.replace("0", "?")
300
- if human_output:
301
- print(
310
+ if (
311
+ human_output
312
+ and (not do_filtering or e.name in args.efuses_to_show)
313
+ and not value_only
314
+ ):
315
+ summary_efuse.append(
302
316
  ROW_FORMAT
303
317
  % (
304
318
  e.get_info(),
@@ -307,18 +321,20 @@ def summary(esp, efuses, args):
307
321
  value,
308
322
  perms,
309
323
  raw,
310
- ),
311
- file=args.file,
324
+ )
312
325
  )
313
326
  desc_len = len(e.description[50:])
314
327
  if desc_len:
315
328
  desc_len += 50
316
329
  for i in range(50, desc_len, 50):
317
- print(
318
- "%-50s %-50s" % ("", e.description[i : (50 + i)]),
319
- file=args.file,
330
+ summary_efuse.append(
331
+ f"{'':<50} {e.description[i : (50 + i)]:<50}"
320
332
  )
321
- if args.format == "json":
333
+ elif human_output and value_only and e.name in args.efuses_to_show:
334
+ summary_efuse.append(f"{value}")
335
+ elif args.format == "json" and (
336
+ not do_filtering or e.name in args.efuses_to_show
337
+ ):
322
338
  json_efuse[e.name] = {
323
339
  "name": e.name,
324
340
  "value": base_value if readable else value,
@@ -332,19 +348,26 @@ def summary(esp, efuses, args):
332
348
  "efuse_type": e.efuse_type,
333
349
  "bit_len": e.bit_len,
334
350
  }
335
- if human_output:
336
- print("", file=args.file)
337
- if human_output:
338
- print(efuses.summary(), file=args.file)
351
+ if human_output and not value_only:
352
+ # Remove empty category if efuses are filtered and there are none to show
353
+ if do_filtering and summary_efuse[-1] == f"{category.title()} fuses:":
354
+ summary_efuse.pop()
355
+ else:
356
+ summary_efuse.append("")
357
+ if human_output and not value_only:
358
+ summary_efuse.append(efuses.summary())
339
359
  warnings = efuses.get_coding_scheme_warnings()
340
360
  if warnings:
341
- print(
342
- "WARNING: Coding scheme has encoding bit error warnings", file=args.file
361
+ summary_efuse.append(
362
+ "WARNING: Coding scheme has encoding bit error warnings"
343
363
  )
364
+ if human_output:
365
+ for line in summary_efuse:
366
+ print(line, file=args.file)
344
367
  if args.file != sys.stdout:
345
368
  args.file.close()
346
369
  print("Done")
347
- if args.format == "json":
370
+ elif args.format == "json":
348
371
  json.dump(json_efuse, args.file, sort_keys=True, indent=4)
349
372
  print("")
350
373
 
@@ -20,7 +20,7 @@ class EfuseDefineRegisters(EfuseRegistersBase):
20
20
  EFUSE_MEM_SIZE = 0x01FC + 4
21
21
 
22
22
  # EFUSE registers & command/conf values
23
- DR_REG_EFUSE_BASE = 0x600B0800
23
+ DR_REG_EFUSE_BASE = 0x600B4800
24
24
  EFUSE_PGM_DATA0_REG = DR_REG_EFUSE_BASE
25
25
  EFUSE_CHECK_VALUE0_REG = DR_REG_EFUSE_BASE + 0x020
26
26
  EFUSE_CLK_REG = DR_REG_EFUSE_BASE + 0x1C8
@@ -236,14 +236,21 @@ def burn_key(esp, efuses, args, digest=None):
236
236
  block = efuses.blocks[block_num]
237
237
 
238
238
  if digest is None:
239
- data = datafile.read()
239
+ if keypurpose == "ECDSA_KEY":
240
+ sk = espsecure.load_ecdsa_signing_key(datafile)
241
+ data = sk.to_string()
242
+ if len(data) == 24:
243
+ # the private key is 24 bytes long for NIST192p, and 8 bytes of padding
244
+ data = b"\x00" * 8 + data
245
+ else:
246
+ data = datafile.read()
240
247
  else:
241
248
  data = datafile
242
249
 
243
250
  print(" - %s" % (efuse.name), end=" ")
244
251
  revers_msg = None
245
252
  if efuses[block.key_purpose_name].need_reverse(keypurpose):
246
- revers_msg = "\tReversing byte order for AES-XTS hardware peripheral"
253
+ revers_msg = f"\tReversing byte order for {keypurpose} hardware peripheral"
247
254
  data = data[::-1]
248
255
  print(
249
256
  "-> [{}]".format(
@@ -236,14 +236,21 @@ def burn_key(esp, efuses, args, digest=None):
236
236
  block = efuses.blocks[block_num]
237
237
 
238
238
  if digest is None:
239
- data = datafile.read()
239
+ if keypurpose == "ECDSA_KEY":
240
+ sk = espsecure.load_ecdsa_signing_key(datafile)
241
+ data = sk.to_string()
242
+ if len(data) == 24:
243
+ # the private key is 24 bytes long for NIST192p, and 8 bytes of padding
244
+ data = b"\x00" * 8 + data
245
+ else:
246
+ data = datafile.read()
240
247
  else:
241
248
  data = datafile
242
249
 
243
250
  print(" - %s" % (efuse.name), end=" ")
244
251
  revers_msg = None
245
252
  if efuses[block.key_purpose_name].need_reverse(keypurpose):
246
- revers_msg = "\tReversing byte order for AES-XTS hardware peripheral"
253
+ revers_msg = f"\tReversing byte order for {keypurpose} hardware peripheral"
247
254
  data = data[::-1]
248
255
  print(
249
256
  "-> [{}]".format(
@@ -5,6 +5,7 @@
5
5
  # SPDX-License-Identifier: GPL-2.0-or-later
6
6
 
7
7
  import os
8
+ from typing import List
8
9
 
9
10
  import yaml
10
11
 
@@ -119,7 +120,7 @@ class EfuseDefineFields(EfuseFieldsBase):
119
120
  # if BLK_VERSION_MINOR is 1, these efuse fields are in BLOCK2
120
121
  self.BLOCK2_CALIBRATION_EFUSES = []
121
122
 
122
- self.CALC = []
123
+ self.CALC: List = []
123
124
 
124
125
  dir_name = os.path.dirname(os.path.abspath(__file__))
125
126
  dir_name, file_name = os.path.split(dir_name)
@@ -304,7 +304,7 @@ def burn_key(esp, efuses, args, digest=None):
304
304
 
305
305
  if digest is None:
306
306
  if keypurpose == "ECDSA_KEY":
307
- sk = espsecure._load_ecdsa_signing_key(datafile)
307
+ sk = espsecure.load_ecdsa_signing_key(datafile)
308
308
  data = sk.to_string()
309
309
  if len(data) == 24:
310
310
  # the private key is 24 bytes long for NIST192p, and 8 bytes of padding
@@ -9,6 +9,7 @@ import os
9
9
  import yaml
10
10
 
11
11
  from ..mem_definition_base import EfuseBlocksBase, EfuseFieldsBase, EfuseRegistersBase
12
+ from typing import List
12
13
 
13
14
 
14
15
  class EfuseDefineRegisters(EfuseRegistersBase):
@@ -115,7 +116,7 @@ class EfuseDefineFields(EfuseFieldsBase):
115
116
  # if BLK_VERSION_MAJOR is 1, these efuse fields are in BLOCK2
116
117
  self.BLOCK2_CALIBRATION_EFUSES = []
117
118
 
118
- self.CALC = []
119
+ self.CALC: List = []
119
120
 
120
121
  dir_name = os.path.dirname(os.path.abspath(__file__))
121
122
  dir_name, file_name = os.path.split(dir_name)
@@ -13,6 +13,7 @@ from ..mem_definition_base import (
13
13
  EfuseFieldsBase,
14
14
  EfuseRegistersBase,
15
15
  )
16
+ from typing import List
16
17
 
17
18
 
18
19
  class EfuseDefineRegisters(EfuseRegistersBase):
@@ -119,7 +120,7 @@ class EfuseDefineFields(EfuseFieldsBase):
119
120
  # if BLK_VERSION_MINOR is 1, these efuse fields are in BLOCK2
120
121
  self.BLOCK2_CALIBRATION_EFUSES = []
121
122
 
122
- self.CALC = []
123
+ self.CALC: List = []
123
124
 
124
125
  dir_name = os.path.dirname(os.path.abspath(__file__))
125
126
  dir_name, file_name = os.path.split(dir_name)
@@ -5,6 +5,7 @@
5
5
  # SPDX-License-Identifier: GPL-2.0-or-later
6
6
 
7
7
  from collections import namedtuple
8
+ from typing import Optional, List
8
9
 
9
10
 
10
11
  class EfuseRegistersBase(object):
@@ -19,9 +20,9 @@ class EfuseRegistersBase(object):
19
20
 
20
21
 
21
22
  class EfuseBlocksBase(object):
22
- BLOCKS = None
23
+ BLOCKS: Optional[List] = None
23
24
  NamedtupleBlock = namedtuple(
24
- "Block",
25
+ "NamedtupleBlock",
25
26
  "name alias id rd_addr wr_addr write_disable_bit "
26
27
  "read_disable_bit len key_purpose",
27
28
  )
@@ -49,7 +50,7 @@ class Field:
49
50
  word = None
50
51
  pos = None
51
52
  bit_len = 0
52
- alt_names = []
53
+ alt_names: List[str] = []
53
54
  type = ""
54
55
  write_disable_bit = None
55
56
  read_disable_bit = None
@@ -61,7 +62,7 @@ class Field:
61
62
 
62
63
  class EfuseFieldsBase(object):
63
64
  def __init__(self, e_desc) -> None:
64
- self.ALL_EFUSES = []
65
+ self.ALL_EFUSES: List = []
65
66
 
66
67
  def set_category_and_class_type(efuse, name):
67
68
  def includes(name, names):
@@ -28,7 +28,7 @@ __all__ = [
28
28
  "write_mem",
29
29
  ]
30
30
 
31
- __version__ = "4.8.dev3"
31
+ __version__ = "4.8.dev4"
32
32
 
33
33
  import argparse
34
34
  import inspect
@@ -496,7 +496,7 @@ def main(argv=None, esp=None):
496
496
  "quantity. This will make the other segments invisible to the ROM "
497
497
  "loader. Use this argument with care because the ROM loader will load "
498
498
  "only the RAM segments although the other segments being present in "
499
- "the output.",
499
+ "the output. Implies --dont-append-digest",
500
500
  action="store_true",
501
501
  default=None,
502
502
  )
@@ -11,7 +11,7 @@ import os
11
11
  import re
12
12
  import struct
13
13
  import tempfile
14
- from typing import BinaryIO, Optional
14
+ from typing import IO, Optional
15
15
 
16
16
  from intelhex import HexRecordError, IntelHex
17
17
 
@@ -43,7 +43,7 @@ def align_file_position(f, size):
43
43
  f.seek(align, 1)
44
44
 
45
45
 
46
- def intel_hex_to_bin(file: BinaryIO, start_addr: Optional[int] = None) -> BinaryIO:
46
+ def intel_hex_to_bin(file: IO[bytes], start_addr: Optional[int] = None) -> IO[bytes]:
47
47
  """Convert IntelHex file to temp binary file with padding from start_addr
48
48
  If hex file was detected return temp bin file object; input file otherwise"""
49
49
  INTEL_HEX_MAGIC = b":"
@@ -115,10 +115,11 @@ class ImageSegment(object):
115
115
  """Wrapper class for a segment in an ESP image
116
116
  (very similar to a section in an ELFImage also)"""
117
117
 
118
- def __init__(self, addr, data, file_offs=None):
118
+ def __init__(self, addr, data, file_offs=None, flags=0):
119
119
  self.addr = addr
120
120
  self.data = data
121
121
  self.file_offs = file_offs
122
+ self.flags = flags
122
123
  self.include_in_checksum = True
123
124
  if self.addr != 0:
124
125
  self.pad_to_alignment(
@@ -167,8 +168,8 @@ class ELFSection(ImageSegment):
167
168
  """Wrapper class for a section in an ELF image, has a section
168
169
  name as well as the common properties of an ImageSegment."""
169
170
 
170
- def __init__(self, name, addr, data):
171
- super(ELFSection, self).__init__(addr, data)
171
+ def __init__(self, name, addr, data, flags):
172
+ super(ELFSection, self).__init__(addr, data, flags=flags)
172
173
  self.name = name.decode("utf-8")
173
174
 
174
175
  def __repr__(self):
@@ -178,6 +179,9 @@ class ELFSection(ImageSegment):
178
179
  class BaseFirmwareImage(object):
179
180
  SEG_HEADER_LEN = 8
180
181
  SHA256_DIGEST_LEN = 32
182
+ ELF_FLAG_WRITE = 0x1
183
+ ELF_FLAG_READ = 0x2
184
+ ELF_FLAG_EXEC = 0x4
181
185
 
182
186
  """ Base class with common firmware image functions """
183
187
 
@@ -352,6 +356,11 @@ class BaseFirmwareImage(object):
352
356
  irom_segment = self.get_irom_segment()
353
357
  return [s for s in self.segments if s != irom_segment]
354
358
 
359
+ def sort_segments(self):
360
+ if not self.segments:
361
+ return # nothing to sort
362
+ self.segments = sorted(self.segments, key=lambda s: s.addr)
363
+
355
364
  def merge_adjacent_segments(self):
356
365
  if not self.segments:
357
366
  return # nothing to merge
@@ -368,6 +377,8 @@ class BaseFirmwareImage(object):
368
377
  elem.get_memory_type(self) == next_elem.get_memory_type(self),
369
378
  elem.include_in_checksum == next_elem.include_in_checksum,
370
379
  next_elem.addr == elem.addr + len(elem.data),
380
+ next_elem.flags & self.ELF_FLAG_EXEC
381
+ == elem.flags & self.ELF_FLAG_EXEC,
371
382
  )
372
383
  ):
373
384
  # Merge any segment that ends where the next one starts,
@@ -755,8 +766,10 @@ class ESP32FirmwareImage(BaseFirmwareImage):
755
766
  self.ROM_LOADER.BOOTLOADER_FLASH_OFFSET - self.SEG_HEADER_LEN
756
767
  )
757
768
  if pad_len < align_min:
758
- print("Unable to align the segment!")
759
- break
769
+ # in case pad_len does not fit minimum alignment,
770
+ # pad it to next aligned boundary
771
+ pad_len += self.IROM_ALIGN
772
+
760
773
  pad_len -= self.ROM_LOADER.BOOTLOADER_FLASH_OFFSET
761
774
  pad_segment = ImageSegment(0, b"\x00" * pad_len, f.tell())
762
775
  self.save_segment(f, pad_segment)
@@ -1269,7 +1282,7 @@ class ELFFile(object):
1269
1282
  name_offs, sec_type, _flags, lma, sec_offs, size = struct.unpack_from(
1270
1283
  "<LLLLLL", section_header[offs:]
1271
1284
  )
1272
- return (name_offs, sec_type, lma, size, sec_offs)
1285
+ return (name_offs, sec_type, lma, size, sec_offs, _flags)
1273
1286
 
1274
1287
  all_sections = [read_section_header(offs) for offs in section_header_offsets]
1275
1288
  prog_sections = [s for s in all_sections if s[1] in ELFFile.PROG_SEC_TYPES]
@@ -1278,7 +1291,7 @@ class ELFFile(object):
1278
1291
  # search for the string table section
1279
1292
  if (shstrndx * self.LEN_SEC_HEADER) not in section_header_offsets:
1280
1293
  raise FatalError("ELF file has no STRTAB section at shstrndx %d" % shstrndx)
1281
- _, sec_type, _, sec_size, sec_offs = read_section_header(
1294
+ _, sec_type, _, sec_size, sec_offs, _ = read_section_header(
1282
1295
  shstrndx * self.LEN_SEC_HEADER
1283
1296
  )
1284
1297
  if sec_type != ELFFile.SEC_TYPE_STRTAB:
@@ -1300,14 +1313,14 @@ class ELFFile(object):
1300
1313
  return f.read(size)
1301
1314
 
1302
1315
  prog_sections = [
1303
- ELFSection(lookup_string(n_offs), lma, read_data(offs, size))
1304
- for (n_offs, _type, lma, size, offs) in prog_sections
1316
+ ELFSection(lookup_string(n_offs), lma, read_data(offs, size), flags=_flags)
1317
+ for (n_offs, _type, lma, size, offs, _flags) in prog_sections
1305
1318
  if lma != 0 and size > 0
1306
1319
  ]
1307
1320
  self.sections = prog_sections
1308
1321
  self.nobits_sections = [
1309
- ELFSection(lookup_string(n_offs), lma, b"")
1310
- for (n_offs, _type, lma, size, offs) in nobits_secitons
1322
+ ELFSection(lookup_string(n_offs), lma, b"", flags=_flags)
1323
+ for (n_offs, _type, lma, size, offs, _flags) in nobits_secitons
1311
1324
  if lma != 0 and size > 0
1312
1325
  ]
1313
1326
 
@@ -1340,7 +1353,7 @@ class ELFFile(object):
1340
1353
  _flags,
1341
1354
  _align,
1342
1355
  ) = struct.unpack_from("<LLLLLLLL", segment_header[offs:])
1343
- return (seg_type, lma, size, seg_offs)
1356
+ return (seg_type, lma, size, seg_offs, _flags)
1344
1357
 
1345
1358
  all_segments = [read_segment_header(offs) for offs in segment_header_offsets]
1346
1359
  prog_segments = [s for s in all_segments if s[0] == ELFFile.SEG_TYPE_LOAD]
@@ -1350,8 +1363,8 @@ class ELFFile(object):
1350
1363
  return f.read(size)
1351
1364
 
1352
1365
  prog_segments = [
1353
- ELFSection(b"PHDR", lma, read_data(offs, size))
1354
- for (_type, lma, size, offs) in prog_segments
1366
+ ELFSection(b"PHDR", lma, read_data(offs, size), flags=_flags)
1367
+ for (_type, lma, size, offs, _flags) in prog_segments
1355
1368
  if lma != 0 and size > 0
1356
1369
  ]
1357
1370
  self.segments = prog_segments