Skip to content

Commit feabf7b

Browse files
committed
Use kconfiglib in sdkconfig update script
1 parent e90c07e commit feabf7b

1 file changed

Lines changed: 146 additions & 46 deletions

File tree

ports/espressif/tools/update_sdkconfig.py

Lines changed: 146 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import pathlib
55
import click
66
import copy
7+
import kconfiglib
8+
import os
79

810
OPT_SETTINGS = [
911
"CONFIG_ESP_ERR_TO_NAME_LOOKUP",
@@ -21,17 +23,14 @@
2123
"CONFIG_OPTIMIZATION_ASSERTION_LEVEL",
2224
"CONFIG_OPTIMIZATION_ASSERTIONS_",
2325
"CONFIG_HAL_DEFAULT_ASSERTION_LEVEL",
26+
"CONFIG_BOOTLOADER_LOG_LEVEL",
27+
"LOG_DEFAULT_LEVEL",
2428
]
2529

2630
TARGET_SETTINGS = [
2731
"CONFIG_IDF_TARGET",
2832
"CONFIG_IDF_FIRMWARE_CHIP_ID",
2933
"CONFIG_BOOTLOADER_OFFSET_IN_FLASH",
30-
"CONFIG_ESP32_",
31-
"CONFIG_ESP32C3_",
32-
"CONFIG_ESP32S2_",
33-
"CONFIG_ESP32S3_",
34-
"CONFIG_ESP32H2_",
3534
"CONFIG_ESP_SLEEP_POWER_DOWN_FLASH",
3635
"CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE",
3736
"CONFIG_ESP_SYSTEM_MEMPROT_",
@@ -57,7 +56,6 @@
5756
]
5857

