fbuild 1.2.8__py3-none-any.whl
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.
- fbuild/__init__.py +390 -0
- fbuild/assets/example.txt +1 -0
- fbuild/build/__init__.py +117 -0
- fbuild/build/archive_creator.py +186 -0
- fbuild/build/binary_generator.py +444 -0
- fbuild/build/build_component_factory.py +131 -0
- fbuild/build/build_info_generator.py +624 -0
- fbuild/build/build_state.py +325 -0
- fbuild/build/build_utils.py +93 -0
- fbuild/build/compilation_executor.py +422 -0
- fbuild/build/compiler.py +165 -0
- fbuild/build/compiler_avr.py +574 -0
- fbuild/build/configurable_compiler.py +664 -0
- fbuild/build/configurable_linker.py +637 -0
- fbuild/build/flag_builder.py +214 -0
- fbuild/build/library_dependency_processor.py +185 -0
- fbuild/build/linker.py +708 -0
- fbuild/build/orchestrator.py +67 -0
- fbuild/build/orchestrator_avr.py +651 -0
- fbuild/build/orchestrator_esp32.py +878 -0
- fbuild/build/orchestrator_rp2040.py +719 -0
- fbuild/build/orchestrator_stm32.py +696 -0
- fbuild/build/orchestrator_teensy.py +580 -0
- fbuild/build/source_compilation_orchestrator.py +218 -0
- fbuild/build/source_scanner.py +516 -0
- fbuild/cli.py +717 -0
- fbuild/cli_utils.py +314 -0
- fbuild/config/__init__.py +16 -0
- fbuild/config/board_config.py +542 -0
- fbuild/config/board_loader.py +92 -0
- fbuild/config/ini_parser.py +369 -0
- fbuild/config/mcu_specs.py +88 -0
- fbuild/daemon/__init__.py +42 -0
- fbuild/daemon/async_client.py +531 -0
- fbuild/daemon/client.py +1505 -0
- fbuild/daemon/compilation_queue.py +293 -0
- fbuild/daemon/configuration_lock.py +865 -0
- fbuild/daemon/daemon.py +585 -0
- fbuild/daemon/daemon_context.py +293 -0
- fbuild/daemon/error_collector.py +263 -0
- fbuild/daemon/file_cache.py +332 -0
- fbuild/daemon/firmware_ledger.py +546 -0
- fbuild/daemon/lock_manager.py +508 -0
- fbuild/daemon/logging_utils.py +149 -0
- fbuild/daemon/messages.py +957 -0
- fbuild/daemon/operation_registry.py +288 -0
- fbuild/daemon/port_state_manager.py +249 -0
- fbuild/daemon/process_tracker.py +366 -0
- fbuild/daemon/processors/__init__.py +18 -0
- fbuild/daemon/processors/build_processor.py +248 -0
- fbuild/daemon/processors/deploy_processor.py +664 -0
- fbuild/daemon/processors/install_deps_processor.py +431 -0
- fbuild/daemon/processors/locking_processor.py +777 -0
- fbuild/daemon/processors/monitor_processor.py +285 -0
- fbuild/daemon/request_processor.py +457 -0
- fbuild/daemon/shared_serial.py +819 -0
- fbuild/daemon/status_manager.py +238 -0
- fbuild/daemon/subprocess_manager.py +316 -0
- fbuild/deploy/__init__.py +21 -0
- fbuild/deploy/deployer.py +67 -0
- fbuild/deploy/deployer_esp32.py +310 -0
- fbuild/deploy/docker_utils.py +315 -0
- fbuild/deploy/monitor.py +519 -0
- fbuild/deploy/qemu_runner.py +603 -0
- fbuild/interrupt_utils.py +34 -0
- fbuild/ledger/__init__.py +52 -0
- fbuild/ledger/board_ledger.py +560 -0
- fbuild/output.py +352 -0
- fbuild/packages/__init__.py +66 -0
- fbuild/packages/archive_utils.py +1098 -0
- fbuild/packages/arduino_core.py +412 -0
- fbuild/packages/cache.py +256 -0
- fbuild/packages/concurrent_manager.py +510 -0
- fbuild/packages/downloader.py +518 -0
- fbuild/packages/fingerprint.py +423 -0
- fbuild/packages/framework_esp32.py +538 -0
- fbuild/packages/framework_rp2040.py +349 -0
- fbuild/packages/framework_stm32.py +459 -0
- fbuild/packages/framework_teensy.py +346 -0
- fbuild/packages/github_utils.py +96 -0
- fbuild/packages/header_trampoline_cache.py +394 -0
- fbuild/packages/library_compiler.py +203 -0
- fbuild/packages/library_manager.py +549 -0
- fbuild/packages/library_manager_esp32.py +725 -0
- fbuild/packages/package.py +163 -0
- fbuild/packages/platform_esp32.py +383 -0
- fbuild/packages/platform_rp2040.py +400 -0
- fbuild/packages/platform_stm32.py +581 -0
- fbuild/packages/platform_teensy.py +312 -0
- fbuild/packages/platform_utils.py +131 -0
- fbuild/packages/platformio_registry.py +369 -0
- fbuild/packages/sdk_utils.py +231 -0
- fbuild/packages/toolchain.py +436 -0
- fbuild/packages/toolchain_binaries.py +196 -0
- fbuild/packages/toolchain_esp32.py +489 -0
- fbuild/packages/toolchain_metadata.py +185 -0
- fbuild/packages/toolchain_rp2040.py +436 -0
- fbuild/packages/toolchain_stm32.py +417 -0
- fbuild/packages/toolchain_teensy.py +404 -0
- fbuild/platform_configs/esp32.json +150 -0
- fbuild/platform_configs/esp32c2.json +144 -0
- fbuild/platform_configs/esp32c3.json +143 -0
- fbuild/platform_configs/esp32c5.json +151 -0
- fbuild/platform_configs/esp32c6.json +151 -0
- fbuild/platform_configs/esp32p4.json +149 -0
- fbuild/platform_configs/esp32s3.json +151 -0
- fbuild/platform_configs/imxrt1062.json +56 -0
- fbuild/platform_configs/rp2040.json +70 -0
- fbuild/platform_configs/rp2350.json +76 -0
- fbuild/platform_configs/stm32f1.json +59 -0
- fbuild/platform_configs/stm32f4.json +63 -0
- fbuild/py.typed +0 -0
- fbuild-1.2.8.dist-info/METADATA +468 -0
- fbuild-1.2.8.dist-info/RECORD +121 -0
- fbuild-1.2.8.dist-info/WHEEL +5 -0
- fbuild-1.2.8.dist-info/entry_points.txt +5 -0
- fbuild-1.2.8.dist-info/licenses/LICENSE +21 -0
- fbuild-1.2.8.dist-info/top_level.txt +2 -0
- fbuild_lint/__init__.py +0 -0
- fbuild_lint/ruff_plugins/__init__.py +0 -0
- fbuild_lint/ruff_plugins/keyboard_interrupt_checker.py +158 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
"""STM32 Framework Management.
|
|
2
|
+
|
|
3
|
+
This module handles downloading, extracting, and managing the STM32duino Arduino framework
|
|
4
|
+
needed for STM32 Arduino builds.
|
|
5
|
+
|
|
6
|
+
Framework Download Process:
|
|
7
|
+
1. Download Arduino_Core_STM32 from GitHub (stm32duino/Arduino_Core_STM32)
|
|
8
|
+
2. Extract to cache directory
|
|
9
|
+
3. Provide access to cores, variants, and libraries
|
|
10
|
+
|
|
11
|
+
Framework Structure (after extraction):
|
|
12
|
+
cores/
|
|
13
|
+
└── arduino/ # Arduino core for STM32
|
|
14
|
+
├── Arduino.h
|
|
15
|
+
├── main.cpp
|
|
16
|
+
├── wiring.c
|
|
17
|
+
└── ...
|
|
18
|
+
variants/
|
|
19
|
+
├── STM32F1xx/ # STM32F1 variants
|
|
20
|
+
├── STM32F4xx/ # STM32F4 variants
|
|
21
|
+
└── ...
|
|
22
|
+
|
|
23
|
+
Supported MCU Families:
|
|
24
|
+
- STM32F0, STM32F1, STM32F2, STM32F3, STM32F4, STM32F7
|
|
25
|
+
- STM32G0, STM32G4
|
|
26
|
+
- STM32H7
|
|
27
|
+
- STM32L0, STM32L1, STM32L4, STM32L5
|
|
28
|
+
- STM32U5
|
|
29
|
+
- STM32WB, STM32WL
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
from typing import Any, Dict, List, Optional
|
|
34
|
+
|
|
35
|
+
from .cache import Cache
|
|
36
|
+
from .downloader import DownloadError, ExtractionError, PackageDownloader
|
|
37
|
+
from .package import IFramework, PackageError
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class FrameworkErrorSTM32(PackageError):
|
|
41
|
+
"""Raised when STM32 framework operations fail."""
|
|
42
|
+
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class FrameworkSTM32(IFramework):
|
|
47
|
+
"""Manages STM32 framework download, extraction, and access.
|
|
48
|
+
|
|
49
|
+
This class handles the stm32duino Arduino_Core_STM32 framework which includes:
|
|
50
|
+
- Arduino core for STM32 (cores/arduino/)
|
|
51
|
+
- Board variants (variants/)
|
|
52
|
+
- Built-in libraries
|
|
53
|
+
- CMSIS and HAL drivers
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
# STM32duino repository URL
|
|
57
|
+
FRAMEWORK_REPO_URL = "https://github.com/stm32duino/Arduino_Core_STM32"
|
|
58
|
+
# Using tagged release for stability
|
|
59
|
+
FRAMEWORK_VERSION = "2.12.0"
|
|
60
|
+
FRAMEWORK_ARCHIVE_URL = f"https://github.com/stm32duino/Arduino_Core_STM32/archive/refs/tags/{FRAMEWORK_VERSION}.zip"
|
|
61
|
+
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
cache: Cache,
|
|
65
|
+
show_progress: bool = True,
|
|
66
|
+
):
|
|
67
|
+
"""Initialize STM32 framework manager.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
cache: Cache manager instance
|
|
71
|
+
show_progress: Whether to show download/extraction progress
|
|
72
|
+
"""
|
|
73
|
+
self.cache = cache
|
|
74
|
+
self.show_progress = show_progress
|
|
75
|
+
self.downloader = PackageDownloader()
|
|
76
|
+
|
|
77
|
+
# Use tagged version
|
|
78
|
+
self.version = self.FRAMEWORK_VERSION
|
|
79
|
+
self.framework_url = self.FRAMEWORK_ARCHIVE_URL
|
|
80
|
+
|
|
81
|
+
# Get framework path from cache
|
|
82
|
+
self.framework_path = cache.get_platform_path(self.framework_url, self.version)
|
|
83
|
+
|
|
84
|
+
def ensure_framework(self) -> Path:
|
|
85
|
+
"""Ensure framework is downloaded and extracted.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
Path to the extracted framework directory
|
|
89
|
+
|
|
90
|
+
Raises:
|
|
91
|
+
FrameworkErrorSTM32: If download or extraction fails
|
|
92
|
+
"""
|
|
93
|
+
if self.is_installed():
|
|
94
|
+
if self.show_progress:
|
|
95
|
+
print(f"Using cached Arduino_Core_STM32 {self.version}")
|
|
96
|
+
return self.framework_path
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
if self.show_progress:
|
|
100
|
+
print(f"Downloading Arduino_Core_STM32 {self.version}...")
|
|
101
|
+
|
|
102
|
+
# Download and extract framework package
|
|
103
|
+
self.cache.ensure_directories()
|
|
104
|
+
|
|
105
|
+
# Use downloader to handle download and extraction
|
|
106
|
+
archive_name = f"Arduino_Core_STM32-{self.version}.zip"
|
|
107
|
+
archive_path = self.framework_path.parent / archive_name
|
|
108
|
+
|
|
109
|
+
# Download if not cached
|
|
110
|
+
if not archive_path.exists():
|
|
111
|
+
archive_path.parent.mkdir(parents=True, exist_ok=True)
|
|
112
|
+
self.downloader.download(self.framework_url, archive_path, show_progress=self.show_progress)
|
|
113
|
+
else:
|
|
114
|
+
if self.show_progress:
|
|
115
|
+
print("Using cached Arduino_Core_STM32 archive")
|
|
116
|
+
|
|
117
|
+
# Extract to framework directory
|
|
118
|
+
if self.show_progress:
|
|
119
|
+
print("Extracting Arduino_Core_STM32...")
|
|
120
|
+
|
|
121
|
+
# Create temp extraction directory
|
|
122
|
+
temp_extract = self.framework_path.parent / "temp_extract"
|
|
123
|
+
temp_extract.mkdir(parents=True, exist_ok=True)
|
|
124
|
+
|
|
125
|
+
self.downloader.extract_archive(archive_path, temp_extract, show_progress=self.show_progress)
|
|
126
|
+
|
|
127
|
+
# Find the Arduino_Core_STM32 directory in the extracted content
|
|
128
|
+
# Usually it's a subdirectory like "Arduino_Core_STM32-2.12.0/"
|
|
129
|
+
extracted_dirs = list(temp_extract.glob("Arduino_Core_STM32-*"))
|
|
130
|
+
if not extracted_dirs:
|
|
131
|
+
# Maybe it extracted directly
|
|
132
|
+
extracted_dirs = [temp_extract]
|
|
133
|
+
|
|
134
|
+
source_dir = extracted_dirs[0]
|
|
135
|
+
|
|
136
|
+
# Move to final location
|
|
137
|
+
if self.framework_path.exists():
|
|
138
|
+
import shutil
|
|
139
|
+
|
|
140
|
+
shutil.rmtree(self.framework_path)
|
|
141
|
+
|
|
142
|
+
source_dir.rename(self.framework_path)
|
|
143
|
+
|
|
144
|
+
# Clean up temp directory
|
|
145
|
+
if temp_extract.exists() and temp_extract != self.framework_path:
|
|
146
|
+
import shutil
|
|
147
|
+
|
|
148
|
+
shutil.rmtree(temp_extract, ignore_errors=True)
|
|
149
|
+
|
|
150
|
+
if self.show_progress:
|
|
151
|
+
print(f"Arduino_Core_STM32 installed to {self.framework_path}")
|
|
152
|
+
|
|
153
|
+
return self.framework_path
|
|
154
|
+
|
|
155
|
+
except (DownloadError, ExtractionError) as e:
|
|
156
|
+
raise FrameworkErrorSTM32(f"Failed to install Arduino_Core_STM32: {e}")
|
|
157
|
+
except KeyboardInterrupt as ke:
|
|
158
|
+
from fbuild.interrupt_utils import handle_keyboard_interrupt_properly
|
|
159
|
+
|
|
160
|
+
handle_keyboard_interrupt_properly(ke)
|
|
161
|
+
raise # Never reached, but satisfies type checker
|
|
162
|
+
except Exception as e:
|
|
163
|
+
raise FrameworkErrorSTM32(f"Unexpected error installing framework: {e}")
|
|
164
|
+
|
|
165
|
+
def is_installed(self) -> bool:
|
|
166
|
+
"""Check if framework is already installed.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
True if framework directory exists with key files
|
|
170
|
+
"""
|
|
171
|
+
if not self.framework_path.exists():
|
|
172
|
+
return False
|
|
173
|
+
|
|
174
|
+
# Verify arduino core directory exists
|
|
175
|
+
arduino_path = self.framework_path / "cores" / "arduino"
|
|
176
|
+
if not arduino_path.exists():
|
|
177
|
+
return False
|
|
178
|
+
|
|
179
|
+
# Verify essential files exist
|
|
180
|
+
required_files = [
|
|
181
|
+
arduino_path / "Arduino.h",
|
|
182
|
+
arduino_path / "main.cpp",
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
return all(f.exists() for f in required_files)
|
|
186
|
+
|
|
187
|
+
def get_core_dir(self, core_name: str = "arduino") -> Path:
|
|
188
|
+
"""Get path to specific core directory.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
core_name: Core name (default: "arduino")
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
Path to the core directory
|
|
195
|
+
|
|
196
|
+
Raises:
|
|
197
|
+
FrameworkErrorSTM32: If core directory doesn't exist
|
|
198
|
+
"""
|
|
199
|
+
core_path = self.framework_path / "cores" / core_name
|
|
200
|
+
if not core_path.exists():
|
|
201
|
+
raise FrameworkErrorSTM32(f"Core '{core_name}' not found at {core_path}")
|
|
202
|
+
return core_path
|
|
203
|
+
|
|
204
|
+
def get_core_sources(self, core_name: str = "arduino") -> List[Path]:
|
|
205
|
+
"""Get all source files in a core.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
core_name: Core name (default: "arduino")
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
List of .c and .cpp source file paths
|
|
212
|
+
"""
|
|
213
|
+
core_dir = self.get_core_dir(core_name)
|
|
214
|
+
sources: List[Path] = []
|
|
215
|
+
|
|
216
|
+
# Get all .c and .cpp files in the core directory (recursively)
|
|
217
|
+
sources.extend(core_dir.rglob("*.c"))
|
|
218
|
+
sources.extend(core_dir.rglob("*.cpp"))
|
|
219
|
+
|
|
220
|
+
# Remove duplicates and sort
|
|
221
|
+
return sorted(set(sources))
|
|
222
|
+
|
|
223
|
+
def get_core_includes(self, core_name: str = "arduino") -> List[Path]:
|
|
224
|
+
"""Get include directories for a core.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
core_name: Core name (default: "arduino")
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
List of include directory paths
|
|
231
|
+
"""
|
|
232
|
+
core_dir = self.get_core_dir(core_name)
|
|
233
|
+
includes = [core_dir]
|
|
234
|
+
|
|
235
|
+
# Add api directory if it exists
|
|
236
|
+
api_dir = core_dir / "api"
|
|
237
|
+
if api_dir.exists():
|
|
238
|
+
includes.append(api_dir)
|
|
239
|
+
|
|
240
|
+
# Add stm32 directory if it exists
|
|
241
|
+
stm32_dir = core_dir / "stm32"
|
|
242
|
+
if stm32_dir.exists():
|
|
243
|
+
includes.append(stm32_dir)
|
|
244
|
+
|
|
245
|
+
# CRITICAL: Add SrcWrapper includes (clock.h, interrupt.h, PinNames.h, etc.)
|
|
246
|
+
srcwrapper_inc = self.framework_path / "libraries" / "SrcWrapper" / "inc"
|
|
247
|
+
if srcwrapper_inc.exists():
|
|
248
|
+
includes.append(srcwrapper_inc)
|
|
249
|
+
|
|
250
|
+
return includes
|
|
251
|
+
|
|
252
|
+
def get_stm32_system_includes(self, mcu_family: str) -> List[Path]:
|
|
253
|
+
"""Get STM32 system include directories for CMSIS and HAL.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
mcu_family: MCU family name (e.g., "STM32F4xx", "STM32F1xx")
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
List of system include directory paths
|
|
260
|
+
"""
|
|
261
|
+
includes = []
|
|
262
|
+
|
|
263
|
+
system_dir = self.framework_path / "system"
|
|
264
|
+
if not system_dir.exists():
|
|
265
|
+
return includes
|
|
266
|
+
|
|
267
|
+
# CMSIS Core includes
|
|
268
|
+
cmsis_core = system_dir / "Drivers" / "CMSIS" / "Core" / "Include"
|
|
269
|
+
if cmsis_core.exists():
|
|
270
|
+
includes.append(cmsis_core)
|
|
271
|
+
|
|
272
|
+
# CMSIS Device includes for specific MCU family
|
|
273
|
+
cmsis_device = system_dir / "Drivers" / "CMSIS" / "Device" / "ST" / mcu_family / "Include"
|
|
274
|
+
if cmsis_device.exists():
|
|
275
|
+
includes.append(cmsis_device)
|
|
276
|
+
|
|
277
|
+
# HAL Driver includes for specific MCU family
|
|
278
|
+
hal_driver = system_dir / "Drivers" / f"{mcu_family}_HAL_Driver" / "Inc"
|
|
279
|
+
if hal_driver.exists():
|
|
280
|
+
includes.append(hal_driver)
|
|
281
|
+
|
|
282
|
+
# Legacy HAL includes
|
|
283
|
+
hal_legacy = system_dir / "Drivers" / f"{mcu_family}_HAL_Driver" / "Inc" / "Legacy"
|
|
284
|
+
if hal_legacy.exists():
|
|
285
|
+
includes.append(hal_legacy)
|
|
286
|
+
|
|
287
|
+
# LL (Low-Layer) driver includes (same as HAL path)
|
|
288
|
+
# Already included above
|
|
289
|
+
|
|
290
|
+
# System directory itself
|
|
291
|
+
includes.append(system_dir)
|
|
292
|
+
|
|
293
|
+
return includes
|
|
294
|
+
|
|
295
|
+
def get_variant_dir(self, variant: str) -> Optional[Path]:
|
|
296
|
+
"""Get variant directory for a specific board.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
variant: Variant identifier (e.g., "STM32F4xx/F446R(C-E)T")
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
Path to variant directory or None if not found
|
|
303
|
+
"""
|
|
304
|
+
variants_dir = self.framework_path / "variants"
|
|
305
|
+
variant_path = variants_dir / variant
|
|
306
|
+
|
|
307
|
+
return variant_path if variant_path.exists() else None
|
|
308
|
+
|
|
309
|
+
def get_system_dir(self) -> Path:
|
|
310
|
+
"""Get path to system directory containing CMSIS and HAL.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
Path to system directory
|
|
314
|
+
|
|
315
|
+
Raises:
|
|
316
|
+
FrameworkErrorSTM32: If system directory doesn't exist
|
|
317
|
+
"""
|
|
318
|
+
system_dir = self.framework_path / "system"
|
|
319
|
+
if not system_dir.exists():
|
|
320
|
+
raise FrameworkErrorSTM32(f"System directory not found at {system_dir}")
|
|
321
|
+
return system_dir
|
|
322
|
+
|
|
323
|
+
def get_cmsis_dir(self) -> Optional[Path]:
|
|
324
|
+
"""Get path to CMSIS directory.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
Path to CMSIS directory or None if not found
|
|
328
|
+
"""
|
|
329
|
+
cmsis_dir = self.framework_path / "system" / "Drivers" / "CMSIS"
|
|
330
|
+
return cmsis_dir if cmsis_dir.exists() else None
|
|
331
|
+
|
|
332
|
+
def get_hal_dir(self, mcu_family: str) -> Optional[Path]:
|
|
333
|
+
"""Get path to HAL drivers for a specific MCU family.
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
mcu_family: MCU family name (e.g., "STM32F4xx")
|
|
337
|
+
|
|
338
|
+
Returns:
|
|
339
|
+
Path to HAL directory or None if not found
|
|
340
|
+
"""
|
|
341
|
+
hal_dir = self.framework_path / "system" / "Drivers" / f"{mcu_family}_HAL_Driver"
|
|
342
|
+
return hal_dir if hal_dir.exists() else None
|
|
343
|
+
|
|
344
|
+
def list_cores(self) -> List[str]:
|
|
345
|
+
"""List all available cores.
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
List of core names
|
|
349
|
+
"""
|
|
350
|
+
cores_dir = self.framework_path / "cores"
|
|
351
|
+
if not cores_dir.exists():
|
|
352
|
+
return []
|
|
353
|
+
|
|
354
|
+
return [d.name for d in cores_dir.iterdir() if d.is_dir()]
|
|
355
|
+
|
|
356
|
+
def list_variants(self) -> List[str]:
|
|
357
|
+
"""List all available variants.
|
|
358
|
+
|
|
359
|
+
Returns:
|
|
360
|
+
List of variant identifiers
|
|
361
|
+
"""
|
|
362
|
+
variants_dir = self.framework_path / "variants"
|
|
363
|
+
if not variants_dir.exists():
|
|
364
|
+
return []
|
|
365
|
+
|
|
366
|
+
variants = []
|
|
367
|
+
# Variants are organized by MCU family
|
|
368
|
+
for family_dir in variants_dir.iterdir():
|
|
369
|
+
if family_dir.is_dir():
|
|
370
|
+
for variant_dir in family_dir.iterdir():
|
|
371
|
+
if variant_dir.is_dir():
|
|
372
|
+
variants.append(f"{family_dir.name}/{variant_dir.name}")
|
|
373
|
+
|
|
374
|
+
return sorted(variants)
|
|
375
|
+
|
|
376
|
+
def get_framework_info(self) -> Dict[str, Any]:
|
|
377
|
+
"""Get information about the installed framework.
|
|
378
|
+
|
|
379
|
+
Returns:
|
|
380
|
+
Dictionary with framework information
|
|
381
|
+
"""
|
|
382
|
+
info = {
|
|
383
|
+
"version": self.version,
|
|
384
|
+
"path": str(self.framework_path),
|
|
385
|
+
"url": self.framework_url,
|
|
386
|
+
"installed": self.is_installed(),
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if self.is_installed():
|
|
390
|
+
info["available_cores"] = self.list_cores()
|
|
391
|
+
arduino_dir = self.framework_path / "cores" / "arduino"
|
|
392
|
+
if arduino_dir.exists():
|
|
393
|
+
info["arduino_path"] = str(arduino_dir)
|
|
394
|
+
info["arduino_sources"] = len(self.get_core_sources("arduino"))
|
|
395
|
+
|
|
396
|
+
return info
|
|
397
|
+
|
|
398
|
+
# Implement IFramework interface methods
|
|
399
|
+
def get_cores_dir(self) -> Path:
|
|
400
|
+
"""Get path to cores directory.
|
|
401
|
+
|
|
402
|
+
Returns:
|
|
403
|
+
Path to cores directory containing Arduino core implementation
|
|
404
|
+
|
|
405
|
+
Raises:
|
|
406
|
+
FrameworkErrorSTM32: If cores directory doesn't exist
|
|
407
|
+
"""
|
|
408
|
+
cores_dir = self.framework_path / "cores"
|
|
409
|
+
if not cores_dir.exists():
|
|
410
|
+
raise FrameworkErrorSTM32(f"Cores directory not found at {cores_dir}")
|
|
411
|
+
return cores_dir
|
|
412
|
+
|
|
413
|
+
def get_variants_dir(self) -> Path:
|
|
414
|
+
"""Get path to variants directory.
|
|
415
|
+
|
|
416
|
+
Returns:
|
|
417
|
+
Path to variants directory
|
|
418
|
+
|
|
419
|
+
Raises:
|
|
420
|
+
FrameworkErrorSTM32: If variants directory doesn't exist
|
|
421
|
+
"""
|
|
422
|
+
variants_dir = self.framework_path / "variants"
|
|
423
|
+
if not variants_dir.exists():
|
|
424
|
+
raise FrameworkErrorSTM32(f"Variants directory not found at {variants_dir}")
|
|
425
|
+
return variants_dir
|
|
426
|
+
|
|
427
|
+
def get_libraries_dir(self) -> Path:
|
|
428
|
+
"""Get path to built-in libraries directory.
|
|
429
|
+
|
|
430
|
+
Returns:
|
|
431
|
+
Path to libraries directory
|
|
432
|
+
|
|
433
|
+
Raises:
|
|
434
|
+
FrameworkErrorSTM32: If libraries directory doesn't exist
|
|
435
|
+
"""
|
|
436
|
+
libraries_dir = self.framework_path / "libraries"
|
|
437
|
+
if not libraries_dir.exists():
|
|
438
|
+
raise FrameworkErrorSTM32(f"Libraries directory not found at {libraries_dir}")
|
|
439
|
+
return libraries_dir
|
|
440
|
+
|
|
441
|
+
# Implement IPackage interface
|
|
442
|
+
def ensure_package(self) -> Path:
|
|
443
|
+
"""Ensure package is downloaded and extracted.
|
|
444
|
+
|
|
445
|
+
Returns:
|
|
446
|
+
Path to the extracted package directory
|
|
447
|
+
|
|
448
|
+
Raises:
|
|
449
|
+
PackageError: If download or extraction fails
|
|
450
|
+
"""
|
|
451
|
+
return self.ensure_framework()
|
|
452
|
+
|
|
453
|
+
def get_package_info(self) -> Dict[str, Any]:
|
|
454
|
+
"""Get information about the package.
|
|
455
|
+
|
|
456
|
+
Returns:
|
|
457
|
+
Dictionary with package metadata (version, path, etc.)
|
|
458
|
+
"""
|
|
459
|
+
return self.get_framework_info()
|