# Copyright 2014-present PlatformIO # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import sys import subprocess from platformio.managers.platform import PlatformBase IS_WINDOWS = sys.platform.startswith("win") class Ststm32Platform(PlatformBase): def configure_default_packages(self, variables, targets): board = variables.get("board") board_config = self.board_config(board) build_core = variables.get( "board_build.core", board_config.get("build.core", "arduino")) build_mcu = variables.get("board_build.mcu", board_config.get("build.mcu", "")) frameworks = variables.get("pioframework", []) if "arduino" in frameworks: if board.startswith(("portenta", "opta", "nicla_vision")): self.frameworks["arduino"]["package"] = "framework-arduino-mbed" self.frameworks["arduino"][ "script" ] = "builder/frameworks/arduino/mbed-core/arduino-core-mbed.py" self.packages["framework-arduinoststm32"]["optional"] = True elif build_core == "maple": self.frameworks["arduino"]["package"] = "framework-arduinoststm32-maple" self.packages["framework-arduinoststm32-maple"]["optional"] = False self.packages["framework-arduinoststm32"]["optional"] = True elif build_core == "stm32l0": self.frameworks["arduino"]["package"] = "framework-arduinoststm32l0" self.packages["framework-arduinoststm32l0"]["optional"] = False self.packages["framework-arduinoststm32"]["optional"] = True else: self.packages["toolchain-gccarmnoneeabi"]["version"] = "~1.120301.0" self.packages["framework-cmsis"]["version"] = "~2.50700.0" self.packages["framework-cmsis"]["optional"] = False if "mbed" in frameworks: self.packages["toolchain-gccarmnoneeabi"]["version"] = "~1.90201.0" if "cmsis" in frameworks: assert build_mcu, ("Missing MCU field for %s" % board) device_package = "framework-cmsis-" + build_mcu[0:7] if device_package in self.packages: self.packages[device_package]["optional"] = False if "stm32cube" in frameworks: assert build_mcu, ("Missing MCU field for %s" % board) device_package = "framework-stm32cube%s" % build_mcu[5:7] self.frameworks["stm32cube"]["package"] = device_package if any(f in frameworks for f in ("cmsis", "stm32cube")): self.packages["tool-ldscripts-ststm32"]["optional"] = False default_protocol = board_config.get("upload.protocol") or "" if variables.get("upload_protocol", default_protocol) == "dfu": dfu_package = "tool-dfuutil" if board.startswith(("portenta", "opta", "nicla")): dfu_package = "tool-dfuutil-arduino" self.packages.pop("tool-dfuutil") else: self.packages.pop("tool-dfuutil-arduino") self.packages[dfu_package]["optional"] = False if board == "mxchip_az3166": self.frameworks["arduino"][ "package"] = "framework-arduinostm32mxchip" self.frameworks["arduino"][ "script"] = "builder/frameworks/arduino/mxchip.py" self.packages["toolchain-gccarmnoneeabi"]["version"] = "~1.60301.0" if "zephyr" in variables.get("pioframework", []): for p in self.packages: if p in ("tool-cmake", "tool-dtc", "tool-ninja"): self.packages[p]["optional"] = False self.packages["toolchain-gccarmnoneeabi"]["version"] = "~1.120301.0" if not IS_WINDOWS: self.packages["tool-gperf"]["optional"] = False # configure J-LINK tool jlink_conds = [ "jlink" in variables.get(option, "") for option in ("upload_protocol", "debug_tool") ] if board: jlink_conds.extend([ "jlink" in board_config.get(key, "") for key in ("debug.default_tools", "upload.protocol") ]) jlink_pkgname = "tool-jlink" if not any(jlink_conds) and jlink_pkgname in self.packages: del self.packages[jlink_pkgname] return PlatformBase.configure_default_packages(self, variables, targets) def install_package(self, name, *args, **kwargs): pkg = super().install_package(name, *args, **kwargs) if name != "framework-zephyr": return pkg if not os.path.isfile(os.path.join(pkg.path, "_pio", "state.json")): self.pm.log.info("Installing Zephyr project dependencies...") try: subprocess.run([ os.path.normpath(sys.executable), os.path.join(pkg.path, "scripts", "platformio", "install-deps.py"), "--platform", self.name ]) except subprocess.CalledProcessError: self.pm.log.info("Failed to install Zephyr dependencies!") return pkg def get_boards(self, id_=None): result = PlatformBase.get_boards(self, id_) if not result: return result if id_: return self._add_default_debug_tools(result) else: for key, value in result.items(): result[key] = self._add_default_debug_tools(result[key]) return result def _add_default_debug_tools(self, board): debug = board.manifest.get("debug", {}) upload_protocols = board.manifest.get("upload", {}).get( "protocols", []) if "tools" not in debug: debug["tools"] = {} # BlackMagic, J-Link, ST-Link for link in ("blackmagic", "jlink", "stlink", "cmsis-dap"): if link not in upload_protocols or link in debug["tools"]: continue if link == "blackmagic": debug["tools"]["blackmagic"] = { "hwids": [["0x1d50", "0x6018"]], "require_debug_port": True } elif link == "jlink": assert debug.get("jlink_device"), ( "Missed J-Link Device ID for %s" % board.id) debug["tools"][link] = { "server": { "package": "tool-jlink", "arguments": [ "-singlerun", "-if", "SWD", "-select", "USB", "-device", debug.get("jlink_device"), "-port", "2331" ], "executable": ("JLinkGDBServerCL.exe" if IS_WINDOWS else "JLinkGDBServer") } } else: server_args = ["-s", "$PACKAGE_DIR/openocd/scripts"] if debug.get("openocd_board"): server_args.extend([ "-f", "board/%s.cfg" % debug.get("openocd_board") ]) else: assert debug.get("openocd_target"), ( "Missed target configuration for %s" % board.id) server_args.extend([ "-f", "interface/%s.cfg" % link, "-c", "transport select %s" % ( "hla_swd" if link == "stlink" else "swd"), "-f", "target/%s.cfg" % debug.get("openocd_target") ]) server_args.extend(debug.get("openocd_extra_args", [])) debug["tools"][link] = { "server": { "package": "tool-openocd", "executable": "bin/openocd", "arguments": server_args } } debug["tools"][link]["onboard"] = link in debug.get("onboard_tools", []) debug["tools"][link]["default"] = link in debug.get("default_tools", []) board.manifest["debug"] = debug return board def configure_debug_session(self, debug_config): if debug_config.speed: server_executable = (debug_config.server or {}).get("executable", "").lower() if "openocd" in server_executable: debug_config.server["arguments"].extend( ["-c", "adapter speed %s" % debug_config.speed] ) elif "jlink" in server_executable: debug_config.server["arguments"].extend( ["-speed", debug_config.speed] )