mirror of https://github.com/ARMmbed/mbed-os.git
179 lines
5.8 KiB
Python
179 lines
5.8 KiB
Python
"""
|
|
Copyright (c) 2016-2019 ARM Limited. All rights reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
|
|
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.
|
|
"""
|
|
|
|
from os.path import join, dirname
|
|
from json import load, dump
|
|
import warnings
|
|
|
|
try:
|
|
from cmsis_pack_manager import Cache as _Cache
|
|
_CPM_PRESENT = True
|
|
except (ImportError, OSError):
|
|
_CPM_PRESENT = False
|
|
|
|
from tools.flash_algo import PackFlashAlgo
|
|
|
|
warnings.filterwarnings("ignore")
|
|
|
|
RootPackURL = "http://www.keil.com/pack/index.idx"
|
|
|
|
LocalPackDir = dirname(__file__)
|
|
LocalPackIndex = join(LocalPackDir, "index.json")
|
|
LocalPackAliases = join(LocalPackDir, "aliases.json")
|
|
LocalPackLegacyNames = join(LocalPackDir, "legacy-names.json")
|
|
|
|
|
|
class _CacheLookup(object):
|
|
def __init__(self, index, legacy_names):
|
|
self.index = index
|
|
self.legacy_names = legacy_names
|
|
|
|
def __getitem__(self, name):
|
|
try:
|
|
return self.index[name]
|
|
except KeyError:
|
|
return self.index[self.legacy_names[name]]
|
|
|
|
def __contains__(self, name):
|
|
return name in self.index or name in self.legacy_names
|
|
|
|
|
|
class Cache(object):
|
|
""" The Cache object is the only relevant API object at the moment
|
|
|
|
Constructing the Cache object does not imply any caching.
|
|
A user of the API must explicitly call caching functions.
|
|
|
|
:param silent: Not used
|
|
:type silent: bool
|
|
:param no_timeouts: Not used
|
|
:type no_timeouts: bool
|
|
"""
|
|
def __init__(self, silent, no_timeouts):
|
|
if _CPM_PRESENT:
|
|
self._cache = _Cache(
|
|
silent, no_timeouts,
|
|
json_path=LocalPackDir, data_path=LocalPackDir
|
|
)
|
|
else:
|
|
self._cache = None
|
|
|
|
try:
|
|
self._legacy_names = load(open(LocalPackLegacyNames))
|
|
except IOError:
|
|
self._legacy_names = {}
|
|
|
|
def _get_sectors(self, device):
|
|
"""Extract sector sizes from device FLM algorithm
|
|
|
|
Will return None if there is no algorithm, pdsc URL formatted in
|
|
correctly
|
|
|
|
:return: A list tuples of sector start and size
|
|
:rtype: [list]
|
|
"""
|
|
try:
|
|
pack = self._cache.pack_from_cache(device)
|
|
ret = []
|
|
for algo in device['algorithms']:
|
|
try:
|
|
flm = pack.open(
|
|
algo["file_name"]
|
|
.replace("\\\\", "/")
|
|
.replace("\\", "/")
|
|
)
|
|
flash_alg = PackFlashAlgo(flm.read())
|
|
sectors = [(flash_alg.flash_start + offset, size)
|
|
for offset, size in flash_alg.sector_sizes]
|
|
ret.extend(sectors)
|
|
except Exception:
|
|
pass
|
|
ret.sort(key=lambda sector: sector[0])
|
|
return ret
|
|
except Exception:
|
|
return None
|
|
|
|
@property
|
|
def index(self):
|
|
if _CPM_PRESENT:
|
|
return _CacheLookup(self._cache.index, self._legacy_names)
|
|
else:
|
|
local_index = load(open(LocalPackIndex))
|
|
return _CacheLookup(local_index, self._legacy_names)
|
|
|
|
def cache_descriptors(self):
|
|
if _CPM_PRESENT:
|
|
return self._cache.cache_descriptors()
|
|
else:
|
|
print(
|
|
'The Python package "cmsis-pack-manager" is not installed. '
|
|
'To cache CMSIS Pack descriptors, please install this '
|
|
'package with "pip install cmsis-pack-manager".'
|
|
)
|
|
return []
|
|
|
|
def cache_everything(self):
|
|
if _CPM_PRESENT:
|
|
self._cache.cache_everything()
|
|
for name, device in self._cache.index.items():
|
|
if name != "version":
|
|
device["sectors"] = self._get_sectors(device)
|
|
self.generate_index()
|
|
else:
|
|
print(
|
|
'The Python package "cmsis-pack-manager" is not installed. '
|
|
'To update the cache, please install this package with '
|
|
'"pip install cmsis-pack-manager".'
|
|
)
|
|
|
|
def get_svd_file(self, device_name):
|
|
"""Retrieve the flash algorithm file for a particular part.
|
|
|
|
Assumes that both the PDSC and the PACK file associated with that part
|
|
are in the cache.
|
|
|
|
:param device_name: The exact name of a device
|
|
:type device_name: str
|
|
:return: A file-like object that, when read, is the ELF file that
|
|
describes the flashing algorithm
|
|
:rtype: ZipExtFile
|
|
"""
|
|
if _CPM_PRESENT:
|
|
device = self.index[device_name]
|
|
pack = self._cache.pack_from_cache(device)
|
|
return pack.open(device['debug'])
|
|
else:
|
|
print(
|
|
'The Python package "cmsis-pack-manager" is not installed. '
|
|
'To use SVD files, please install this package with '
|
|
'"pip install cmsis-pack-manager".'
|
|
)
|
|
return None
|
|
|
|
def generate_index(self):
|
|
if _CPM_PRESENT:
|
|
with open(LocalPackIndex, "w+") as out:
|
|
self._cache.index["version"] = "0.2.0"
|
|
dump(self._cache.index, out, indent=4, sort_keys=True)
|
|
else:
|
|
print(
|
|
'The Python package "cmsis-pack-manager" is not installed. '
|
|
'To generate a CMSIS Pack index, please install this package with '
|
|
'"pip install cmsis-pack-manager".'
|
|
)
|