forked from platformio/platformio-core
		
	
		
			
				
	
	
		
			159 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
 | 
						|
#
 | 
						|
# 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
 | 
						|
 | 
						|
from platformio import fs, telemetry, util
 | 
						|
from platformio.commands.debug.exception import (
 | 
						|
    DebugInvalidOptionsError,
 | 
						|
    DebugSupportError,
 | 
						|
)
 | 
						|
from platformio.compat import PY2
 | 
						|
from platformio.exception import UserSideException
 | 
						|
from platformio.platform.exception import InvalidBoardManifest
 | 
						|
 | 
						|
 | 
						|
class PlatformBoardConfig(object):
 | 
						|
    def __init__(self, manifest_path):
 | 
						|
        self._id = os.path.basename(manifest_path)[:-5]
 | 
						|
        assert os.path.isfile(manifest_path)
 | 
						|
        self.manifest_path = manifest_path
 | 
						|
        try:
 | 
						|
            self._manifest = fs.load_json(manifest_path)
 | 
						|
        except ValueError:
 | 
						|
            raise InvalidBoardManifest(manifest_path)
 | 
						|
        if not set(["name", "url", "vendor"]) <= set(self._manifest):
 | 
						|
            raise UserSideException(
 | 
						|
                "Please specify name, url and vendor fields for " + manifest_path
 | 
						|
            )
 | 
						|
 | 
						|
    def get(self, path, default=None):
 | 
						|
        try:
 | 
						|
            value = self._manifest
 | 
						|
            for k in path.split("."):
 | 
						|
                value = value[k]
 | 
						|
            # pylint: disable=undefined-variable
 | 
						|
            if PY2 and isinstance(value, unicode):
 | 
						|
                # cast to plain string from unicode for PY2, resolves issue in
 | 
						|
                # dev/platform when BoardConfig.get() is used in pair with
 | 
						|
                # os.path.join(file_encoding, unicode_encoding)
 | 
						|
                try:
 | 
						|
                    value = value.encode("utf-8")
 | 
						|
                except UnicodeEncodeError:
 | 
						|
                    pass
 | 
						|
            return value
 | 
						|
        except KeyError:
 | 
						|
            if default is not None:
 | 
						|
                return default
 | 
						|
        raise KeyError("Invalid board option '%s'" % path)
 | 
						|
 | 
						|
    def update(self, path, value):
 | 
						|
        newdict = None
 | 
						|
        for key in path.split(".")[::-1]:
 | 
						|
            if newdict is None:
 | 
						|
                newdict = {key: value}
 | 
						|
            else:
 | 
						|
                newdict = {key: newdict}
 | 
						|
        util.merge_dicts(self._manifest, newdict)
 | 
						|
 | 
						|
    def __contains__(self, key):
 | 
						|
        try:
 | 
						|
            self.get(key)
 | 
						|
            return True
 | 
						|
        except KeyError:
 | 
						|
            return False
 | 
						|
 | 
						|
    @property
 | 
						|
    def id(self):
 | 
						|
        return self._id
 | 
						|
 | 
						|
    @property
 | 
						|
    def id_(self):
 | 
						|
        return self.id
 | 
						|
 | 
						|
    @property
 | 
						|
    def manifest(self):
 | 
						|
        return self._manifest
 | 
						|
 | 
						|
    def get_brief_data(self):
 | 
						|
        result = {
 | 
						|
            "id": self.id,
 | 
						|
            "name": self._manifest["name"],
 | 
						|
            "platform": self._manifest.get("platform"),
 | 
						|
            "mcu": self._manifest.get("build", {}).get("mcu", "").upper(),
 | 
						|
            "fcpu": int(
 | 
						|
                "".join(
 | 
						|
                    [
 | 
						|
                        c
 | 
						|
                        for c in str(self._manifest.get("build", {}).get("f_cpu", "0L"))
 | 
						|
                        if c.isdigit()
 | 
						|
                    ]
 | 
						|
                )
 | 
						|
            ),
 | 
						|
            "ram": self._manifest.get("upload", {}).get("maximum_ram_size", 0),
 | 
						|
            "rom": self._manifest.get("upload", {}).get("maximum_size", 0),
 | 
						|
            "frameworks": self._manifest.get("frameworks"),
 | 
						|
            "vendor": self._manifest["vendor"],
 | 
						|
            "url": self._manifest["url"],
 | 
						|
        }
 | 
						|
        if self._manifest.get("connectivity"):
 | 
						|
            result["connectivity"] = self._manifest.get("connectivity")
 | 
						|
        debug = self.get_debug_data()
 | 
						|
        if debug:
 | 
						|
            result["debug"] = debug
 | 
						|
        return result
 | 
						|
 | 
						|
    def get_debug_data(self):
 | 
						|
        if not self._manifest.get("debug", {}).get("tools"):
 | 
						|
            return None
 | 
						|
        tools = {}
 | 
						|
        for name, options in self._manifest["debug"]["tools"].items():
 | 
						|
            tools[name] = {}
 | 
						|
            for key, value in options.items():
 | 
						|
                if key in ("default", "onboard") and value:
 | 
						|
                    tools[name][key] = value
 | 
						|
        return {"tools": tools}
 | 
						|
 | 
						|
    def get_debug_tool_name(self, custom=None):
 | 
						|
        debug_tools = self._manifest.get("debug", {}).get("tools")
 | 
						|
        tool_name = custom
 | 
						|
        if tool_name == "custom":
 | 
						|
            return tool_name
 | 
						|
        if not debug_tools:
 | 
						|
            telemetry.send_event("Debug", "Request", self.id)
 | 
						|
            raise DebugSupportError(self._manifest["name"])
 | 
						|
        if tool_name:
 | 
						|
            if tool_name in debug_tools:
 | 
						|
                return tool_name
 | 
						|
            raise DebugInvalidOptionsError(
 | 
						|
                "Unknown debug tool `%s`. Please use one of `%s` or `custom`"
 | 
						|
                % (tool_name, ", ".join(sorted(list(debug_tools))))
 | 
						|
            )
 | 
						|
 | 
						|
        # automatically select best tool
 | 
						|
        data = {"default": [], "onboard": [], "external": []}
 | 
						|
        for key, value in debug_tools.items():
 | 
						|
            if value.get("default"):
 | 
						|
                data["default"].append(key)
 | 
						|
            elif value.get("onboard"):
 | 
						|
                data["onboard"].append(key)
 | 
						|
            data["external"].append(key)
 | 
						|
 | 
						|
        for key, value in data.items():
 | 
						|
            if not value:
 | 
						|
                continue
 | 
						|
            return sorted(value)[0]
 | 
						|
 | 
						|
        assert any(item for item in data)
 |