CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Tools/ardupilotwaf/boards.py
Views: 1798
1
# encoding: utf-8
2
3
from collections import OrderedDict
4
import re
5
import sys, os
6
import fnmatch
7
import platform
8
9
import waflib
10
from waflib import Utils
11
from waflib.Configure import conf
12
import json
13
_board_classes = {}
14
_board = None
15
16
# modify our search path:
17
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../libraries/AP_HAL_ChibiOS/hwdef/scripts'))
18
import chibios_hwdef
19
import build_options
20
21
class BoardMeta(type):
22
def __init__(cls, name, bases, dct):
23
super(BoardMeta, cls).__init__(name, bases, dct)
24
25
if 'abstract' not in cls.__dict__:
26
cls.abstract = False
27
if cls.abstract:
28
return
29
30
if not hasattr(cls, 'toolchain'):
31
cls.toolchain = 'native'
32
33
board_name = getattr(cls, 'name', name)
34
if board_name in _board_classes:
35
raise Exception('board named %s already exists' % board_name)
36
_board_classes[board_name] = cls
37
38
class Board:
39
abstract = True
40
41
def __init__(self):
42
self.with_can = False
43
44
def configure(self, cfg):
45
cfg.env.TOOLCHAIN = cfg.options.toolchain or self.toolchain
46
cfg.env.ROMFS_FILES = []
47
if hasattr(self,'configure_toolchain'):
48
self.configure_toolchain(cfg)
49
else:
50
cfg.load('toolchain')
51
cfg.load('cxx_checks')
52
53
# don't check elf symbols by default
54
cfg.env.CHECK_SYMBOLS = False
55
56
env = waflib.ConfigSet.ConfigSet()
57
def srcpath(path):
58
return cfg.srcnode.make_node(path).abspath()
59
env.SRCROOT = srcpath('')
60
61
self.configure_env(cfg, env)
62
63
# Setup scripting:
64
env.DEFINES.update(
65
LUA_32BITS = 1,
66
)
67
68
env.AP_LIBRARIES += [
69
'AP_Scripting',
70
'AP_Scripting/lua/src',
71
]
72
73
if cfg.options.enable_scripting:
74
env.DEFINES.update(
75
AP_SCRIPTING_ENABLED = 1,
76
)
77
elif cfg.options.disable_scripting:
78
env.DEFINES.update(
79
AP_SCRIPTING_ENABLED = 0,
80
)
81
82
# allow GCS disable for AP_DAL example
83
if cfg.options.no_gcs:
84
env.CXXFLAGS += ['-DHAL_GCS_ENABLED=0']
85
86
# configurations for XRCE-DDS
87
if cfg.options.enable_dds:
88
cfg.recurse('libraries/AP_DDS')
89
env.ENABLE_DDS = True
90
env.AP_LIBRARIES += [
91
'AP_DDS'
92
]
93
env.DEFINES.update(AP_DDS_ENABLED = 1)
94
# check for microxrceddsgen
95
cfg.find_program('microxrceddsgen',mandatory=True)
96
else:
97
env.ENABLE_DDS = False
98
env.DEFINES.update(AP_DDS_ENABLED = 0)
99
100
# setup for supporting onvif cam control
101
if cfg.options.enable_onvif:
102
cfg.recurse('libraries/AP_ONVIF')
103
env.ENABLE_ONVIF = True
104
env.ROMFS_FILES += [('scripts/ONVIF_Camera_Control.lua',
105
'libraries/AP_Scripting/applets/ONVIF_Camera_Control.lua')]
106
env.DEFINES.update(
107
ENABLE_ONVIF=1,
108
SCRIPTING_ENABLE_DEFAULT=1,
109
)
110
env.AP_LIBRARIES += [
111
'AP_ONVIF'
112
]
113
else:
114
env.ENABLE_ONVIF = False
115
env.DEFINES.update(
116
ENABLE_ONVIF=0,
117
)
118
119
# allow enable of OpenDroneID for any board
120
if cfg.options.enable_opendroneid:
121
env.ENABLE_OPENDRONEID = True
122
env.DEFINES.update(
123
AP_OPENDRONEID_ENABLED=1,
124
)
125
cfg.msg("Enabled OpenDroneID", 'yes')
126
else:
127
cfg.msg("Enabled OpenDroneID", 'no', color='YELLOW')
128
129
# allow enable of firmware ID checking for any board
130
if cfg.options.enable_check_firmware:
131
env.CHECK_FIRMWARE_ENABLED = True
132
env.DEFINES.update(
133
AP_CHECK_FIRMWARE_ENABLED=1,
134
)
135
cfg.msg("Enabled firmware ID checking", 'yes')
136
else:
137
cfg.msg("Enabled firmware ID checking", 'no', color='YELLOW')
138
139
if cfg.options.enable_gps_logging:
140
env.DEFINES.update(
141
AP_GPS_DEBUG_LOGGING_ENABLED=1,
142
)
143
cfg.msg("GPS Debug Logging", 'yes')
144
else:
145
cfg.msg("GPS Debug Logging", 'no', color='YELLOW')
146
147
# allow enable of custom controller for any board
148
# enabled on sitl by default
149
if (cfg.options.enable_custom_controller or self.get_name() == "sitl") and not cfg.options.no_gcs:
150
env.ENABLE_CUSTOM_CONTROLLER = True
151
env.DEFINES.update(
152
AP_CUSTOMCONTROL_ENABLED=1,
153
)
154
env.AP_LIBRARIES += [
155
'AC_CustomControl'
156
]
157
cfg.msg("Enabled custom controller", 'yes')
158
else:
159
env.DEFINES.update(
160
AP_CUSTOMCONTROL_ENABLED=0,
161
)
162
cfg.msg("Enabled custom controller", 'no', color='YELLOW')
163
164
# support enabling any option in build_options.py
165
for opt in build_options.BUILD_OPTIONS:
166
enable_option = opt.config_option().replace("-","_")
167
disable_option = "disable_" + enable_option[len("enable-"):]
168
if getattr(cfg.options, enable_option, False):
169
env.CXXFLAGS += ['-D%s=1' % opt.define]
170
cfg.msg("Enabled %s" % opt.label, 'yes', color='GREEN')
171
elif getattr(cfg.options, disable_option, False):
172
env.CXXFLAGS += ['-D%s=0' % opt.define]
173
cfg.msg("Enabled %s" % opt.label, 'no', color='YELLOW')
174
175
if cfg.options.disable_networking:
176
env.CXXFLAGS += ['-DAP_NETWORKING_ENABLED=0']
177
178
if cfg.options.enable_networking_tests:
179
env.CXXFLAGS += ['-DAP_NETWORKING_TESTS_ENABLED=1']
180
181
if cfg.options.enable_iomcu_profiled_support:
182
env.CXXFLAGS += ['-DAP_IOMCU_PROFILED_SUPPORT_ENABLED=1']
183
184
d = env.get_merged_dict()
185
# Always prepend so that arguments passed in the command line get
186
# the priority.
187
for k, val in d.items():
188
# Dictionaries (like 'DEFINES') are converted to lists to
189
# conform to waf conventions.
190
if isinstance(val, dict):
191
keys = list(val.keys())
192
if not isinstance(val, OrderedDict):
193
keys.sort()
194
val = ['%s=%s' % (vk, val[vk]) for vk in keys]
195
196
if k in cfg.env and isinstance(cfg.env[k], list):
197
cfg.env.prepend_value(k, val)
198
else:
199
cfg.env[k] = val
200
201
cfg.ap_common_checks()
202
203
cfg.env.prepend_value('INCLUDES', [
204
cfg.srcnode.find_dir('libraries/AP_Common/missing').abspath()
205
])
206
if os.path.exists(os.path.join(env.SRCROOT, '.vscode/c_cpp_properties.json')) and 'AP_NO_COMPILE_COMMANDS' not in os.environ:
207
# change c_cpp_properties.json configure the VSCode Intellisense env
208
c_cpp_properties = json.load(open(os.path.join(env.SRCROOT, '.vscode/c_cpp_properties.json')))
209
for config in c_cpp_properties['configurations']:
210
config['compileCommands'] = "${workspaceFolder}/build/%s/compile_commands.json" % self.get_name()
211
json.dump(c_cpp_properties, open(os.path.join(env.SRCROOT, './.vscode/c_cpp_properties.json'), 'w'), indent=4)
212
cfg.msg("Configured VSCode Intellisense", 'yes')
213
else:
214
cfg.msg("Configured VSCode Intellisense:", 'no', color='YELLOW')
215
216
def cc_version_gte(self, cfg, want_major, want_minor):
217
if cfg.env.TOOLCHAIN == "custom":
218
return True
219
(major, minor, patchlevel) = cfg.env.CC_VERSION
220
return (int(major) > want_major or
221
(int(major) == want_major and int(minor) >= want_minor))
222
223
def configure_env(self, cfg, env):
224
# Use a dictionary instead of the conventional list for definitions to
225
# make easy to override them. Convert back to list before consumption.
226
env.DEFINES = {}
227
228
env.with_can = self.with_can
229
230
# potentially set extra defines from an environment variable:
231
if cfg.options.define is not None:
232
for (n, v) in [d.split("=") for d in cfg.options.define]:
233
cfg.msg("Defining: %s" % (n, ), v)
234
env.CFLAGS += ['-D%s=%s' % (n, v)]
235
env.CXXFLAGS += ['-D%s=%s' % (n, v)]
236
237
env.CFLAGS += [
238
'-ffunction-sections',
239
'-fdata-sections',
240
'-fsigned-char',
241
242
'-Wall',
243
'-Wextra',
244
'-Werror=format',
245
'-Wpointer-arith',
246
'-Wcast-align',
247
'-Wno-missing-field-initializers',
248
'-Wno-unused-parameter',
249
'-Wno-redundant-decls',
250
'-Wno-unknown-pragmas',
251
'-Wno-trigraphs',
252
'-Werror=shadow',
253
'-Werror=return-type',
254
'-Werror=unused-result',
255
'-Werror=unused-variable',
256
'-Werror=narrowing',
257
'-Werror=attributes',
258
'-Werror=overflow',
259
'-Werror=parentheses',
260
'-Werror=format-extra-args',
261
'-Werror=ignored-qualifiers',
262
'-Werror=undef',
263
'-DARDUPILOT_BUILD',
264
]
265
266
if cfg.options.scripting_checks:
267
env.DEFINES.update(
268
AP_SCRIPTING_CHECKS = 1,
269
)
270
271
cfg.msg("CXX Compiler", "%s %s" % (cfg.env.COMPILER_CXX, ".".join(cfg.env.CC_VERSION)))
272
273
if cfg.options.assert_cc_version:
274
cfg.msg("Checking compiler", "%s %s" % (cfg.options.assert_cc_version, ".".join(cfg.env.CC_VERSION)))
275
have_version = cfg.env.COMPILER_CXX+"-"+'.'.join(list(cfg.env.CC_VERSION))
276
want_version = cfg.options.assert_cc_version
277
if have_version != want_version:
278
cfg.fatal("cc version mismatch: %s should be %s" % (have_version, want_version))
279
280
if 'clang' in cfg.env.COMPILER_CC:
281
env.CFLAGS += [
282
'-fcolor-diagnostics',
283
'-Wno-gnu-designator',
284
'-Wno-inconsistent-missing-override',
285
'-Wno-mismatched-tags',
286
'-Wno-gnu-variable-sized-type-not-at-end',
287
'-Werror=implicit-fallthrough',
288
'-cl-single-precision-constant',
289
]
290
env.CXXFLAGS += [
291
'-cl-single-precision-constant',
292
]
293
else:
294
env.CFLAGS += [
295
'-Wno-format-contains-nul',
296
'-fsingle-precision-constant', # force const vals to be float , not double. so 100.0 means 100.0f
297
]
298
if self.cc_version_gte(cfg, 7, 4):
299
env.CXXFLAGS += [
300
'-Werror=implicit-fallthrough',
301
]
302
env.CXXFLAGS += [
303
'-fsingle-precision-constant',
304
'-Wno-psabi',
305
]
306
307
if cfg.env.DEBUG:
308
env.CFLAGS += [
309
'-g',
310
'-O0',
311
]
312
env.DEFINES.update(
313
HAL_DEBUG_BUILD = 1,
314
)
315
elif cfg.options.debug_symbols:
316
env.CFLAGS += [
317
'-g',
318
]
319
if cfg.env.COVERAGE:
320
env.CFLAGS += [
321
'-fprofile-arcs',
322
'-ftest-coverage',
323
]
324
env.CXXFLAGS += [
325
'-fprofile-arcs',
326
'-ftest-coverage',
327
]
328
env.LINKFLAGS += [
329
'-lgcov',
330
'-coverage',
331
]
332
env.DEFINES.update(
333
HAL_COVERAGE_BUILD = 1,
334
)
335
336
if cfg.options.bootloader:
337
# don't let bootloaders try and pull scripting in
338
cfg.options.disable_scripting = True
339
if cfg.options.signed_fw:
340
env.DEFINES.update(
341
ENABLE_HEAP = 1,
342
)
343
else:
344
env.DEFINES.update(
345
ENABLE_HEAP = 1,
346
)
347
348
if cfg.options.enable_math_check_indexes:
349
env.CXXFLAGS += ['-DMATH_CHECK_INDEXES']
350
351
if cfg.options.private_key:
352
env.PRIVATE_KEY = cfg.options.private_key
353
354
env.CXXFLAGS += [
355
'-std=gnu++11',
356
357
'-fdata-sections',
358
'-ffunction-sections',
359
'-fno-exceptions',
360
'-fsigned-char',
361
362
'-Wall',
363
'-Wextra',
364
'-Wpointer-arith',
365
'-Wno-unused-parameter',
366
'-Wno-missing-field-initializers',
367
'-Wno-redundant-decls',
368
'-Wno-unknown-pragmas',
369
'-Wno-expansion-to-defined',
370
'-Werror=reorder',
371
'-Werror=cast-align',
372
'-Werror=attributes',
373
'-Werror=format-security',
374
'-Werror=format-extra-args',
375
'-Werror=enum-compare',
376
'-Werror=format',
377
'-Werror=array-bounds',
378
'-Werror=uninitialized',
379
'-Werror=init-self',
380
'-Werror=narrowing',
381
'-Werror=return-type',
382
'-Werror=switch',
383
'-Werror=sign-compare',
384
'-Werror=type-limits',
385
'-Werror=undef',
386
'-Werror=unused-result',
387
'-Werror=shadow',
388
'-Werror=unused-value',
389
'-Werror=unused-variable',
390
'-Werror=delete-non-virtual-dtor',
391
'-Wfatal-errors',
392
'-Wno-trigraphs',
393
'-Werror=parentheses',
394
'-DARDUPILOT_BUILD',
395
'-Wuninitialized',
396
'-Warray-bounds',
397
]
398
399
if 'clang++' in cfg.env.COMPILER_CXX:
400
env.CXXFLAGS += [
401
'-fcolor-diagnostics',
402
403
'-Werror=address-of-packed-member',
404
405
'-Werror=inconsistent-missing-override',
406
'-Werror=overloaded-virtual',
407
408
# catch conversion issues:
409
'-Werror=bitfield-enum-conversion',
410
'-Werror=bool-conversion',
411
'-Werror=constant-conversion',
412
'-Werror=enum-conversion',
413
'-Werror=int-conversion',
414
'-Werror=literal-conversion',
415
'-Werror=non-literal-null-conversion',
416
'-Werror=null-conversion',
417
'-Werror=objc-literal-conversion',
418
# '-Werror=shorten-64-to-32', # ARRAY_SIZE() creates this all over the place as the caller typically takes a uint32_t not a size_t
419
'-Werror=string-conversion',
420
# '-Werror=sign-conversion', # can't use as we assign into AP_Int8 from uint8_ts
421
422
'-Wno-gnu-designator',
423
'-Wno-mismatched-tags',
424
'-Wno-gnu-variable-sized-type-not-at-end',
425
'-Werror=implicit-fallthrough',
426
]
427
else:
428
env.CXXFLAGS += [
429
'-Wno-format-contains-nul',
430
'-Werror=unused-but-set-variable'
431
]
432
if self.cc_version_gte(cfg, 5, 2):
433
env.CXXFLAGS += [
434
'-Werror=suggest-override',
435
]
436
if self.cc_version_gte(cfg, 7, 4):
437
env.CXXFLAGS += [
438
'-Werror=implicit-fallthrough',
439
'-Werror=maybe-uninitialized',
440
'-Werror=duplicated-cond',
441
]
442
if self.cc_version_gte(cfg, 8, 4):
443
env.CXXFLAGS += [
444
'-Werror=sizeof-pointer-div',
445
]
446
if self.cc_version_gte(cfg, 13, 2):
447
env.CXXFLAGS += [
448
'-Werror=use-after-free',
449
]
450
env.CFLAGS += [
451
'-Werror=use-after-free',
452
]
453
454
if cfg.options.Werror:
455
errors = ['-Werror',
456
'-Werror=missing-declarations',
457
'-Werror=float-equal',
458
'-Werror=undef',
459
]
460
env.CFLAGS += errors
461
env.CXXFLAGS += errors
462
463
if cfg.env.DEBUG:
464
env.CXXFLAGS += [
465
'-g',
466
'-O0',
467
]
468
469
if cfg.env.DEST_OS == 'darwin':
470
if self.cc_version_gte(cfg, 15, 0):
471
env.LINKFLAGS += [
472
'-Wl,-dead_strip,-ld_classic',
473
]
474
else:
475
env.LINKFLAGS += [
476
'-Wl,-dead_strip',
477
]
478
else:
479
env.LINKFLAGS += [
480
'-fno-exceptions',
481
'-Wl,--gc-sections',
482
]
483
484
if self.with_can:
485
# for both AP_Perip and main fw enable deadlines
486
env.DEFINES.update(CANARD_ENABLE_DEADLINE = 1)
487
488
if not cfg.env.AP_PERIPH:
489
env.AP_LIBRARIES += [
490
'AP_DroneCAN',
491
'modules/DroneCAN/libcanard/*.c',
492
]
493
if cfg.options.enable_dronecan_tests:
494
env.DEFINES.update(AP_TEST_DRONECAN_DRIVERS = 1)
495
496
env.DEFINES.update(
497
DRONECAN_CXX_WRAPPERS = 1,
498
USE_USER_HELPERS = 1,
499
CANARD_ALLOCATE_SEM=1
500
)
501
502
503
504
if cfg.options.build_dates:
505
env.build_dates = True
506
507
# We always want to use PRI format macros
508
cfg.define('__STDC_FORMAT_MACROS', 1)
509
510
if cfg.options.postype_single:
511
env.CXXFLAGS += ['-DHAL_WITH_POSTYPE_DOUBLE=0']
512
513
if cfg.options.osd or cfg.options.osd_fonts:
514
env.CXXFLAGS += ['-DOSD_ENABLED=1', '-DHAL_MSP_ENABLED=1']
515
516
if cfg.options.osd_fonts:
517
for f in os.listdir('libraries/AP_OSD/fonts'):
518
if fnmatch.fnmatch(f, "font*bin"):
519
env.ROMFS_FILES += [(f,'libraries/AP_OSD/fonts/'+f)]
520
521
if cfg.options.ekf_double:
522
env.CXXFLAGS += ['-DHAL_WITH_EKF_DOUBLE=1']
523
524
if cfg.options.ekf_single:
525
env.CXXFLAGS += ['-DHAL_WITH_EKF_DOUBLE=0']
526
527
if cfg.options.consistent_builds:
528
# squash all line numbers to be the number 17
529
env.CXXFLAGS += [
530
"-D__AP_LINE__=17",
531
]
532
else:
533
env.CXXFLAGS += [
534
"-D__AP_LINE__=__LINE__",
535
]
536
537
# add files from ROMFS_custom
538
custom_dir = 'ROMFS_custom'
539
if os.path.exists(custom_dir):
540
for root, subdirs, files in os.walk(custom_dir):
541
for f in files:
542
if fnmatch.fnmatch(f,"*~"):
543
# exclude emacs tmp files
544
continue
545
fname = root[len(custom_dir)+1:]+"/"+f
546
if fname.startswith("/"):
547
fname = fname[1:]
548
env.ROMFS_FILES += [(fname,root+"/"+f)]
549
550
def pre_build(self, bld):
551
'''pre-build hook that gets called before dynamic sources'''
552
if bld.env.ROMFS_FILES:
553
self.embed_ROMFS_files(bld)
554
555
def build(self, bld):
556
bld.ap_version_append_str('GIT_VERSION', bld.git_head_hash(short=True))
557
bld.ap_version_append_int('GIT_VERSION_INT', int("0x" + bld.git_head_hash(short=True), base=16))
558
bld.ap_version_append_str('AP_BUILD_ROOT', bld.srcnode.abspath())
559
import time
560
ltime = time.localtime()
561
if bld.env.build_dates:
562
bld.ap_version_append_int('BUILD_DATE_YEAR', ltime.tm_year)
563
bld.ap_version_append_int('BUILD_DATE_MONTH', ltime.tm_mon)
564
bld.ap_version_append_int('BUILD_DATE_DAY', ltime.tm_mday)
565
566
def embed_ROMFS_files(self, ctx):
567
'''embed some files using AP_ROMFS'''
568
import embed
569
header = ctx.bldnode.make_node('ap_romfs_embedded.h').abspath()
570
if not embed.create_embedded_h(header, ctx.env.ROMFS_FILES, ctx.env.ROMFS_UNCOMPRESSED):
571
ctx.fatal("Failed to created ap_romfs_embedded.h")
572
573
ctx.env.CXXFLAGS += ['-DHAL_HAVE_AP_ROMFS_EMBEDDED_H']
574
575
# Allow lua to load from ROMFS if any lua files are added
576
for file in ctx.env.ROMFS_FILES:
577
if file[0].startswith("scripts") and file[0].endswith(".lua"):
578
ctx.env.CXXFLAGS += ['-DHAL_HAVE_AP_ROMFS_EMBEDDED_LUA']
579
break
580
581
Board = BoardMeta('Board', Board.__bases__, dict(Board.__dict__))
582
583
def add_dynamic_boards_chibios():
584
'''add boards based on existance of hwdef.dat in subdirectories for ChibiOS'''
585
dirname, dirlist, filenames = next(os.walk('libraries/AP_HAL_ChibiOS/hwdef'))
586
for d in dirlist:
587
if d in _board_classes.keys():
588
continue
589
hwdef = os.path.join(dirname, d, 'hwdef.dat')
590
if os.path.exists(hwdef):
591
newclass = type(d, (chibios,), {'name': d})
592
593
@conf
594
def get_chibios_board_cls(ctx, name, hwdef):
595
if name in _board_classes.keys():
596
_board_classes[name].hwdef = hwdef
597
return _board_classes[name]
598
newclass = type(name, (chibios,), {'name': name})
599
newclass.hwdef = hwdef
600
return newclass
601
602
def add_dynamic_boards_esp32():
603
'''add boards based on existance of hwdef.dat in subdirectories for ESP32'''
604
dirname, dirlist, filenames = next(os.walk('libraries/AP_HAL_ESP32/hwdef'))
605
for d in dirlist:
606
if d in _board_classes.keys():
607
continue
608
hwdef = os.path.join(dirname, d, 'hwdef.dat')
609
if os.path.exists(hwdef):
610
mcu_esp32s3 = True if (d[0:7] == "esp32s3") else False
611
if mcu_esp32s3:
612
newclass = type(d, (esp32s3,), {'name': d})
613
else:
614
newclass = type(d, (esp32,), {'name': d})
615
616
def get_boards_names():
617
add_dynamic_boards_chibios()
618
add_dynamic_boards_esp32()
619
620
return sorted(list(_board_classes.keys()), key=str.lower)
621
622
def is_board_based(board, cls):
623
return issubclass(_board_classes[board], cls)
624
625
def get_ap_periph_boards():
626
'''Add AP_Periph boards based on existance of periph keywork in hwdef.dat or board name'''
627
list_ap = [s for s in list(_board_classes.keys()) if "periph" in s]
628
dirname, dirlist, filenames = next(os.walk('libraries/AP_HAL_ChibiOS/hwdef'))
629
for d in dirlist:
630
if d in list_ap:
631
continue
632
hwdef = os.path.join(dirname, d, 'hwdef.dat')
633
if os.path.exists(hwdef):
634
ch = chibios_hwdef.ChibiOSHWDef(hwdef=[hwdef], quiet=True)
635
try:
636
if ch.is_periph_fw_unprocessed():
637
list_ap.append(d)
638
except chibios_hwdef.ChibiOSHWDefIncludeNotFoundException as e:
639
print(f"{e.includer} includes {e.hwdef} which does not exist")
640
sys.exit(1)
641
642
list_ap = list(set(list_ap))
643
return list_ap
644
645
def get_removed_boards():
646
'''list of boards which have been removed'''
647
return sorted(['px4-v1', 'px4-v2', 'px4-v3', 'px4-v4', 'px4-v4pro'])
648
649
@conf
650
def get_board(ctx):
651
global _board
652
if not _board:
653
if not ctx.env.BOARD:
654
ctx.fatal('BOARD environment variable must be set before first call to get_board()')
655
if ctx.env.BOARD in get_removed_boards():
656
ctx.fatal('''
657
The board target %s has been removed from ArduPilot with the removal of NuttX support and HAL_PX4.
658
659
Please use a replacement build as follows:
660
661
px4-v2 Use Pixhawk1 build
662
px4-v3 Use Pixhawk1 or CubeBlack builds
663
px4-v4 Use Pixracer build
664
px4-v4pro Use DrotekP3Pro build
665
''' % ctx.env.BOARD)
666
667
boards = _board_classes.keys()
668
if ctx.env.BOARD not in boards:
669
ctx.fatal("Invalid board '%s': choices are %s" % (ctx.env.BOARD, ', '.join(sorted(boards, key=str.lower))))
670
_board = _board_classes[ctx.env.BOARD]()
671
return _board
672
673
# NOTE: Keeping all the board definitions together so we can easily
674
# identify opportunities to simplify common flags. In the future might
675
# be worthy to keep board definitions in files of their own.
676
677
class sitl(Board):
678
679
def __init__(self):
680
self.with_can = True
681
682
def configure_env(self, cfg, env):
683
super(sitl, self).configure_env(cfg, env)
684
env.DEFINES.update(
685
CONFIG_HAL_BOARD = 'HAL_BOARD_SITL',
686
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_NONE',
687
AP_SCRIPTING_CHECKS = 1, # SITL should always do runtime scripting checks
688
AP_BARO_PROBE_EXTERNAL_I2C_BUSES = 1,
689
)
690
691
env.BOARD_CLASS = "SITL"
692
693
cfg.define('AP_SIM_ENABLED', 1)
694
cfg.define('HAL_WITH_SPI', 1)
695
cfg.define('HAL_WITH_RAMTRON', 1)
696
cfg.define('AP_OPENDRONEID_ENABLED', 1)
697
cfg.define('AP_SIGNED_FIRMWARE', 0)
698
699
cfg.define('AP_NOTIFY_LP5562_BUS', 2)
700
cfg.define('AP_NOTIFY_LP5562_ADDR', 0x30)
701
702
# turn on fencepoint and rallypoint protocols so they're still tested:
703
env.CXXFLAGS.extend([
704
'-DAP_MAVLINK_RALLY_POINT_PROTOCOL_ENABLED=HAL_GCS_ENABLED&&HAL_RALLY_ENABLED',
705
'-DAC_POLYFENCE_FENCE_POINT_PROTOCOL_SUPPORT=HAL_GCS_ENABLED&&AP_FENCE_ENABLED'
706
])
707
708
try:
709
env.CXXFLAGS.remove('-DHAL_NAVEKF2_AVAILABLE=0')
710
except ValueError:
711
pass
712
env.CXXFLAGS += ['-DHAL_NAVEKF2_AVAILABLE=1']
713
714
if self.with_can:
715
cfg.define('HAL_NUM_CAN_IFACES', 2)
716
env.DEFINES.update(CANARD_MULTI_IFACE=1,
717
CANARD_IFACE_ALL = 0x3,
718
CANARD_ENABLE_CANFD = 1,
719
CANARD_ENABLE_ASSERTS = 1)
720
if not cfg.options.force_32bit:
721
# needed for cygwin
722
env.CXXFLAGS += [ '-DCANARD_64_BIT=1' ]
723
env.CFLAGS += [ '-DCANARD_64_BIT=1' ]
724
if Utils.unversioned_sys_platform().startswith("linux"):
725
cfg.define('HAL_CAN_WITH_SOCKETCAN', 1)
726
else:
727
cfg.define('HAL_CAN_WITH_SOCKETCAN', 0)
728
729
env.CXXFLAGS += [
730
'-Werror=float-equal',
731
'-Werror=missing-declarations',
732
]
733
734
if not cfg.options.disable_networking and not 'clang' in cfg.env.COMPILER_CC:
735
# lwip doesn't build with clang
736
env.CXXFLAGS += ['-DAP_NETWORKING_ENABLED=1']
737
738
if cfg.options.ubsan or cfg.options.ubsan_abort:
739
env.CXXFLAGS += [
740
"-fsanitize=undefined",
741
"-fsanitize=float-cast-overflow",
742
"-DUBSAN_ENABLED",
743
]
744
env.LINKFLAGS += [
745
"-fsanitize=undefined",
746
"-lubsan",
747
]
748
749
if cfg.options.ubsan_abort:
750
env.CXXFLAGS += [
751
"-fno-sanitize-recover"
752
]
753
754
if not cfg.env.DEBUG:
755
env.CXXFLAGS += [
756
'-O3',
757
]
758
759
if 'clang++' in cfg.env.COMPILER_CXX and cfg.options.asan:
760
env.CXXFLAGS += [
761
'-fsanitize=address',
762
'-fno-omit-frame-pointer',
763
]
764
765
env.LIB += [
766
'm',
767
]
768
769
cfg.check_librt(env)
770
cfg.check_feenableexcept()
771
772
env.LINKFLAGS += ['-pthread',]
773
774
if cfg.env.DEBUG and 'clang++' in cfg.env.COMPILER_CXX and cfg.options.asan:
775
env.LINKFLAGS += ['-fsanitize=address']
776
777
env.AP_LIBRARIES += [
778
'AP_HAL_SITL',
779
'AP_CSVReader',
780
]
781
782
env.AP_LIBRARIES += [
783
'SITL',
784
]
785
786
# wrap malloc to ensure memory is zeroed
787
if cfg.env.DEST_OS == 'cygwin':
788
# on cygwin we need to wrap _malloc_r instead
789
env.LINKFLAGS += ['-Wl,--wrap,_malloc_r']
790
elif platform.system() != 'Darwin':
791
env.LINKFLAGS += ['-Wl,--wrap,malloc']
792
793
if cfg.options.enable_sfml:
794
if not cfg.check_SFML(env):
795
cfg.fatal("Failed to find SFML libraries")
796
797
if cfg.options.enable_sfml_joystick:
798
if not cfg.check_SFML(env):
799
cfg.fatal("Failed to find SFML libraries")
800
env.CXXFLAGS += ['-DSFML_JOYSTICK']
801
802
if cfg.options.sitl_osd:
803
env.CXXFLAGS += ['-DWITH_SITL_OSD','-DOSD_ENABLED=1']
804
for f in os.listdir('libraries/AP_OSD/fonts'):
805
if fnmatch.fnmatch(f, "font*bin"):
806
env.ROMFS_FILES += [(f,'libraries/AP_OSD/fonts/'+f)]
807
808
for f in os.listdir('Tools/autotest/models'):
809
if fnmatch.fnmatch(f, "*.json") or fnmatch.fnmatch(f, "*.parm"):
810
env.ROMFS_FILES += [('models/'+f,'Tools/autotest/models/'+f)]
811
812
# include locations.txt so SITL on windows can lookup by name
813
env.ROMFS_FILES += [('locations.txt','Tools/autotest/locations.txt')]
814
815
# embed any scripts from ROMFS/scripts
816
if os.path.exists('ROMFS/scripts'):
817
for f in os.listdir('ROMFS/scripts'):
818
if fnmatch.fnmatch(f, "*.lua"):
819
env.ROMFS_FILES += [('scripts/'+f,'ROMFS/scripts/'+f)]
820
821
if cfg.options.sitl_rgbled:
822
env.CXXFLAGS += ['-DWITH_SITL_RGBLED']
823
824
if cfg.options.enable_sfml_audio:
825
if not cfg.check_SFML_Audio(env):
826
cfg.fatal("Failed to find SFML Audio libraries")
827
env.CXXFLAGS += ['-DWITH_SITL_TONEALARM']
828
829
if cfg.env.DEST_OS == 'cygwin':
830
env.LIB += [
831
'winmm',
832
]
833
834
if Utils.unversioned_sys_platform() == 'cygwin':
835
env.CXXFLAGS += ['-DCYGWIN_BUILD']
836
837
if 'clang++' in cfg.env.COMPILER_CXX:
838
print("Disabling SLP for clang++")
839
env.CXXFLAGS += [
840
'-fno-slp-vectorize' # compiler bug when trying to use SLP
841
]
842
843
if cfg.options.force_32bit:
844
# 32bit platform flags
845
env.CXXFLAGS += [
846
'-m32',
847
]
848
env.CFLAGS += [
849
'-m32',
850
]
851
env.LDFLAGS += [
852
'-m32',
853
]
854
855
# whitelist of compilers which we should build with -Werror
856
gcc_whitelist = frozenset([
857
('11','3','0'),
858
('11','4','0'),
859
('12','1','0'),
860
])
861
862
# initialise werr_enabled from defaults:
863
werr_enabled = bool('g++' in cfg.env.COMPILER_CXX and cfg.env.CC_VERSION in gcc_whitelist)
864
865
# now process overrides to that default:
866
if (cfg.options.Werror is not None and
867
cfg.options.Werror == cfg.options.disable_Werror):
868
cfg.fatal("Asked to both enable and disable Werror")
869
870
if cfg.options.Werror is not None:
871
werr_enabled = cfg.options.Werror
872
elif cfg.options.disable_Werror is not None:
873
werr_enabled = not cfg.options.disable_Werror
874
875
if werr_enabled:
876
cfg.msg("Enabling -Werror", "yes")
877
if '-Werror' not in env.CXXFLAGS:
878
env.CXXFLAGS += [ '-Werror' ]
879
else:
880
cfg.msg("Enabling -Werror", "no")
881
if '-Werror' in env.CXXFLAGS:
882
env.CXXFLAGS.remove('-Werror')
883
884
def get_name(self):
885
return self.__class__.__name__
886
887
888
class sitl_periph(sitl):
889
def configure_env(self, cfg, env):
890
cfg.env.AP_PERIPH = 1
891
super(sitl_periph, self).configure_env(cfg, env)
892
env.DEFINES.update(
893
HAL_BUILD_AP_PERIPH = 1,
894
PERIPH_FW = 1,
895
HAL_RAM_RESERVE_START = 0,
896
897
CANARD_ENABLE_CANFD = 1,
898
CANARD_ENABLE_TAO_OPTION = 1,
899
CANARD_MULTI_IFACE = 1,
900
901
# FIXME: SITL library should not be using AP_AHRS:
902
AP_AHRS_ENABLED = 1,
903
AP_AHRS_BACKEND_DEFAULT_ENABLED = 0,
904
AP_AHRS_DCM_ENABLED = 1, # need a default backend
905
HAL_EXTERNAL_AHRS_ENABLED = 0,
906
907
HAL_MAVLINK_BINDINGS_ENABLED = 1,
908
909
AP_AIRSPEED_AUTOCAL_ENABLE = 0,
910
AP_CAN_SLCAN_ENABLED = 0,
911
AP_ICENGINE_ENABLED = 0,
912
AP_MISSION_ENABLED = 0,
913
AP_RCPROTOCOL_ENABLED = 0,
914
AP_RTC_ENABLED = 0,
915
AP_SCHEDULER_ENABLED = 0,
916
AP_SCRIPTING_ENABLED = 0,
917
AP_STATS_ENABLED = 0,
918
AP_UART_MONITOR_ENABLED = 1,
919
COMPASS_CAL_ENABLED = 0,
920
COMPASS_LEARN_ENABLED = 0,
921
COMPASS_MOT_ENABLED = 0,
922
HAL_CAN_DEFAULT_NODE_ID = 0,
923
HAL_CANMANAGER_ENABLED = 0,
924
HAL_GCS_ENABLED = 0,
925
HAL_GENERATOR_ENABLED = 0,
926
HAL_LOGGING_ENABLED = 0,
927
HAL_LOGGING_MAVLINK_ENABLED = 0,
928
HAL_PROXIMITY_ENABLED = 0,
929
HAL_RALLY_ENABLED = 0,
930
HAL_SUPPORT_RCOUT_SERIAL = 0,
931
AP_TERRAIN_AVAILABLE = 0,
932
AP_CUSTOMROTATIONS_ENABLED = 0,
933
)
934
935
try:
936
env.CXXFLAGS.remove('-DHAL_NAVEKF2_AVAILABLE=1')
937
except ValueError:
938
pass
939
env.CXXFLAGS += ['-DHAL_NAVEKF2_AVAILABLE=0']
940
941
class sitl_periph_universal(sitl_periph):
942
def configure_env(self, cfg, env):
943
super(sitl_periph_universal, self).configure_env(cfg, env)
944
env.DEFINES.update(
945
CAN_APP_NODE_NAME = '"org.ardupilot.ap_periph_universal"',
946
APJ_BOARD_ID = 100,
947
948
HAL_PERIPH_ENABLE_GPS = 1,
949
HAL_PERIPH_ENABLE_AIRSPEED = 1,
950
HAL_PERIPH_ENABLE_MAG = 1,
951
HAL_PERIPH_ENABLE_BARO = 1,
952
HAL_PERIPH_ENABLE_IMU = 1,
953
HAL_PERIPH_ENABLE_RANGEFINDER = 1,
954
HAL_PERIPH_ENABLE_BATTERY = 1,
955
HAL_PERIPH_ENABLE_EFI = 1,
956
HAL_PERIPH_ENABLE_RPM = 1,
957
HAL_PERIPH_ENABLE_RPM_STREAM = 1,
958
HAL_PERIPH_ENABLE_RC_OUT = 1,
959
HAL_PERIPH_ENABLE_ADSB = 1,
960
HAL_PERIPH_ENABLE_SERIAL_OPTIONS = 1,
961
AP_AIRSPEED_ENABLED = 1,
962
AP_BATTERY_ESC_ENABLED = 1,
963
HAL_PWM_COUNT = 32,
964
HAL_WITH_ESC_TELEM = 1,
965
AP_EXTENDED_ESC_TELEM_ENABLED = 1,
966
AP_TERRAIN_AVAILABLE = 1,
967
HAL_GYROFFT_ENABLED = 0,
968
)
969
970
class sitl_periph_gps(sitl_periph):
971
def configure_env(self, cfg, env):
972
cfg.env.AP_PERIPH = 1
973
super(sitl_periph_gps, self).configure_env(cfg, env)
974
env.DEFINES.update(
975
HAL_BUILD_AP_PERIPH = 1,
976
PERIPH_FW = 1,
977
CAN_APP_NODE_NAME = '"org.ardupilot.ap_periph_gps"',
978
APJ_BOARD_ID = 101,
979
980
HAL_PERIPH_ENABLE_GPS = 1,
981
)
982
983
class sitl_periph_battmon(sitl_periph):
984
def configure_env(self, cfg, env):
985
cfg.env.AP_PERIPH = 1
986
super(sitl_periph_battmon, self).configure_env(cfg, env)
987
env.DEFINES.update(
988
HAL_BUILD_AP_PERIPH = 1,
989
PERIPH_FW = 1,
990
CAN_APP_NODE_NAME = '"org.ardupilot.ap_periph_battmon"',
991
APJ_BOARD_ID = 101,
992
993
HAL_PERIPH_ENABLE_BATTERY = 1,
994
)
995
996
class esp32(Board):
997
abstract = True
998
toolchain = 'xtensa-esp32-elf'
999
def configure_env(self, cfg, env):
1000
env.BOARD_CLASS = "ESP32"
1001
1002
def expand_path(p):
1003
print("USING EXPRESSIF IDF:"+str(env.idf))
1004
return cfg.root.find_dir(env.IDF+p).abspath()
1005
try:
1006
env.IDF = os.environ['IDF_PATH']
1007
except:
1008
env.IDF = cfg.srcnode.abspath()+"/modules/esp_idf"
1009
1010
super(esp32, self).configure_env(cfg, env)
1011
cfg.load('esp32')
1012
env.DEFINES.update(
1013
CONFIG_HAL_BOARD = 'HAL_BOARD_ESP32',
1014
)
1015
1016
tt = self.name[5:] #leave off 'esp32' so we just get 'buzz','diy','icarus, etc
1017
1018
# this makes sure we get the correct subtype
1019
env.DEFINES.update(
1020
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_ESP32_%s' % tt.upper() ,
1021
)
1022
1023
if self.name.endswith("empty"):
1024
# for empty targets build as SIM-on-HW
1025
env.DEFINES.update(AP_SIM_ENABLED = 1)
1026
env.AP_LIBRARIES += [
1027
'SITL',
1028
]
1029
else:
1030
env.DEFINES.update(AP_SIM_ENABLED = 0)
1031
1032
# FreeRTOS component from esp-idf expects this define
1033
env.DEFINES.update(ESP_PLATFORM = 1)
1034
1035
env.AP_LIBRARIES += [
1036
'AP_HAL_ESP32',
1037
]
1038
1039
env.CFLAGS += [
1040
'-fno-inline-functions',
1041
'-mlongcalls',
1042
'-fsingle-precision-constant',
1043
]
1044
env.CFLAGS.remove('-Werror=undef')
1045
1046
env.CXXFLAGS += ['-mlongcalls',
1047
'-Os',
1048
'-g',
1049
'-ffunction-sections',
1050
'-fdata-sections',
1051
'-fno-exceptions',
1052
'-fno-rtti',
1053
'-nostdlib',
1054
'-fstrict-volatile-bitfields',
1055
'-Wno-sign-compare',
1056
'-fno-inline-functions',
1057
'-mlongcalls',
1058
'-fsingle-precision-constant', # force const vals to be float , not double. so 100.0 means 100.0f
1059
'-fno-threadsafe-statics']
1060
env.CXXFLAGS.remove('-Werror=undef')
1061
env.CXXFLAGS.remove('-Werror=shadow')
1062
1063
# wrap malloc to ensure memory is zeroed
1064
env.LINKFLAGS += ['-Wl,--wrap,malloc']
1065
1066
# TODO: remove once hwdef.dat support is in place
1067
defaults_file = 'libraries/AP_HAL_ESP32/hwdef/%s/defaults.parm' % self.get_name()
1068
if os.path.exists(defaults_file):
1069
env.ROMFS_FILES += [('defaults.parm', defaults_file)]
1070
env.DEFINES.update(
1071
HAL_PARAM_DEFAULTS_PATH='"@ROMFS/defaults.parm"',
1072
)
1073
1074
env.INCLUDES += [
1075
cfg.srcnode.find_dir('libraries/AP_HAL_ESP32/boards').abspath(),
1076
]
1077
env.AP_PROGRAM_AS_STLIB = True
1078
#if cfg.options.enable_profile:
1079
# env.CXXFLAGS += ['-pg',
1080
# '-DENABLE_PROFILE=1']
1081
def pre_build(self, bld):
1082
'''pre-build hook that gets called before dynamic sources'''
1083
from waflib.Context import load_tool
1084
module = load_tool('esp32', [], with_sys_path=True)
1085
fun = getattr(module, 'pre_build', None)
1086
if fun:
1087
fun(bld)
1088
super(esp32, self).pre_build(bld)
1089
1090
1091
def build(self, bld):
1092
super(esp32, self).build(bld)
1093
bld.load('esp32')
1094
1095
def get_name(self):
1096
return self.__class__.__name__
1097
1098
class esp32s3(esp32):
1099
abstract = True
1100
toolchain = 'xtensa-esp32s3-elf'
1101
1102
class chibios(Board):
1103
abstract = True
1104
toolchain = 'arm-none-eabi'
1105
1106
def configure_env(self, cfg, env):
1107
if hasattr(self, 'hwdef'):
1108
cfg.env.HWDEF = self.hwdef
1109
super(chibios, self).configure_env(cfg, env)
1110
1111
cfg.load('chibios')
1112
env.BOARD = self.name
1113
env.BOARD_CLASS = "ChibiOS"
1114
1115
env.DEFINES.update(
1116
CONFIG_HAL_BOARD = 'HAL_BOARD_CHIBIOS',
1117
HAVE_STD_NULLPTR_T = 0,
1118
USE_LIBC_REALLOC = 0,
1119
)
1120
1121
env.AP_LIBRARIES += [
1122
'AP_HAL_ChibiOS',
1123
]
1124
1125
# make board name available for USB IDs
1126
env.CHIBIOS_BOARD_NAME = 'HAL_BOARD_NAME="%s"' % self.name
1127
env.HAL_MAX_STACK_FRAME_SIZE = 'HAL_MAX_STACK_FRAME_SIZE=%d' % 1300 # set per Wframe-larger-than, ensure its same
1128
env.CFLAGS += cfg.env.CPU_FLAGS + [
1129
'-Wlogical-op',
1130
'-Wframe-larger-than=1300',
1131
'-Wno-attributes',
1132
'-fno-exceptions',
1133
'-Wall',
1134
'-Wextra',
1135
'-Wno-sign-compare',
1136
'-Wfloat-equal',
1137
'-Wpointer-arith',
1138
'-Wmissing-declarations',
1139
'-Wno-unused-parameter',
1140
'-Werror=array-bounds',
1141
'-Wfatal-errors',
1142
'-Werror=uninitialized',
1143
'-Werror=init-self',
1144
'-Werror=unused-but-set-variable',
1145
'-Wno-missing-field-initializers',
1146
'-Wno-trigraphs',
1147
'-fno-strict-aliasing',
1148
'-fomit-frame-pointer',
1149
'-falign-functions=16',
1150
'-ffunction-sections',
1151
'-fdata-sections',
1152
'-fno-strength-reduce',
1153
'-fno-builtin-printf',
1154
'-fno-builtin-fprintf',
1155
'-fno-builtin-vprintf',
1156
'-fno-builtin-vfprintf',
1157
'-fno-builtin-puts',
1158
'-mno-thumb-interwork',
1159
'-mthumb',
1160
'--specs=nano.specs',
1161
'--specs=nosys.specs',
1162
'-D__USE_CMSIS',
1163
'-Werror=deprecated-declarations',
1164
'-DNDEBUG=1'
1165
]
1166
if not cfg.options.Werror:
1167
env.CFLAGS += [
1168
'-Wno-error=double-promotion',
1169
'-Wno-error=missing-declarations',
1170
'-Wno-error=float-equal',
1171
'-Wno-error=cpp',
1172
]
1173
1174
env.CXXFLAGS += env.CFLAGS + [
1175
'-fno-rtti',
1176
'-fno-threadsafe-statics',
1177
]
1178
env.CFLAGS += [
1179
'-std=c11'
1180
]
1181
1182
if Utils.unversioned_sys_platform() == 'cygwin':
1183
env.CXXFLAGS += ['-DCYGWIN_BUILD']
1184
1185
bldnode = cfg.bldnode.make_node(self.name)
1186
env.BUILDROOT = bldnode.make_node('').abspath()
1187
1188
env.LINKFLAGS = cfg.env.CPU_FLAGS + [
1189
'-fomit-frame-pointer',
1190
'-falign-functions=16',
1191
'-ffunction-sections',
1192
'-fdata-sections',
1193
'-u_port_lock',
1194
'-u_port_unlock',
1195
'-u_exit',
1196
'-u_kill',
1197
'-u_getpid',
1198
'-u_errno',
1199
'-uchThdExit',
1200
'-fno-common',
1201
'-nostartfiles',
1202
'-mno-thumb-interwork',
1203
'-mthumb',
1204
'--specs=nano.specs',
1205
'--specs=nosys.specs',
1206
'-L%s' % env.BUILDROOT,
1207
'-L%s' % cfg.srcnode.make_node('modules/ChibiOS/os/common/startup/ARMCMx/compilers/GCC/ld/').abspath(),
1208
'-L%s' % cfg.srcnode.make_node('libraries/AP_HAL_ChibiOS/hwdef/common/').abspath(),
1209
'-Wl,-Map,Linker.map,%s--cref,--gc-sections,--no-warn-mismatch,--library-path=/ld,--script=ldscript.ld,--defsym=__process_stack_size__=%s,--defsym=__main_stack_size__=%s' % ("--print-memory-usage," if cfg.env.EXT_FLASH_SIZE_MB > 0 and cfg.env.INT_FLASH_PRIMARY == 0 else "", cfg.env.PROCESS_STACK, cfg.env.MAIN_STACK)
1210
]
1211
1212
if cfg.env.DEBUG:
1213
env.CFLAGS += [
1214
'-gdwarf-4',
1215
'-g3',
1216
]
1217
env.LINKFLAGS += [
1218
'-gdwarf-4',
1219
'-g3',
1220
]
1221
1222
if cfg.env.COMPILER_CXX == "g++":
1223
if not self.cc_version_gte(cfg, 10, 2):
1224
# require at least 10.2 compiler
1225
cfg.fatal("ChibiOS build requires g++ version 10.2.1 or later, found %s" % '.'.join(cfg.env.CC_VERSION))
1226
1227
if cfg.env.ENABLE_ASSERTS:
1228
cfg.msg("Enabling ChibiOS asserts", "yes")
1229
env.CFLAGS += [ '-DHAL_CHIBIOS_ENABLE_ASSERTS' ]
1230
env.CXXFLAGS += [ '-DHAL_CHIBIOS_ENABLE_ASSERTS' ]
1231
else:
1232
cfg.msg("Enabling ChibiOS asserts", "no")
1233
1234
1235
if cfg.env.SAVE_TEMPS:
1236
env.CXXFLAGS += [ '-S', '-save-temps=obj' ]
1237
1238
if cfg.options.disable_watchdog:
1239
cfg.msg("Disabling Watchdog", "yes")
1240
env.CFLAGS += [ '-DDISABLE_WATCHDOG' ]
1241
env.CXXFLAGS += [ '-DDISABLE_WATCHDOG' ]
1242
else:
1243
cfg.msg("Disabling Watchdog", "no")
1244
1245
if cfg.env.ENABLE_MALLOC_GUARD:
1246
cfg.msg("Enabling malloc guard", "yes")
1247
env.CFLAGS += [ '-DHAL_CHIBIOS_ENABLE_MALLOC_GUARD' ]
1248
env.CXXFLAGS += [ '-DHAL_CHIBIOS_ENABLE_MALLOC_GUARD' ]
1249
else:
1250
cfg.msg("Enabling malloc guard", "no")
1251
1252
if cfg.env.ENABLE_STATS:
1253
cfg.msg("Enabling ChibiOS thread statistics", "yes")
1254
env.CFLAGS += [ '-DHAL_ENABLE_THREAD_STATISTICS' ]
1255
env.CXXFLAGS += [ '-DHAL_ENABLE_THREAD_STATISTICS' ]
1256
else:
1257
cfg.msg("Enabling ChibiOS thread statistics", "no")
1258
1259
if cfg.env.SIM_ENABLED:
1260
env.DEFINES.update(
1261
AP_SIM_ENABLED = 1,
1262
)
1263
env.AP_LIBRARIES += [
1264
'SITL',
1265
]
1266
else:
1267
env.DEFINES.update(
1268
AP_SIM_ENABLED = 0,
1269
)
1270
1271
env.LIB += ['gcc', 'm']
1272
1273
env.GIT_SUBMODULES += [
1274
'ChibiOS',
1275
]
1276
1277
env.INCLUDES += [
1278
cfg.srcnode.find_dir('libraries/AP_GyroFFT/CMSIS_5/include').abspath(),
1279
cfg.srcnode.find_dir('modules/lwip/src/include/compat/posix').abspath()
1280
]
1281
1282
# whitelist of compilers which we should build with -Werror
1283
gcc_whitelist = frozenset([
1284
('4','9','3'),
1285
('6','3','1'),
1286
('9','2','1'),
1287
('9','3','1'),
1288
('10','2','1'),
1289
('11','3','0'),
1290
('11','4','0'),
1291
])
1292
1293
if cfg.env.HAL_CANFD_SUPPORTED:
1294
env.DEFINES.update(CANARD_ENABLE_CANFD=1)
1295
else:
1296
env.DEFINES.update(CANARD_ENABLE_TAO_OPTION=1)
1297
if not cfg.options.bootloader and cfg.env.HAL_NUM_CAN_IFACES:
1298
if int(cfg.env.HAL_NUM_CAN_IFACES) >= 1:
1299
env.DEFINES.update(CANARD_IFACE_ALL=(1<<int(cfg.env.HAL_NUM_CAN_IFACES))-1)
1300
if cfg.options.Werror or cfg.env.CC_VERSION in gcc_whitelist:
1301
cfg.msg("Enabling -Werror", "yes")
1302
if '-Werror' not in env.CXXFLAGS:
1303
env.CXXFLAGS += [ '-Werror' ]
1304
else:
1305
cfg.msg("Enabling -Werror", "no")
1306
1307
if cfg.options.signed_fw:
1308
cfg.define('AP_SIGNED_FIRMWARE', 1)
1309
env.CFLAGS += [
1310
'-DAP_SIGNED_FIRMWARE=1',
1311
]
1312
else:
1313
cfg.define('AP_SIGNED_FIRMWARE', 0)
1314
env.CFLAGS += [
1315
'-DAP_SIGNED_FIRMWARE=0',
1316
]
1317
1318
try:
1319
import intelhex
1320
env.HAVE_INTEL_HEX = True
1321
cfg.msg("Checking for intelhex module:", 'OK')
1322
except Exception:
1323
cfg.msg("Checking for intelhex module:", 'disabled', color='YELLOW')
1324
env.HAVE_INTEL_HEX = False
1325
1326
if cfg.options.enable_new_checking:
1327
env.CHECK_SYMBOLS = True
1328
else:
1329
# disable new checking on ChibiOS by default to save flash
1330
# we enable it in a CI test to catch incorrect usage
1331
env.CXXFLAGS += [
1332
"-DNEW_NOTHROW=new",
1333
"-fcheck-new", # rely on -fcheck-new ensuring nullptr checks
1334
]
1335
1336
def build(self, bld):
1337
super(chibios, self).build(bld)
1338
bld.ap_version_append_str('CHIBIOS_GIT_VERSION', bld.git_submodule_head_hash('ChibiOS', short=True))
1339
bld.load('chibios')
1340
1341
def pre_build(self, bld):
1342
'''pre-build hook that gets called before dynamic sources'''
1343
from waflib.Context import load_tool
1344
module = load_tool('chibios', [], with_sys_path=True)
1345
fun = getattr(module, 'pre_build', None)
1346
if fun:
1347
fun(bld)
1348
super(chibios, self).pre_build(bld)
1349
1350
def get_name(self):
1351
return self.name
1352
1353
class linux(Board):
1354
def __init__(self):
1355
if self.toolchain == 'native':
1356
self.with_can = True
1357
else:
1358
self.with_can = False
1359
1360
def configure_env(self, cfg, env):
1361
if cfg.options.board == 'linux':
1362
self.with_can = True
1363
super(linux, self).configure_env(cfg, env)
1364
1365
env.BOARD_CLASS = "LINUX"
1366
1367
env.DEFINES.update(
1368
CONFIG_HAL_BOARD = 'HAL_BOARD_LINUX',
1369
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_NONE',
1370
AP_SIM_ENABLED = 0,
1371
)
1372
1373
if not cfg.env.DEBUG:
1374
env.CXXFLAGS += [
1375
'-O3',
1376
]
1377
1378
env.LIB += [
1379
'm',
1380
]
1381
1382
cfg.check_librt(env)
1383
cfg.check_lttng(env)
1384
cfg.check_libdl(env)
1385
cfg.check_libiio(env)
1386
1387
env.LINKFLAGS += ['-pthread',]
1388
env.AP_LIBRARIES += [
1389
'AP_HAL_Linux',
1390
]
1391
1392
# wrap malloc to ensure memory is zeroed
1393
# note that this also needs to be done in the CMakeLists.txt files
1394
env.LINKFLAGS += ['-Wl,--wrap,malloc']
1395
1396
if cfg.options.force_32bit:
1397
env.DEFINES.update(
1398
HAL_FORCE_32BIT = 1,
1399
)
1400
# 32bit platform flags
1401
cfg.env.CXXFLAGS += [
1402
'-m32',
1403
]
1404
cfg.env.CFLAGS += [
1405
'-m32',
1406
]
1407
cfg.env.LDFLAGS += [
1408
'-m32',
1409
]
1410
else:
1411
env.DEFINES.update(
1412
HAL_FORCE_32BIT = 0,
1413
)
1414
if self.with_can and cfg.options.board == 'linux':
1415
cfg.env.HAL_NUM_CAN_IFACES = 2
1416
cfg.define('HAL_NUM_CAN_IFACES', 2)
1417
cfg.define('HAL_CANFD_SUPPORTED', 1)
1418
cfg.define('CANARD_ENABLE_CANFD', 1)
1419
1420
if self.with_can:
1421
env.DEFINES.update(CANARD_MULTI_IFACE=1,
1422
CANARD_IFACE_ALL = 0x3)
1423
1424
if cfg.options.apstatedir:
1425
cfg.define('AP_STATEDIR', cfg.options.apstatedir)
1426
1427
defaults_file = 'libraries/AP_HAL_Linux/boards/%s/defaults.parm' % self.get_name()
1428
if os.path.exists(defaults_file):
1429
env.ROMFS_FILES += [('defaults.parm', defaults_file)]
1430
env.DEFINES.update(
1431
HAL_PARAM_DEFAULTS_PATH='"@ROMFS/defaults.parm"',
1432
)
1433
1434
def build(self, bld):
1435
super(linux, self).build(bld)
1436
if bld.options.upload:
1437
waflib.Options.commands.append('rsync')
1438
# Avoid infinite recursion
1439
bld.options.upload = False
1440
1441
def get_name(self):
1442
# get name of class
1443
return self.__class__.__name__
1444
1445
1446
class navigator(linux):
1447
toolchain = 'arm-linux-gnueabihf'
1448
1449
def configure_env(self, cfg, env):
1450
super(navigator, self).configure_env(cfg, env)
1451
1452
env.DEFINES.update(
1453
CONFIG_HAL_BOARD_SUBTYPE='HAL_BOARD_SUBTYPE_LINUX_NAVIGATOR',
1454
)
1455
1456
class navigator64(linux):
1457
toolchain = 'aarch64-linux-gnu'
1458
1459
def configure_env(self, cfg, env):
1460
super(navigator64, self).configure_env(cfg, env)
1461
1462
env.DEFINES.update(
1463
CONFIG_HAL_BOARD_SUBTYPE='HAL_BOARD_SUBTYPE_LINUX_NAVIGATOR',
1464
)
1465
1466
1467
class erleboard(linux):
1468
toolchain = 'arm-linux-gnueabihf'
1469
1470
def configure_env(self, cfg, env):
1471
super(erleboard, self).configure_env(cfg, env)
1472
1473
env.DEFINES.update(
1474
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD',
1475
)
1476
1477
class navio(linux):
1478
toolchain = 'arm-linux-gnueabihf'
1479
1480
def configure_env(self, cfg, env):
1481
super(navio, self).configure_env(cfg, env)
1482
1483
env.DEFINES.update(
1484
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_NAVIO',
1485
)
1486
1487
class navio2(linux):
1488
toolchain = 'arm-linux-gnueabihf'
1489
1490
def configure_env(self, cfg, env):
1491
super(navio2, self).configure_env(cfg, env)
1492
1493
env.DEFINES.update(
1494
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_NAVIO2',
1495
)
1496
1497
class edge(linux):
1498
toolchain = 'arm-linux-gnueabihf'
1499
1500
def __init__(self):
1501
self.with_can = True
1502
1503
def configure_env(self, cfg, env):
1504
super(edge, self).configure_env(cfg, env)
1505
1506
env.DEFINES.update(
1507
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_EDGE',
1508
)
1509
1510
class zynq(linux):
1511
toolchain = 'arm-xilinx-linux-gnueabi'
1512
1513
def configure_env(self, cfg, env):
1514
super(zynq, self).configure_env(cfg, env)
1515
1516
env.DEFINES.update(
1517
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_ZYNQ',
1518
)
1519
1520
class ocpoc_zynq(linux):
1521
toolchain = 'arm-linux-gnueabihf'
1522
1523
def configure_env(self, cfg, env):
1524
super(ocpoc_zynq, self).configure_env(cfg, env)
1525
1526
env.DEFINES.update(
1527
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_OCPOC_ZYNQ',
1528
)
1529
1530
class bbbmini(linux):
1531
toolchain = 'arm-linux-gnueabihf'
1532
1533
def __init__(self):
1534
self.with_can = True
1535
1536
def configure_env(self, cfg, env):
1537
super(bbbmini, self).configure_env(cfg, env)
1538
cfg.env.HAL_NUM_CAN_IFACES = 1
1539
env.DEFINES.update(
1540
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_BBBMINI',
1541
)
1542
1543
class blue(linux):
1544
toolchain = 'arm-linux-gnueabihf'
1545
1546
def __init__(self):
1547
self.with_can = True
1548
1549
def configure_env(self, cfg, env):
1550
super(blue, self).configure_env(cfg, env)
1551
cfg.env.HAL_NUM_CAN_IFACES = 1
1552
1553
env.DEFINES.update(
1554
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_BLUE',
1555
)
1556
1557
class pocket(linux):
1558
toolchain = 'arm-linux-gnueabihf'
1559
1560
def __init__(self):
1561
self.with_can = True
1562
1563
def configure_env(self, cfg, env):
1564
super(pocket, self).configure_env(cfg, env)
1565
cfg.env.HAL_NUM_CAN_IFACES = 1
1566
1567
env.DEFINES.update(
1568
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_POCKET',
1569
)
1570
1571
class pxf(linux):
1572
toolchain = 'arm-linux-gnueabihf'
1573
1574
def configure_env(self, cfg, env):
1575
super(pxf, self).configure_env(cfg, env)
1576
1577
env.DEFINES.update(
1578
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_PXF',
1579
)
1580
1581
class bebop(linux):
1582
toolchain = 'arm-linux-gnueabihf'
1583
1584
def configure_env(self, cfg, env):
1585
super(bebop, self).configure_env(cfg, env)
1586
1587
env.DEFINES.update(
1588
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_BEBOP',
1589
)
1590
1591
class vnav(linux):
1592
toolchain = 'arm-linux-gnueabihf'
1593
1594
def configure_env(self, cfg, env):
1595
super(vnav, self).configure_env(cfg, env)
1596
1597
env.DEFINES.update(
1598
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_VNAV',
1599
)
1600
1601
class disco(linux):
1602
toolchain = 'arm-linux-gnueabihf'
1603
1604
def configure_env(self, cfg, env):
1605
super(disco, self).configure_env(cfg, env)
1606
1607
env.DEFINES.update(
1608
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_DISCO',
1609
)
1610
1611
class erlebrain2(linux):
1612
toolchain = 'arm-linux-gnueabihf'
1613
1614
def configure_env(self, cfg, env):
1615
super(erlebrain2, self).configure_env(cfg, env)
1616
1617
env.DEFINES.update(
1618
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2',
1619
)
1620
1621
class bhat(linux):
1622
toolchain = 'arm-linux-gnueabihf'
1623
1624
def configure_env(self, cfg, env):
1625
super(bhat, self).configure_env(cfg, env)
1626
1627
env.DEFINES.update(
1628
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_BH',
1629
)
1630
1631
class dark(linux):
1632
toolchain = 'arm-linux-gnueabihf'
1633
1634
def configure_env(self, cfg, env):
1635
super(dark, self).configure_env(cfg, env)
1636
1637
env.DEFINES.update(
1638
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_DARK',
1639
)
1640
1641
class pxfmini(linux):
1642
toolchain = 'arm-linux-gnueabihf'
1643
1644
def configure_env(self, cfg, env):
1645
super(pxfmini, self).configure_env(cfg, env)
1646
1647
env.DEFINES.update(
1648
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_PXFMINI',
1649
)
1650
1651
class aero(linux):
1652
def __init__(self):
1653
self.with_can = True
1654
1655
def configure_env(self, cfg, env):
1656
super(aero, self).configure_env(cfg, env)
1657
1658
env.DEFINES.update(
1659
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_AERO',
1660
)
1661
1662
class rst_zynq(linux):
1663
toolchain = 'arm-linux-gnueabihf'
1664
1665
def configure_env(self, cfg, env):
1666
super(rst_zynq, self).configure_env(cfg, env)
1667
1668
env.DEFINES.update(
1669
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_RST_ZYNQ',
1670
)
1671
1672
class obal(linux):
1673
toolchain = 'arm-linux-gnueabihf'
1674
1675
def configure_env(self, cfg, env):
1676
super(obal, self).configure_env(cfg, env)
1677
1678
env.DEFINES.update(
1679
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_OBAL_V1',
1680
)
1681
1682
class canzero(linux):
1683
toolchain = 'arm-linux-gnueabihf'
1684
1685
def __init__(self):
1686
self.with_can = True
1687
1688
def configure_env(self, cfg, env):
1689
super(canzero, self).configure_env(cfg, env)
1690
1691
env.DEFINES.update(
1692
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_CANZERO',
1693
)
1694
1695
class SITL_static(sitl):
1696
def configure_env(self, cfg, env):
1697
super(SITL_static, self).configure_env(cfg, env)
1698
cfg.env.STATIC_LINKING = True
1699
1700
class SITL_x86_64_linux_gnu(SITL_static):
1701
toolchain = 'x86_64-linux-gnu'
1702
1703
class SITL_arm_linux_gnueabihf(SITL_static):
1704
toolchain = 'arm-linux-gnueabihf'
1705
1706
class QURT(Board):
1707
'''support for QURT based boards'''
1708
toolchain = 'custom'
1709
1710
def __init__(self):
1711
self.with_can = False
1712
1713
def configure_toolchain(self, cfg):
1714
cfg.env.CXX_NAME = 'gcc'
1715
cfg.env.HEXAGON_SDK_DIR = "/opt/hexagon-sdk/4.1.0.4-lite"
1716
cfg.env.CC_VERSION = ('4','1','0')
1717
cfg.env.TOOLCHAIN_DIR = cfg.env.HEXAGON_SDK_DIR + "/tools/HEXAGON_Tools/8.4.05/Tools"
1718
cfg.env.COMPILER_CC = cfg.env.TOOLCHAIN_DIR + "/bin/hexagon-clang"
1719
cfg.env.COMPILER_CXX = cfg.env.TOOLCHAIN_DIR + "/bin/hexagon-clang++"
1720
cfg.env.LINK_CXX = cfg.env.HEXAGON_SDK_DIR + "/tools/HEXAGON_Tools/8.4.05/Tools/bin/hexagon-link"
1721
cfg.env.CXX = ["ccache", cfg.env.COMPILER_CXX]
1722
cfg.env.CC = ["ccache", cfg.env.COMPILER_CC]
1723
cfg.env.CXX_TGT_F = ['-c', '-o']
1724
cfg.env.CC_TGT_F = ['-c', '-o']
1725
cfg.env.CCLNK_SRC_F = []
1726
cfg.env.CXXLNK_SRC_F = []
1727
cfg.env.CXXLNK_TGT_F = ['-o']
1728
cfg.env.CCLNK_TGT_F = ['-o']
1729
cfg.env.CPPPATH_ST = '-I%s'
1730
cfg.env.DEFINES_ST = '-D%s'
1731
cfg.env.AR = cfg.env.HEXAGON_SDK_DIR + "/tools/HEXAGON_Tools/8.4.05/Tools/bin/hexagon-ar"
1732
cfg.env.ARFLAGS = 'rcs'
1733
cfg.env.cxxstlib_PATTERN = 'lib%s.a'
1734
cfg.env.cstlib_PATTERN = 'lib%s.a'
1735
cfg.env.LIBPATH_ST = '-L%s'
1736
cfg.env.LIB_ST = '-l%s'
1737
cfg.env.SHLIB_MARKER = ''
1738
cfg.env.STLIBPATH_ST = '-L%s'
1739
cfg.env.STLIB_MARKER = ''
1740
cfg.env.STLIB_ST = '-l%s'
1741
cfg.env.LDFLAGS = [
1742
'-lgcc',
1743
cfg.env.TOOLCHAIN_DIR + '/target/hexagon/lib/v66/G0/pic/finiS.o'
1744
]
1745
1746
def configure_env(self, cfg, env):
1747
super(QURT, self).configure_env(cfg, env)
1748
1749
env.BOARD_CLASS = "QURT"
1750
env.HEXAGON_APP = "libardupilot.so"
1751
env.INCLUDES += [cfg.env.HEXAGON_SDK_DIR + "/rtos/qurt/computev66/include/qurt"]
1752
env.INCLUDES += [cfg.env.HEXAGON_SDK_DIR + "/rtos/qurt/computev66/include/posix"]
1753
1754
CFLAGS = "-MD -mv66 -fPIC -mcpu=hexagonv66 -G0 -fdata-sections -ffunction-sections -fomit-frame-pointer -fmerge-all-constants -fno-signed-zeros -fno-trapping-math -freciprocal-math -fno-math-errno -fno-strict-aliasing -fvisibility=hidden -fno-rtti -fmath-errno"
1755
env.CXXFLAGS += CFLAGS.split()
1756
env.CFLAGS += CFLAGS.split()
1757
1758
env.DEFINES.update(
1759
CONFIG_HAL_BOARD = 'HAL_BOARD_QURT',
1760
CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_NONE',
1761
AP_SIM_ENABLED = 0,
1762
)
1763
1764
env.LINKFLAGS = [
1765
"-march=hexagon",
1766
"-mcpu=hexagonv66",
1767
"-shared",
1768
"-call_shared",
1769
"-G0",
1770
cfg.env.TOOLCHAIN_DIR + "/target/hexagon/lib/v66/G0/pic/initS.o",
1771
f"-L{cfg.env.TOOLCHAIN_DIR}/target/hexagon/lib/v66/G0/pic",
1772
"-Bsymbolic",
1773
cfg.env.TOOLCHAIN_DIR + "/target/hexagon/lib/v66/G0/pic/libgcc.a",
1774
"--wrap=malloc",
1775
"--wrap=calloc",
1776
"--wrap=free",
1777
"--wrap=realloc",
1778
"--wrap=printf",
1779
"--wrap=strdup",
1780
"--wrap=__stack_chk_fail",
1781
"-lc"
1782
]
1783
1784
if not cfg.env.DEBUG:
1785
env.CXXFLAGS += [
1786
'-O3',
1787
]
1788
1789
env.AP_LIBRARIES += [
1790
'AP_HAL_QURT',
1791
]
1792
1793
def build(self, bld):
1794
super(QURT, self).build(bld)
1795
bld.load('qurt')
1796
1797
def get_name(self):
1798
# get name of class
1799
return self.__class__.__name__
1800
1801
1802