3Copyright (c) 2017 ARM Limited
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
18"""Functions that manage a platform database"""
23from collections
import OrderedDict, defaultdict
26from os
import makedirs
27from os.path
import join, dirname, getmtime
28from platformdirs
import user_data_dir
29from fasteners
import InterProcessLock
38logger = logging.getLogger(
"mbedls.platform_database")
39logger.addHandler(logging.NullHandler())
42LOCAL_PLATFORM_DATABASE = join(user_data_dir(
"mbedls"),
"platforms.json")
43LOCAL_MOCKS_DATABASE = join(user_data_dir(
"mbedls"),
"mock.json")
45DEFAULT_PLATFORM_DB = {
55 u'0183':
u'UBLOX_C027',
63 u'0227':
u'MIMXRT1050_EVK',
64 u'0228':
u'RAPIDIOT_K64F',
67 u'0234':
u'RAPIDIOT_KW41Z',
73 u'0300':
u'MTS_GAMBIT',
74 u'0305':
u'MTS_MDOT_F405RG',
75 u'0310':
u'MTS_DRAGONFLY_F411RE',
77 u'0312':
u'MTS_DRAGONFLY_L471QG',
78 u'0315':
u'MTS_MDOT_F411RE',
79 u'0350':
u'XDOT_L151CC',
80 u'0400':
u'MAXWSNENV',
81 u'0405':
u'MAX32600MBED',
82 u'0406':
u'MAX32620MBED',
83 u'0407':
u'MAX32620HSP',
84 u'0408':
u'MAX32625NEXPAQ',
85 u'0409':
u'MAX32630FTHR',
86 u'0410':
u'ETTEPLAN_LORA',
87 u'0415':
u'MAX32625MBED',
88 u'0416':
u'MAX32625PICO',
89 u'0417':
u'MAX32630MBED',
90 u'0418':
u'MAX32620FTHR',
91 u'0419':
u'MAX35103EVKIT2',
92 u'0420':
u'MAX32630HSP3',
93 u'0450':
u'MTB_UBLOX_ODIN_W2',
94 u'0451':
u'MTB_MXCHIP_EMW3166',
95 u'0452':
u'MTB_LAIRD_BL600',
96 u'0453':
u'MTB_MTS_XDOT',
97 u'0454':
u'MTB_MTS_DRAGONFLY',
98 u'0455':
u'MTB_UBLOX_NINA_B1',
99 u'0456':
u'MTB_MURATA_ABZ',
100 u'0457':
u'MTB_RAK811',
101 u'0458':
u'MTB_ADV_WISE_1510',
102 u'0459':
u'MTB_ADV_WISE_1530',
103 u'0460':
u'MTB_ADV_WISE_1570',
104 u'0461':
u'MTB_LAIRD_BL652',
105 u'0462':
u'MTB_USI_WM_BN_BM_22',
106 u'0465':
u'MTB_LAIRD_BL654',
107 u'0466':
u'MTB_MURATA_WSM_BL241',
108 u'0472':
u'MTB_ACONNO_ACN52832',
109 u'0500':
u'SPANSION_PLACEHOLDER',
110 u'0505':
u'SPANSION_PLACEHOLDER',
111 u'0510':
u'SPANSION_PLACEHOLDER',
112 u'0602':
u'EV_COG_AD3029LZ',
113 u'0603':
u'EV_COG_AD4050LZ',
114 u'0700':
u'NUCLEO_F103RB',
115 u'0705':
u'NUCLEO_F302R8',
116 u'0710':
u'NUCLEO_L152RE',
117 u'0715':
u'NUCLEO_L053R8',
118 u'0720':
u'NUCLEO_F401RE',
119 u'0725':
u'NUCLEO_F030R8',
120 u'0730':
u'NUCLEO_F072RB',
121 u'0735':
u'NUCLEO_F334R8',
122 u'0740':
u'NUCLEO_F411RE',
123 u'0742':
u'NUCLEO_F413ZH',
124 u'0743':
u'DISCO_F413ZH',
125 u'0744':
u'NUCLEO_F410RB',
126 u'0745':
u'NUCLEO_F303RE',
127 u'0746':
u'DISCO_F303VC',
128 u'0747':
u'NUCLEO_F303ZE',
129 u'0750':
u'NUCLEO_F091RC',
130 u'0755':
u'NUCLEO_F070RB',
131 u'0760':
u'NUCLEO_L073RZ',
132 u'0764':
u'DISCO_L475VG_IOT01A',
133 u'0765':
u'NUCLEO_L476RG',
134 u'0766':
u'SILICA_SENSOR_NODE',
135 u'0770':
u'NUCLEO_L432KC',
136 u'0774':
u'DISCO_L4R9I',
137 u'0775':
u'NUCLEO_F303K8',
138 u'0776':
u'NUCLEO_L4R5ZI',
139 u'0777':
u'NUCLEO_F446RE',
140 u'0778':
u'NUCLEO_F446ZE',
141 u'0779':
u'NUCLEO_L433RC_P',
142 u'0780':
u'NUCLEO_L011K4',
143 u'0781':
u'NUCLEO_L4R5ZI_P',
144 u'0785':
u'NUCLEO_F042K6',
145 u'0788':
u'DISCO_F469NI',
146 u'0790':
u'NUCLEO_L031K6',
147 u'0791':
u'NUCLEO_F031K6',
148 u'0795':
u'DISCO_F429ZI',
149 u'0796':
u'NUCLEO_F429ZI',
150 u'0797':
u'NUCLEO_F439ZI',
151 u'0799':
u'ST_PLACEHOLDER',
152 u'0805':
u'DISCO_L053C8',
153 u'0810':
u'DISCO_F334C8',
154 u'0812':
u'NUCLEO_F722ZE',
155 u'0813':
u'NUCLEO_H743ZI',
156 u'0815':
u'DISCO_F746NG',
157 u'0816':
u'NUCLEO_F746ZG',
158 u'0817':
u'DISCO_F769NI',
159 u'0818':
u'NUCLEO_F767ZI',
160 u'0820':
u'DISCO_L476VG',
161 u'0821':
u'NUCLEO_L452RE',
162 u'0822':
u'DISCO_L496AG',
163 u'0823':
u'NUCLEO_L496ZG',
166 u'0826':
u'NUCLEO_F412ZG',
167 u'0827':
u'NUCLEO_L486RG',
168 u'0828':
u'NUCLEO_L496ZG_P',
169 u'0829':
u'NUCLEO_L452RE_P',
170 u'0830':
u'DISCO_F407VG',
171 u'0833':
u'DISCO_L072CZ_LRWAN1',
172 u'0835':
u'NUCLEO_F207ZG',
173 u'0839':
u'NUCLEO_WB55RG',
174 u'0840':
u'B96B_F446VE',
175 u'0879':
u'NUCLEO_F756ZG',
176 u'0900':
u'XPRO_SAMR21',
177 u'0905':
u'XPRO_SAMW25',
178 u'0910':
u'XPRO_SAML21',
179 u'0915':
u'XPRO_SAMD21',
185 u'1019':
u'TY51822R3',
187 u'1034':
u'LPC11U34',
188 u'1040':
u'LPC11U24',
189 u'1045':
u'LPC11U24',
191 u'1054':
u'LPC54114',
192 u'1056':
u'LPC546XX',
194 u'1061':
u'LPC11U35_401',
195 u'1062':
u'LPC4088_DM',
196 u'1070':
u'NRF51822',
197 u'1075':
u'NRF51822_OTA',
198 u'1080':
u'OC_MBUINO',
199 u'1090':
u'RBLAB_NRF51822',
200 u'1093':
u'RBLAB_BLENANO2',
201 u'1095':
u'RBLAB_BLENANO',
202 u'1100':
u'NRF51_DK',
203 u'1101':
u'NRF52_DK',
204 u'1102':
u'NRF52840_DK',
205 u'1105':
u'NRF51_DK_OTA',
207 u'1120':
u'NRF51_DONGLE',
208 u'1130':
u'NRF51822_SBK',
209 u'1140':
u'WALLBOT_BLE',
210 u'1168':
u'LPC11U68',
211 u'1200':
u'NCS36510',
212 u'1234':
u'UBLOX_C027',
213 u'1235':
u'UBLOX_C027',
214 u'1236':
u'UBLOX_EVK_ODIN_W2',
215 u'1237':
u'UBLOX_EVK_NINA_B1',
216 u'1300':
u'NUC472-NUTINY',
218 u'1302':
u'NUMAKER_PFM_NUC472',
219 u'1303':
u'NUMAKER_PFM_M453',
220 u'1304':
u'NUMAKER_PFM_M487',
221 u'1305':
u'NUMAKER_PFM_M2351',
222 u'1306':
u'NUMAKER_PFM_NANO130',
223 u'1307':
u'NUMAKER_PFM_NUC240',
224 u'1308':
u'NUMAKER_IOT_M487',
226 u'1600':
u'LPC4330_M4',
227 u'1605':
u'LPC4330_M4',
228 u'1701':
u'GD32_F307VG',
229 u'1702':
u'GD32_F450ZI',
230 u'2000':
u'EFM32_G8XX_STK',
231 u'2005':
u'EFM32HG_STK3400',
232 u'2010':
u'EFM32WG_STK3800',
233 u'2015':
u'EFM32GG_STK3700',
234 u'2020':
u'EFM32LG_STK3600',
235 u'2025':
u'EFM32TG_STK3300',
236 u'2030':
u'EFM32ZG_STK3200',
237 u'2035':
u'EFM32PG_STK3401',
238 u'2040':
u'EFM32PG12_STK3402',
239 u'2041':
u'TB_SENSE_12',
240 u'2045':
u'TB_SENSE_1',
241 u'2100':
u'XBED_LPC1768',
242 u'2201':
u'WIZWIKI_W7500',
243 u'2202':
u'WIZWIKI_W7500ECO',
244 u'2203':
u'WIZWIKI_W7500P',
245 u'2500':
u'ADV_WISE_1570',
246 u'3001':
u'LPC11U24',
247 u'3101':
u'SDT32620B',
248 u'3102':
u'SDT32625B',
249 u'3103':
u'SDT51822B',
250 u'3104':
u'SDT52832B',
252 u'3106':
u'SDT8195B',
253 u'3108':
u'SDT32429B',
254 u'3110':
u'SDT32439B',
255 u'3300':
u'CC3220SF',
256 u'4000':
u'LPC11U35_Y5_MBUG',
257 u'4005':
u'NRF51822_Y5_MBUG',
258 u'4100':
u'MOTE_L152RC',
260 u'4500':
u'DELTA_DFCM_NNN40',
261 u'4501':
u'DELTA_DFBM_NQ620',
262 u'4502':
u'DELTA_DFCM_NNN50',
263 u'4600':
u'REALTEK_RTL8195AM',
264 u'5000':
u'ARM_MPS2',
265 u'5001':
u'ARM_MPS2_M0',
266 u'5002':
u'ARM_BEETLE_SOC',
267 u'5003':
u'ARM_MPS2_M0P',
268 u'5005':
u'ARM_MPS2_M0DS',
269 u'5006':
u'ARM_MUSCA_A1',
270 u'5007':
u'ARM_MPS2_M1',
271 u'5009':
u'ARM_MPS2_M3',
272 u'5011':
u'ARM_MPS2_M4',
273 u'5015':
u'ARM_MPS2_M7',
274 u'5020':
u'HOME_GATEWAY_6LOWPAN',
276 u'5501':
u'GR_LYCHEE',
277 u'6000':
u'FUTURE_SEQUANA',
278 u'6660':
u'NZ32_SC151',
279 u'7010':
u'BLUENINJA_CDP_TZ01B',
282 u'7402':
u'MBED_BR_HAT',
283 u'7778':
u'TEENSY3_1',
286 u'8003':
u'UNO_81AM',
288 u'8080':
u'FF1705_L151CC',
289 u'8081':
u'FF_LPC546XX',
291 u'9002':
u'LPC11U24',
293 u'9004':
u'ARCH_PRO',
294 u'9006':
u'LPC11U24',
295 u'9007':
u'LPC11U35_501',
296 u'9008':
u'XADOW_M0',
297 u'9009':
u'ARCH_BLE',
298 u'9010':
u'ARCH_GPRS',
299 u'9011':
u'ARCH_MAX',
300 u'9012':
u'SEEED_TINY_BLE',
302 u'9015':
u'WIO_BG96',
303 u'9900':
u'NRF51_MICROBIT',
304 u'C002':
u'VK_RZ_A1H',
305 u'C005':
u'MTM_MTCONNECT04S',
306 u'C006':
u'VBLUNO51',
307 u'C008':
u'SAKURAIO_EVB_01',
308 u'C030':
u'UBLOX_C030_U201',
309 u'C031':
u'UBLOX_C030_N211',
310 u'C032':
u'UBLOX_C030_R404M',
311 u'C033':
u'UBLOX_C030_R410M',
312 u'C034':
u'UBLOX_C030_S200',
313 u'C035':
u'UBLOX_C030_R3121',
314 u'FFFF':
u'K20 BOOTLOADER',
319 u'platform_name':
u'NRF51_DK',
320 u'jlink_device_name':
u'nRF51422_xxAC'
323 u'platform_name':
u'NRF52_DK',
324 u'jlink_device_name':
u'nRF52832_xxaa'
327 u'platform_name':
u'KL25Z',
328 u'jlink_device_name':
u'MKL25Z128xxx4'
331 u'platform_name':
u'KL27Z',
332 u'jlink_device_name':
u'MKL27Z64xxx4'
335 u'platform_name':
u'KL43Z',
336 u'jlink_device_name':
u'MKL43Z256xxx4'
340 u'2241':
'SAML21J18A'
347 mtime = getmtime(path)
350 return datetime.datetime.fromtimestamp(mtime)
358 if isinstance(data, dict):
362 return data[simple_data_key]
366 simple_data_key: data
375 raise ValueError(
"Platform Database is out of date")
376 with open(db, encoding=
"utf-8")
as db_in:
377 return json.load(db_in)
378 except (IOError, ValueError)
as exc:
379 if db
is LOCAL_PLATFORM_DATABASE:
381 "Error loading database %s: %s; Recreating", db, str(exc))
383 makedirs(dirname(db))
387 with open(db,
"w", encoding=
"utf-8")
as out:
388 out.write(
unicode(json.dumps(DEFAULT_PLATFORM_DB)))
391 return copy(DEFAULT_PLATFORM_DB)
397 """Represents a union of multiple platform database files.
398 Handles inter-process synchronization of database files.
401 target_id_pattern = re.compile(
r'^[a-fA-F0-9]{4}$')
403 def __init__(self, database_files, primary_database=None):
404 """Construct a PlatformDatabase object from a series of platform database files"""
406 if not self.
_prim_db and len(database_files) == 1:
410 for db
in database_files:
414 first_value = next(iter(new_db.values()))
415 if not isinstance(first_value, dict):
421 for device_type
in new_db:
422 duplicates = self.
_keys[device_type].intersection(set(new_db[device_type].keys()))
423 duplicates = set([
"%s.%s" % (device_type, k)
for k
in duplicates])
426 "Duplicate platform ids found: %s,"
427 " ignoring the definitions from %s",
428 " ".join(duplicates), db)
429 self.
_dbs[db] = new_db
430 self.
_keys[device_type] = self.
_keys[device_type].union(new_db[device_type].keys())
432 self.
_dbs[db] = new_db
435 def items(self, device_type='daplink'):
436 for db
in self.
_dbs.values():
437 for entry
in db.get(device_type, {}).
items():
441 return iter(self.
_keys[device_type])
443 def get(self, index, default=None, device_type='daplink', verbose_data=False):
444 """Standard lookup function. Works exactly like a dict. If 'verbose_data'
445 is True, all data for the platform is returned as a dict."""
446 for db
in self.
_dbs.values():
447 if device_type
in db:
448 maybe_answer = db[device_type].
get(index,
None)
456 lock = InterProcessLock(
"%s.lock" % self.
_prim_db)
457 acquired = lock.acquire(blocking=
False)
459 logger.debug(
"Waiting 60 seconds for file lock")
460 acquired = lock.acquire(blocking=
True, timeout=60)
463 with open(self.
_prim_db,
"w", encoding=
"utf-8")
as out:
470 logger.error(
"Could not update platform database: "
471 "Lock acquire failed after 60 seconds")
474 logger.error(
"Can't update platform database: "
475 "destination database is ambiguous")
478 def add(self, id, platform_name, permanent=False, device_type='daplink'):
479 """Add a platform to this database, optionally updating an origin
486 self.
_dbs[self.
_prim_db][device_type][id] = platform_name
488 cur_db = next(iter(self.
_dbs.values()))
489 if device_type
not in cur_db:
490 cur_db[device_type] = {}
491 cur_db[device_type][id] = platform_name
496 raise ValueError(
"Invald target id: %s" % id)
498 def remove(self, id, permanent=False, device_type='daplink', verbose_data=False):
499 """Remove a platform from this database, optionally updating an origin
500 database. If 'verbose_data' is True, all data for the platform is returned
503 logger.debug(
"Trying remove of %s", id)
504 if id ==
'*' and device_type
in self.
_dbs[self.
_prim_db]:
506 for db
in self.
_dbs.values():
507 if device_type
in db
and id
in db[device_type]:
508 logger.debug(
"Removing id...")
509 removed = db[device_type][id]
510 del db[device_type][id]