5958
BOARD_SETTINGS = [
60-
"PSRAM clock and cs IO for ESP32S3",
6159
"CONFIG_SPIRAM",
6260
"CONFIG_DEFAULT_PSRAM_",
6361
"_SPIRAM_SUPPORT",
@@ -102,6 +100,33 @@ def add_group(lines, last_group, current_group):
102100
return last_group
103101

104102

103+
def sym_default(sym):
104+
# Skip symbols that cannot be changed. Only check
105+
# non-choice symbols, as selects don't affect choice
106+
# symbols.
107+
if not sym.choice and sym.visibility <= kconfiglib.expr_value(sym.rev_dep):
108+
return True
109+
110+
# Skip symbols whose value matches their default
111+
if sym.str_value == sym._str_default():
112+
return True
113+
114+
# Skip symbols that would be selected by default in a
115+
# choice, unless the choice is optional or the symbol type
116+
# isn't bool (it might be possible to set the choice mode
117+
# to n or the symbol to m in those cases).
118+
if (
119+
sym.choice
120+
and not sym.choice.is_optional
121+
and sym.choice._selection_from_defaults() is sym
122+
and sym.orig_type is kconfiglib.BOOL
123+
and sym.tri_value == 2
124+
):
125+
return True
126+
127+
return False
128+
129+
105130
@click.command()
106131
@click.option("--debug")
107132
@click.option("--board")
@@ -122,7 +147,20 @@ def update(debug, board, update_all):
122147
elif line.startswith("CIRCUITPY_ESP_FLASH_SIZE"):
123148
flash = line.split("=")[1].strip()
124149

150+
os.environ["IDF_TARGET"] = target
151+
os.environ[
152+
"COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE"
153+
] = f"build-{board}/esp-idf/kconfigs_projbuild.in"
154+
os.environ["COMPONENT_KCONFIGS_SOURCE_FILE"] = f"build-{board}/esp-idf/kconfigs.in"
155+
156+
kconfig_path = pathlib.Path(f"build-{board}/esp-idf/kconfigs.in")
157+
158+
kconfig_path = pathlib.Path(f"esp-idf/Kconfig")
159+
kconfig = kconfiglib.Kconfig(kconfig_path)
160+
125161
input_config = pathlib.Path(f"build-{board}/esp-idf/sdkconfig")
162+
kconfig.load_config(input_config)
163+
126164
default_config = pathlib.Path("esp-idf-config/sdkconfig.defaults")
127165
if debug:
128166
opt_config = pathlib.Path("esp-idf-config/sdkconfig-debug.defaults")
@@ -133,11 +171,9 @@ def update(debug, board, update_all):
133171
ble_config = pathlib.Path(f"esp-idf-config/sdkconfig-ble.defaults")
134172
board_config = pathlib.Path(f"boards/{board}/sdkconfig")
135173

136-
defaults = default_config.read_text().split("\n")
137-
defaults.extend(opt_config.read_text().split("\n"))
138-
defaults.extend(flash_config.read_text().split("\n"))
139-
defaults.extend(target_config.read_text().split("\n"))
140-
defaults.extend(ble_config.read_text().split("\n"))
174+
cp_kconfig_defaults = kconfiglib.Kconfig(kconfig_path)
175+
for default_file in (default_config, opt_config, flash_config, target_config, ble_config):
176+
cp_kconfig_defaults.load_config(default_file, replace=False)
141177

142178
board_settings = []
143179
last_board_group = None
@@ -151,43 +187,107 @@ def update(debug, board, update_all):
151187
last_ble_group = None
152188
default_settings = []
153189
last_default_group = None
190+
154191
current_group = []
155-
for line in input_config.read_text().split("\n"):
156-
# Normalize the deprecated section labels.
157-
if line == "# End of deprecated options":
158-
line = "# end of Deprecated options for backward compatibility"
159-
if (
160-
line.startswith("# ")
161-
and "CONFIG_" not in line
162-
and "DO NOT EDIT" not in line
163-
and "Project Configuration" not in line
164-
and len(line) > 3
165-
):
166-
if line.startswith("# end of"):
167-
current_group.pop()
192+
193+
for sym in kconfig.unique_defined_syms:
194+
sym._visited = False
195+
196+
# This merges the normal `write_config`, `write_min_config` and CP settings to split into
197+
# different files.
198+
pending_nodes = [kconfig.top_node]
199+
i = 0
200+
while pending_nodes:
201+
node = pending_nodes.pop()
202+
if node is None:
203+
current_group.pop()
204+
continue
205+
206+
if node.item is kconfiglib.MENU:
207+
if node.prompt:
208+
print(" " * len(current_group), i, node.prompt[0])
209+
i += 1
210+
if node.next:
211+
pending_nodes.append(node.next)
212+
213+
# if i > 300:
214+
# break
215+
216+
# We have a configuration item.
217+
item = node.item
218+
if isinstance(item, kconfiglib.Symbol):
219+
if item._visited:
220+
continue
221+
item._visited = True
222+
223+
config_string = item.config_string.strip()
224+
if not config_string:
225+
continue
226+
227+
if node.list:
228+
pending_nodes.append(node.list)
229+
230+
matches_cp_default = cp_kconfig_defaults.syms[item.name].str_value == item.str_value
231+
matches_esp_default = sym_default(item)
232+
233+
if not matches_esp_default:
234+
print(" " * len(current_group), i, config_string.strip())
235+
236+
target_reference = False
237+
for referenced in item.referenced:
238+
if referenced.name.startswith("IDF_TARGET"):
239+
# print(item.name, "references", referenced.name)
240+
target_reference = True
241+
break
242+
243+
if (not update_all and not matches_cp_default) or (
244+
update_all
245+
and matches_group(config_string, BOARD_SETTINGS)
246+
and not matches_esp_default
247+
):
248+
print(" " * (len(current_group) + 1), "board")
249+
last_board_group = add_group(board_settings, last_board_group, current_group)
250+
board_settings.append(config_string)
251+
elif update_all and not matches_esp_default:
252+
if matches_group(config_string, OPT_SETTINGS):
253+
print(" " * (len(current_group) + 1), "opt")
254+
last_opt_group = add_group(opt_settings, last_opt_group, current_group)
255+
opt_settings.append(config_string)
256+
elif matches_group(config_string, FLASH_SETTINGS):
257+
print(" " * (len(current_group) + 1), "flash")
258+
last_flash_group = add_group(flash_settings, last_flash_group, current_group)
259+
flash_settings.append(config_string)
260+
elif target_reference or matches_group(config_string, TARGET_SETTINGS):
261+
print(" " * (len(current_group) + 1), "target")
262+
last_target_group = add_group(
263+
target_settings, last_target_group, current_group
264+
)
265+
target_settings.append(config_string)
266+
elif matches_group(config_string, BLE_SETTINGS):
267+
print(" " * (len(current_group) + 1), "ble")
268+
last_ble_group = add_group(ble_settings, last_ble_group, current_group)
269+
ble_settings.append(config_string)
270+
else:
271+
print(" " * (len(current_group) + 1), "all")
272+
last_default_group = add_group(
273+
default_settings, last_default_group, current_group
274+
)
275+
default_settings.append(config_string)
276+
277+
elif kconfiglib.expr_value(node.dep):
278+
if item is kconfiglib.COMMENT:
279+
print("comment", repr(item))
280+
elif item is kconfiglib.MENU:
281+
# This menu isn't visible so skip to the next node.
282+
if kconfiglib.expr_value(node.visibility) and node.list:
283+
current_group.append(node.prompt[0])
284+
pending_nodes.append(None)
285+
pending_nodes.append(node.list)
286+
elif isinstance(item, kconfiglib.Choice):
287+
# Choices are made up of individual symbols that we need to check.
288+
pending_nodes.append(node.list)
168289
else:
169-
current_group.append(line[2:])
170-
elif (not update_all and line not in defaults) or (
171-
update_all and matches_group(line, BOARD_SETTINGS)
172-
):
173-
last_board_group = add_group(board_settings, last_board_group, current_group)
174-
board_settings.append(line)
175-
elif update_all:
176-
if matches_group(line, OPT_SETTINGS):
177-
last_opt_group = add_group(opt_settings, last_opt_group, current_group)
178-
opt_settings.append(line)
179-
elif matches_group(line, FLASH_SETTINGS):
180-
last_flash_group = add_group(flash_settings, last_flash_group, current_group)
181-
flash_settings.append(line)
182-
elif matches_group(line, TARGET_SETTINGS):
183-
last_target_group = add_group(target_settings, last_target_group, current_group)
184-
target_settings.append(line)
185-
elif matches_group(line, BLE_SETTINGS):
186-
last_ble_group = add_group(ble_settings, last_ble_group, current_group)
187-
ble_settings.append(line)
188-
elif "CONFIG_" in line:
189-
last_default_group = add_group(default_settings, last_default_group, current_group)
190-
default_settings.append(line)
290+
print("unknown", repr(item))
191291

192292
add_group(board_settings, last_board_group, current_group)
193293
add_group(opt_settings, last_opt_group, current_group)

0 commit comments

Comments
 (0)