14
14
15
15
import os
16
16
import contextlib
17
- import requests
18
17
import json
19
18
import subprocess
20
19
import sys
21
20
import shutil
22
21
import logging
23
- from functools import lru_cache
24
22
from typing import Optional , Dict , List , Any
25
- from os .path import join
26
23
27
24
from platformio .public import PlatformBase , to_unix_path
28
25
from platformio .proc import get_pythonexe_path
36
33
MKLITTLEFS_VERSION_400 = "4.0.0"
37
34
DEFAULT_DEBUG_SPEED = "5000"
38
35
DEFAULT_APP_OFFSET = "0x10000"
36
+
39
37
ARDUINO_ESP32_PACKAGE_URL = "https://raw.githubusercontent.com/espressif/arduino-esp32/master/package/package_esp32_index.template.json"
40
38
39
+ # MCUs that support ESP-builtin debug
40
+ ESP_BUILTIN_DEBUG_MCUS = frozenset (["esp32c3" , "esp32c5" , "esp32c6" , "esp32s3" , "esp32h2" , "esp32p4" ])
41
+
41
42
# MCU configuration
42
43
MCU_TOOLCHAIN_CONFIG = {
43
44
"xtensa" : {
@@ -96,7 +97,7 @@ def wrapper(*args, **kwargs):
96
97
return False
97
98
except Exception as e :
98
99
logger .error (f"Unexpected error in { operation_func .__name__ } : { e } " )
99
- return False
100
+ raise # Re-raise unexpected exceptions
100
101
return wrapper
101
102
102
103
@@ -123,6 +124,7 @@ def __init__(self, *args, **kwargs):
123
124
super ().__init__ (* args , ** kwargs )
124
125
self ._packages_dir = None
125
126
self ._tools_cache = {}
127
+ self ._mcu_config_cache = {}
126
128
127
129
@property
128
130
def packages_dir (self ) -> str :
@@ -167,13 +169,12 @@ def _run_idf_tools_install(self, tools_json_path: str, idf_tools_path: str) -> b
167
169
]
168
170
169
171
try :
170
- with open (os .devnull , 'w' ) as devnull :
171
- result = subprocess .run (
172
- cmd ,
173
- stdout = subprocess .DEVNULL ,
174
- stderr = subprocess .DEVNULL ,
175
- timeout = SUBPROCESS_TIMEOUT
176
- )
172
+ result = subprocess .run (
173
+ cmd ,
174
+ stdout = subprocess .DEVNULL ,
175
+ stderr = subprocess .DEVNULL ,
176
+ timeout = SUBPROCESS_TIMEOUT
177
+ )
177
178
178
179
if result .returncode != 0 :
179
180
logger .error ("idf_tools.py installation failed" )
@@ -317,21 +318,25 @@ def _configure_espidf_framework(self, frameworks: List[str], variables: Dict, bo
317
318
318
319
def _get_mcu_config (self , mcu : str ) -> Optional [Dict ]:
319
320
"""MCU configuration with optimized search"""
320
- for arch_name , config in MCU_TOOLCHAIN_CONFIG .items ():
321
+ if mcu in self ._mcu_config_cache :
322
+ return self ._mcu_config_cache [mcu ]
323
+
324
+ for _ , config in MCU_TOOLCHAIN_CONFIG .items ():
321
325
if mcu in config ["mcus" ]:
322
326
# Dynamically add ULP toolchain
323
327
result = config .copy ()
324
328
result ["ulp_toolchain" ] = ["toolchain-esp32ulp" ]
325
329
if mcu != "esp32" :
326
330
result ["ulp_toolchain" ].append ("toolchain-riscv32-esp" )
331
+ self ._mcu_config_cache [mcu ] = result
327
332
return result
328
333
return None
329
334
330
335
def _needs_debug_tools (self , variables : Dict , targets : List [str ]) -> bool :
331
336
"""Check if debug tools are needed"""
332
337
return bool (
333
338
variables .get ("build_type" ) or
334
- "debug" in "" . join ( targets ) or
339
+ "debug" in targets or
335
340
variables .get ("upload_protocol" )
336
341
)
337
342
@@ -483,7 +488,7 @@ def configure_default_packages(self, variables: Dict, targets: List[str]) -> Any
483
488
logger .info ("Package configuration completed successfully" )
484
489
485
490
except Exception as e :
486
- logger .error (f"Error in package configuration: { e } " )
491
+ logger .error (f"Error in package configuration: { type ( e ). __name__ } : { e } " )
487
492
# Don't re-raise to maintain compatibility
488
493
489
494
return super ().configure_default_packages (variables , targets )
@@ -512,9 +517,17 @@ def _add_dynamic_options(self, board):
512
517
debug = board .manifest .get ("debug" , {})
513
518
non_debug_protocols = ["esptool" , "espota" ]
514
519
supported_debug_tools = [
515
- "cmsis-dap" , "esp-prog" , "esp-bridge" , "iot-bus-jtag" , "jlink" ,
516
- "minimodule" , "olimex-arm-usb-tiny-h" , "olimex-arm-usb-ocd-h" ,
517
- "olimex-arm-usb-ocd" , "olimex-jtag-tiny" , "tumpa"
520
+ "cmsis-dap" ,
521
+ "esp-prog" ,
522
+ "esp-bridge" ,
523
+ "iot-bus-jtag" ,
524
+ "jlink" ,
525
+ "minimodule" ,
526
+ "olimex-arm-usb-tiny-h" ,
527
+ "olimex-arm-usb-ocd-h" ,
528
+ "olimex-arm-usb-ocd" ,
529
+ "olimex-jtag-tiny" ,
530
+ "tumpa"
518
531
]
519
532
520
533
# Special configuration for Kaluga board
@@ -523,7 +536,7 @@ def _add_dynamic_options(self, board):
523
536
524
537
# ESP-builtin for certain MCUs
525
538
mcu = board .get ("build.mcu" , "" )
526
- if mcu in ( "esp32c3" , "esp32c5" , "esp32c6" , "esp32s3" , "esp32h2" , "esp32p4" ) :
539
+ if mcu in ESP_BUILTIN_DEBUG_MCUS :
527
540
supported_debug_tools .append ("esp-builtin" )
528
541
529
542
upload_protocol = board .manifest .get ("upload" , {}).get ("protocol" )
@@ -595,10 +608,16 @@ def _get_openocd_interface(self, link: str, board) -> str:
595
608
596
609
def _get_debug_server_args (self , openocd_interface : str , debug : Dict ) -> List [str ]:
597
610
"""Generate debug server arguments"""
611
+ if 'openocd_target' in debug :
612
+ config_type = 'target'
613
+ config_name = debug .get ('openocd_target' )
614
+ else :
615
+ config_type = 'board'
616
+ config_name = debug .get ('openocd_board' )
598
617
return [
599
618
"-s" , "$PACKAGE_DIR/share/openocd/scripts" ,
600
619
"-f" , f"interface/{ openocd_interface } .cfg" ,
601
- "-f" , f"{ ( 'target' , debug . get ( 'openocd_target' )) if 'openocd_target' in debug else ( 'board' , debug . get ( 'openocd_board' )) } "
620
+ "-f" , f"{ config_type } / { config_name } .cfg "
602
621
]
603
622
604
623
def configure_debug_session (self , debug_config ):
0 commit comments