mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[embedded] Add QEMU-based testing configs for ARM and AVR for runtime testing
This commit is contained in:
134
utils/embedded-test-support/embedded-test-support.py
Executable file
134
utils/embedded-test-support/embedded-test-support.py
Executable file
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
# flake8: noqa
|
||||
#
|
||||
# This source file is part of the Swift.org open source project
|
||||
#
|
||||
# Copyright (c) 2024 Apple Inc. and the Swift project authors
|
||||
# Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
#
|
||||
# See https://swift.org/LICENSE.txt for license information
|
||||
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import pathlib
|
||||
|
||||
|
||||
MY_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def shell(cmd):
|
||||
return subprocess.check_output(["bash", "-c", cmd])
|
||||
|
||||
|
||||
def shell_print(cmd):
|
||||
print(cmd)
|
||||
subprocess.check_call(["bash", "-c", cmd])
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--device', choices=sorted([d for d in os.listdir(MY_DIR) if os.path.isdir(MY_DIR + "/" + d)]), required=True)
|
||||
parser.add_argument('command', choices=['run', 'demo-run', 'print-c-flags', 'print-swift-flags', 'print-swift-frontend-flags'])
|
||||
parser.add_argument('--elf-file')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.device == "arm-qemu-stm32f1":
|
||||
target = "armv7em-none-none-eabi"
|
||||
qemu_binary = "qemu-system-arm"
|
||||
qemu_machine = "stm32vldiscovery"
|
||||
mmcu = ""
|
||||
entry_point = "vector_table"
|
||||
semihosting = True
|
||||
qemu_mode = "-kernel"
|
||||
always_optimize_for_size = False
|
||||
elif args.device == "arm-qemu-stm32f4":
|
||||
target = "armv7em-none-none-eabi"
|
||||
qemu_binary = "qemu-system-arm"
|
||||
qemu_machine = "netduinoplus2"
|
||||
mmcu = ""
|
||||
entry_point = "vector_table"
|
||||
semihosting = True
|
||||
qemu_mode = "-kernel"
|
||||
always_optimize_for_size = False
|
||||
elif args.device == "avr-qemu-atmega2560":
|
||||
target = "avr-none-none-elf"
|
||||
qemu_binary = "qemu-system-avr"
|
||||
qemu_machine = "mega2560"
|
||||
mmcu = "-mmcu=atmega2560"
|
||||
entry_point = "start"
|
||||
semihosting = False
|
||||
qemu_mode = "-bios"
|
||||
always_optimize_for_size = True
|
||||
else:
|
||||
assert False
|
||||
|
||||
tmpdir = tempfile.gettempdir()
|
||||
|
||||
cflags = ""
|
||||
cflags += " -nostdlib"
|
||||
cflags += " -ffunction-sections -fdata-sections"
|
||||
cflags += " -ffreestanding"
|
||||
cflags += " -O2"
|
||||
cflags += " -g"
|
||||
cflags += f" {mmcu}"
|
||||
|
||||
supportfile = tmpdir + "/" + target + "-support.o"
|
||||
shell(f"clang -target {target} {cflags} -c {MY_DIR}/{args.device}/support.c -o {supportfile}")
|
||||
|
||||
libcfile = tmpdir + "/" + target + "-libc.o"
|
||||
shell(f"clang -target {target} {cflags} -c {MY_DIR}/libc.c -o {libcfile}")
|
||||
|
||||
demo_o_file = tmpdir + "/" + target + "-demo.o"
|
||||
shell(f"clang -target {target} {cflags} -c {MY_DIR}/demo.c -o {demo_o_file}")
|
||||
|
||||
cflags += f" {supportfile} {libcfile}"
|
||||
|
||||
swift_frontend_flags = ""
|
||||
swift_frontend_flags += " -disable-stack-protector -function-sections"
|
||||
if mmcu != "": swift_frontend_flags += f" -Xcc {mmcu}"
|
||||
|
||||
swift_flags = ""
|
||||
swift_flags += " -Xfrontend -disable-stack-protector -Xfrontend -function-sections -use-ld=lld"
|
||||
swift_flags += " -Xclang-linker -nostdlib -Xlinker --gc-sections"
|
||||
swift_flags += f" {supportfile} {libcfile}"
|
||||
swift_flags += f" -Xlinker -T -Xlinker {MY_DIR}/{args.device}/linkerscript.ld -Xlinker -e -Xlinker {entry_point}"
|
||||
if mmcu != "": swift_flags += f" -Xcc {mmcu}"
|
||||
if always_optimize_for_size: swift_flags += " -Osize"
|
||||
|
||||
cflags += " -fuse-ld=lld"
|
||||
cflags += " -nostdlib"
|
||||
cflags += " -Xlinker --gc-sections"
|
||||
cflags += f" -Xlinker -T -Xlinker {MY_DIR}/{args.device}/linkerscript.ld"
|
||||
cflags += f" -Wl,-e,{entry_point}"
|
||||
|
||||
if args.command == "print-swift-flags":
|
||||
print(swift_flags)
|
||||
|
||||
elif args.command == "print-swift-frontend-flags":
|
||||
print(swift_frontend_flags)
|
||||
|
||||
elif args.command == "print-c-flags":
|
||||
print(cflags)
|
||||
|
||||
elif args.command == "run":
|
||||
if args.elf_file is None:
|
||||
print("Must specify --elf-file <...>")
|
||||
exit(1)
|
||||
|
||||
qemu_command = f"{qemu_binary} -M {qemu_machine} -nographic {qemu_mode} {args.elf_file} {'-semihosting' if semihosting else ''}"
|
||||
shell_print(f"expect -c 'spawn {qemu_command}; expect -timeout 5 -re \"HALT\"'")
|
||||
|
||||
elif args.command == "demo-run":
|
||||
elffile = tmpdir + "/" + target + ".elf"
|
||||
shell(f"clang -target {target} {cflags} {demo_o_file} -o {elffile}")
|
||||
|
||||
qemu_command = f"{qemu_binary} -M {qemu_machine} -nographic {qemu_mode} {elffile} {'-semihosting' if semihosting else ''}"
|
||||
shell_print(f"expect -c 'spawn {qemu_command}; expect -timeout 5 -re \"HALT\"'")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user