forked from platformio/platformio-core
156 lines
5.4 KiB
Python
156 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.compat import PY2
|
|
from platformio.debug.exception import DebugInvalidOptionsError, DebugSupportError
|
|
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)
|