13 def validate_stm32(vendor
, type, devname
, device
):
14 for method
in device
['upload_methods']:
15 if method
not in ['stlink', 'dfu', 'uart', 'wifi', 'betaflight']:
16 error(f
'Invalid upload method "{method}" for target "{vendor}.{type}.{devname}"')
17 if 'stlink' not in device
['upload_methods']:
18 error(f
'STM32 based devices must always have "stlink" as an upload_method for target "{vendor}.{type}.{devname}"')
19 if 'stlink' not in device
:
20 error(f
'STM32 based devices must always have "stlink" attribute for target "{vendor}.{type}.{devname}"')
22 stlink
= device
['stlink']
23 if 'cpus' not in stlink
:
24 error(f
'The "stlink" attribute for target "{vendor}.{type}.{devname}" must have a list of valid "cpus"')
25 if 'offset' not in stlink
:
26 error(f
'The "stlink" attribute for target "{vendor}.{type}.{devname}" must have a valid "offset"')
27 if 'bootloader' not in stlink
:
28 error(f
'The "stlink" attribute for target "{vendor}.{type}.{devname}" must have a valid "bootloader"')
29 # could check the existence of the bootloader file
31 def validate_esp(vendor
, type, devname
, device
):
32 if 'lua_name' not in device
:
33 error(f
'device "{vendor}.{type}.{devname}" must have a "lua_name" child element')
34 if len(device
['lua_name']) > 16:
35 error(f
'device "{vendor}.{type}.{devname}" must have a "lua_name" of 16 characters or less')
36 # validate layout_file
37 if 'layout_file' not in device
:
38 error(f
'device "{vendor}.{type}.{devname}" must have a "layout_file" child element')
40 dir = 'hardware/' + ('RX/' if type.startswith('rx') else 'TX/')
41 if not os
.path
.isfile(dir + device
['layout_file']):
42 layout_file
= device
['layout_file']
43 error(f
'File specified by layout_file "{layout_file}" in target "{vendor}.{type}.{devname}", does not exist')
44 # could validate overlay
46 def validate_esp32(vendor
, type, devname
, device
):
47 for method
in device
['upload_methods']:
48 if method
not in ['uart', 'etx', 'wifi', 'betaflight']:
49 error(f
'Invalid upload method "{method}" for target "{vendor}.{type}.{devname}"')
50 validate_esp(vendor
, type, devname
, device
)
52 def validate_esp8285(vendor
, type, devname
, device
):
53 for method
in device
['upload_methods']:
54 if method
not in ['uart', 'wifi', 'betaflight']:
55 error(f
'Invalid upload method "{method}" for target "{vendor}.{type}.{devname}"')
56 validate_esp(vendor
, type, devname
, device
)
58 def validate_devices(vendor
, type, devname
, device
):
59 if devname
!= devname
.lower():
60 error(f
'device tag "{devname}" should be lowercase')
61 if 'product_name' not in device
:
62 error(f
'device "{vendor}.{type}.{devname}" must have a "product_name" child element')
63 if 'upload_methods' not in device
:
64 error(f
'device "{vendor}.{type}.{devname}" must have a "upload_methods" child element')
66 if 'firmware' not in device
:
67 error(f
'device "{vendor}.{type}.{devname}" must have a "firmware" child element')
69 firmware
= device
['firmware']
70 if firmware
not in firmwares
:
71 error(f
'device "{vendor}.{type}.{devname}" has an invalid firmware file "{firmware}"')
72 elif (firmware
.endswith('_TX') and 'tx_' not in type):
73 error(f
'device "{vendor}.{type}.{devname}" has an invalid firmware file "{firmware}", it must be a TX target firmware')
74 elif (firmware
.endswith('_RX') and 'rx_' not in type):
75 error(f
'device "{vendor}.{type}.{devname}" has an invalid firmware file "{firmware}", it must be an RX target firmware')
77 if 'platform' not in device
:
78 error(f
'device "{vendor}.{type}.{devname}" must have a "platform" child element')
80 platform
= device
['platform']
81 if platform
== 'stm32':
82 validate_stm32(vendor
, type, devname
, device
)
83 elif platform
== 'esp32':
84 validate_esp32(vendor
, type, devname
, device
)
85 elif platform
== 'esp8285':
86 validate_esp8285(vendor
, type, devname
, device
)
88 error(f
'invalid platform "{platform}" in device "{vendor}.{type}.{devname}"')
90 if 'features' in device
:
91 for feature
in device
['features']:
92 if feature
not in ['buzzer', 'unlock-higher-power', 'fan', 'sbus-uart']:
93 error(f
'features must contain one or more of [\'buzzer\', \'unlock-higher-power\', \'fan\', \'sbus-uart\'], if present in target "{vendor}.{type}.{devname}"')
95 def validate_vendor(name
, types
):
96 if name
!= name
.lower():
97 error(f
'vendor tag "{vendor}" should be lowercase')
99 if 'name' not in types
:
100 error(f
'vendor "{vendor}" must have a "name" child element')
103 if type not in ['rx_2400', 'rx_900', 'tx_2400', 'tx_900', 'name']:
104 error(f
'invalid tag "{type}" in "{vendor}"')
105 if type in ['rx_2400', 'rx_900', 'tx_2400', 'tx_900']:
106 for device
in types
[type]:
107 validate_devices(name
, type, device
, types
[type][device
])
109 if __name__
== '__main__':
111 with
open('hardware/targets.json') as f
:
112 targets
= json
.load(f
)
114 for inifile
in glob
.iglob('targets/*.ini'):
115 with
open(inifile
) as ini
:
117 if line
.startswith('[env:'):
119 firmware_file
= line
[5:line
.index('_via_')]
120 firmwares
.add(firmware_file
)
125 for vendor
in targets
:
126 validate_vendor(vendor
, targets
[vendor
])
128 for inifile
in glob
.iglob('targets/*.ini'):
129 with
open(inifile
) as ini
:
131 if line
.startswith('[env:'):
133 if line
.startswith('board_config'):
135 board
= line
[eq
+1:].strip()
136 parts
= board
.split('.')
138 error(f
'{inifile}: board_config must have 3 parts')
143 if vendor
not in targets
:
144 error(f
'{inifile}: targets.json file does not contain vendor {vendor}')
145 elif type not in targets
[vendor
]:
146 error(f
'{inifile}: targets.json "{vendor}" does not contain type {type}')
147 elif device
not in targets
[vendor
][type]:
148 error(f
'{inifile}: targets.json "{vendor}.{type}" does not contain device {device}')