44import pathlib
55import click
66import copy
7+ import kconfiglib
8+ import os
79
810OPT_SETTINGS = [
911 "CONFIG_ESP_ERR_TO_NAME_LOOKUP" ,
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
2630TARGET_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_" ,
5756]
5857
5958BOARD_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