mirror of
https://github.com/apache/nuttx-apps.git
synced 2025-10-19 02:17:37 +08:00
876 lines
28 KiB
Python
Executable File
876 lines
28 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import os
|
|
import platform
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
# Custom argparse actions #
|
|
|
|
|
|
class validate_flags_arg(argparse.Action):
|
|
"""
|
|
Custom argparse action to validate the number of parameters passed to the
|
|
--flags argument. Exactly three parameters are required.
|
|
"""
|
|
|
|
def __call__(self, parser, namespace, values, option_string=None):
|
|
if len(values) != 3:
|
|
raise argparse.ArgumentError(
|
|
self,
|
|
"Invalid number of parameters for --flags. Exactly three parameters are required.",
|
|
)
|
|
setattr(namespace, self.dest, values)
|
|
|
|
|
|
# Vendor specific functions #
|
|
|
|
# Espressif #
|
|
|
|
|
|
def run_espressif_tool(cmd):
|
|
tool = "esptool.py"
|
|
strings_out = ""
|
|
command = "{} {}".format(tool, cmd)
|
|
|
|
strings_out = subprocess.run(
|
|
command, universal_newlines=True, shell=True, capture_output=True
|
|
)
|
|
|
|
return strings_out.stdout
|
|
|
|
|
|
def get_espressif_chip_id():
|
|
output = run_espressif_tool("chip_id")
|
|
string_out = next((s for s in output.split("\n") if "Chip ID" in s), "Not found")
|
|
if string_out != "Not found":
|
|
string_out = string_out.split("Warning: ")[-1]
|
|
return string_out
|
|
|
|
|
|
def get_espressif_flash_id():
|
|
strings_out = []
|
|
output = run_espressif_tool("flash_id")
|
|
|
|
strings_out.append(
|
|
next(
|
|
(s for s in output.split("\n") if "Manufacturer" in s),
|
|
"Manufacturer: Not found",
|
|
)
|
|
)
|
|
strings_out.append(
|
|
next((s for s in output.split("\n") if "Device" in s), "Device: Not found")
|
|
)
|
|
|
|
return strings_out
|
|
|
|
|
|
def get_espressif_security_info():
|
|
output = run_espressif_tool("get_security_info")
|
|
|
|
start_string = "====================="
|
|
stop_string = "Hard resetting via RTS pin..."
|
|
output = output.split("\n")
|
|
strings_out = []
|
|
|
|
str_out = next((s for s in output if start_string in s), "Not found")
|
|
if str_out != "Not found":
|
|
start_index = output.index(start_string) + 1
|
|
stop_index = output.index(stop_string)
|
|
strings_out = output[start_index:stop_index]
|
|
else:
|
|
strings_out.append(str_out)
|
|
|
|
return strings_out
|
|
|
|
|
|
def get_espressif_flash_status():
|
|
output = run_espressif_tool("read_flash_status")
|
|
|
|
string_out = next(
|
|
(s for s in output.split("\n") if "Status value" in s), "Not found"
|
|
)
|
|
if string_out != "Not found":
|
|
string_out = string_out.split("Status value: ")[-1]
|
|
return string_out
|
|
|
|
|
|
def get_espressif_mac_address():
|
|
output = run_espressif_tool("read_mac")
|
|
|
|
string_out = next((s for s in output.split("\n") if "MAC" in s), "Not found")
|
|
if string_out != "Not found":
|
|
string_out = string_out.split("MAC: ")[-1]
|
|
return string_out
|
|
|
|
|
|
def get_espressif_bootloader_version(bindir):
|
|
"""
|
|
Get the bootloader version for Espressif chips from the bootloader binary. This
|
|
function works on Linux, Windows, and macOS.
|
|
|
|
Args:
|
|
bindir (str): The path to the bootloader binary directory.
|
|
|
|
Returns:
|
|
dict: A dictionary containing the bootloader version for each chip.
|
|
"""
|
|
|
|
regex = r"^(?=.*\bv\d+(\.\d+){1,2}\b).+$"
|
|
bootloader_chips = [
|
|
"esp32",
|
|
"esp32s2",
|
|
"esp32s3",
|
|
"esp32c2",
|
|
"esp32c3",
|
|
"esp32c6",
|
|
"esp32h2",
|
|
]
|
|
bootloader_version = {}
|
|
|
|
for chip in bootloader_chips:
|
|
file = "bootloader-{}.bin".format(chip)
|
|
path = os.path.join(bindir, file)
|
|
|
|
if os.path.isfile(path):
|
|
if platform.system() == "Linux":
|
|
process = subprocess.Popen(["strings", path], stdout=subprocess.PIPE)
|
|
elif platform.system() == "Windows":
|
|
process = subprocess.Popen(
|
|
[
|
|
"powershell",
|
|
"Get-Content -Raw -Encoding Byte {} |".format(path)
|
|
+ " % { [char[]]$_ -join \"\" } | Select-String -Pattern '[\\x20-\\x7E]+'"
|
|
+ " -AllMatches | % { $_.Matches } | % { $_.Value }",
|
|
],
|
|
stdout=subprocess.PIPE,
|
|
)
|
|
elif platform.system() == "Darwin":
|
|
process = subprocess.Popen(
|
|
["strings", "-", path], stdout=subprocess.PIPE
|
|
)
|
|
else:
|
|
bootloader_version[chip] = "Not supported on host OS"
|
|
break
|
|
|
|
output, error = process.communicate()
|
|
strings_out = output.decode("utf-8", errors="ignore")
|
|
matches = re.finditer(regex, strings_out, re.MULTILINE)
|
|
|
|
try:
|
|
bootloader_version[chip] = next(matches).group(0)
|
|
except StopIteration:
|
|
bootloader_version[chip] = "Unknown"
|
|
|
|
else:
|
|
bootloader_version[chip] = "Bootloader image not found"
|
|
|
|
return bootloader_version
|
|
|
|
|
|
def get_espressif_toolchain_version():
|
|
"""
|
|
Get the version of different toolchains used by Espressif chips.
|
|
|
|
Args:
|
|
None.
|
|
|
|
Returns:
|
|
dict: A dictionary containing the toolchain version for each toolchain.
|
|
"""
|
|
|
|
toolchain_version = {}
|
|
toolchain_bins = [
|
|
"clang",
|
|
"gcc",
|
|
"xtensa-esp32-elf-gcc",
|
|
"xtensa-esp32s2-elf-gcc",
|
|
"xtensa-esp32s3-elf-gcc",
|
|
"riscv32-esp-elf-gcc",
|
|
"riscv64-unknown-elf-gcc",
|
|
]
|
|
|
|
for binary in toolchain_bins:
|
|
try:
|
|
version_output = subprocess.check_output(
|
|
[binary, "--version"], stderr=subprocess.STDOUT, universal_newlines=True
|
|
)
|
|
version_lines = version_output.split("\n")
|
|
version = version_lines[0].strip()
|
|
toolchain_version[binary] = version
|
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
toolchain_version[binary] = "Not found"
|
|
|
|
return toolchain_version
|
|
|
|
|
|
def get_espressif_hal_version(hal_dir):
|
|
"""
|
|
Get the version of the ESP HAL used by Espressif chips.
|
|
|
|
Args:
|
|
None.
|
|
|
|
Returns:
|
|
str: The ESP HAL version.
|
|
"""
|
|
|
|
hal_version = "Not found"
|
|
|
|
try:
|
|
if os.path.isdir(os.path.join(hal_dir, ".git")):
|
|
hal_version_output = subprocess.check_output(
|
|
["git", "describe", "--tags", "--always"],
|
|
cwd=hal_dir,
|
|
stderr=subprocess.STDOUT,
|
|
universal_newlines=True,
|
|
)
|
|
hal_version = hal_version_output.strip()
|
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
pass
|
|
|
|
return hal_version
|
|
|
|
|
|
# Common functions #
|
|
|
|
|
|
def verbose(info, logs):
|
|
"""
|
|
Prepare and print information on build screen.
|
|
|
|
Args:
|
|
info (dict): Information dictionary of build system.
|
|
logs (str): Vendor specific information string.
|
|
|
|
Returns:
|
|
None.
|
|
"""
|
|
|
|
if args.verbose:
|
|
|
|
out_str = "\n" + "=" * 79 + "\n"
|
|
|
|
out_str += "NuttX RTOS info: {}\n\n".format(info["OS_VERSION"])
|
|
if args.flags:
|
|
out_str += "NuttX CFLAGS: {}\n\n".format(info["NUTTX_CFLAGS"])
|
|
out_str += "NuttX CXXFLAGS: {}\n\n".format(info["NUTTX_CXXFLAGS"])
|
|
out_str += "NuttX LDFLAGS: {}\n\n".format(info["NUTTX_LDFLAGS"])
|
|
|
|
if args.config:
|
|
out_str += "NuttX configuration options: \n"
|
|
for i in range(len(info["NUTTX_CONFIG"])):
|
|
out_str += " " + info["NUTTX_CONFIG"][i].replace('"', '\\"') + "\n"
|
|
out_str += "\n\n"
|
|
|
|
if args.path:
|
|
out_str += "Host system PATH: \n"
|
|
for i in range(len(info["SYSTEM_PATH"])):
|
|
out_str += " " + info["SYSTEM_PATH"][i] + "\n"
|
|
out_str += "\n\n"
|
|
|
|
if args.packages:
|
|
out_str += "Host system installed packages: \n"
|
|
for i in range(len(info["INSTALLED_PACKAGES"])):
|
|
out_str += " " + info["INSTALLED_PACKAGES"][i] + "\n"
|
|
out_str += "\n\n"
|
|
|
|
if args.modules:
|
|
out_str += "Host system installed python modules: \n"
|
|
for i in range(len(info["PYTHON_MODULES"])):
|
|
out_str += " " + info["PYTHON_MODULES"][i] + "\n"
|
|
out_str += "\n\n"
|
|
|
|
if args.espressif:
|
|
out_str += "Espressif specific information: \n\n"
|
|
out_str += logs
|
|
out_str += "=" * 79 + "\n"
|
|
|
|
eprint(out_str)
|
|
|
|
|
|
def eprint(*args, **kwargs):
|
|
"""
|
|
Prints the arguments passed to stderr.
|
|
"""
|
|
|
|
print(*args, file=sys.stderr, **kwargs)
|
|
|
|
|
|
def get_installed_packages():
|
|
"""
|
|
Gets the list of packages installed on the host system. This function works on
|
|
Linux (Debian, Red Hat, and Arch-based distros), Windows, and macOS.
|
|
|
|
Args:
|
|
None.
|
|
|
|
Returns:
|
|
list: Packages (with version) installed on the host system.
|
|
"""
|
|
|
|
packages = []
|
|
|
|
if platform.system() == "Linux":
|
|
package_managers = [
|
|
{
|
|
"name": "Dpkg",
|
|
"command": ["dpkg", "-l"],
|
|
"skip_lines": 5,
|
|
"info_name": 1,
|
|
"info_version": 2,
|
|
},
|
|
{
|
|
"name": "Rpm",
|
|
"command": ["rpm", "-qa", "--queryformat", '"%{NAME} %{VERSION}\\n"'],
|
|
"skip_lines": 0,
|
|
"info_name": 0,
|
|
"info_version": 1,
|
|
},
|
|
{
|
|
"name": "Pacman",
|
|
"command": ["pacman", "-Q", "--queryformat", '"%n %v\\n"'],
|
|
"skip_lines": 0,
|
|
"info_name": 0,
|
|
"info_version": 1,
|
|
},
|
|
]
|
|
|
|
for manager in package_managers:
|
|
try:
|
|
process = subprocess.Popen(manager["command"], stdout=subprocess.PIPE)
|
|
output, error = process.communicate()
|
|
lines = output.decode("utf-8").splitlines()
|
|
|
|
# Skip the specified number of lines based on the package manager
|
|
if lines:
|
|
lines = lines[manager["skip_lines"] :]
|
|
|
|
current_packages = []
|
|
for line in lines:
|
|
package_info = line.split()
|
|
package = package_info[manager["info_name"]]
|
|
version = package_info[manager["info_version"]]
|
|
current_packages.append(f"{package} ({version})")
|
|
|
|
if current_packages:
|
|
packages.extend(current_packages)
|
|
break
|
|
|
|
except (FileNotFoundError, subprocess.CalledProcessError):
|
|
pass
|
|
|
|
elif platform.system() == "Windows":
|
|
try:
|
|
output = subprocess.check_output(
|
|
[
|
|
"powershell",
|
|
"Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\"
|
|
+ "CurrentVersion\\Uninstall\\* | Select-Object DisplayName, DisplayVersion",
|
|
]
|
|
)
|
|
output = output.decode("utf-8", errors="ignore").split("\r\n")
|
|
for line in output[3:]:
|
|
line = line.strip()
|
|
if line:
|
|
match = re.match(r"^(.*?)(\s{2,}[^ ]+)?$", line)
|
|
if match:
|
|
name = match.group(1).strip()
|
|
version = (
|
|
match.group(2).strip() if match.group(2) else "Unknown"
|
|
)
|
|
packages.append(f"{name} ({version})")
|
|
except subprocess.CalledProcessError:
|
|
eprint("Error: Failed to get installed packages.")
|
|
|
|
elif platform.system() == "Darwin":
|
|
try:
|
|
output = subprocess.check_output(["pkgutil", "--pkgs"])
|
|
output = output.decode("utf-8").split("\n")
|
|
for package in output:
|
|
if "." in package:
|
|
try:
|
|
info = subprocess.check_output(
|
|
["pkgutil", "--pkg-info", package]
|
|
)
|
|
info = info.decode("utf-8")
|
|
version = info.split("version: ")[1].split("\n")[0]
|
|
except subprocess.CalledProcessError:
|
|
version = "Unknown"
|
|
packages.append(f"{package} ({version})")
|
|
except subprocess.CalledProcessError:
|
|
eprint("Error: Failed to get installed packages.")
|
|
|
|
packages.sort()
|
|
return packages
|
|
|
|
|
|
def get_python_modules():
|
|
"""
|
|
Gets the list of python modules installed on the host system.
|
|
|
|
Args:
|
|
None.
|
|
|
|
Returns:
|
|
list: Python modules (with version) installed on the host system.
|
|
"""
|
|
|
|
modules = []
|
|
|
|
output = subprocess.check_output(
|
|
["pip", "list", "--format=freeze"], universal_newlines=True
|
|
)
|
|
for line in output.splitlines():
|
|
if line.startswith("#"):
|
|
continue
|
|
package_info = line.split("==")
|
|
if len(package_info) > 1:
|
|
modules.append("{}-{}".format(package_info[0], package_info[1]))
|
|
else:
|
|
modules.append(package_info[0])
|
|
return modules
|
|
|
|
|
|
def get_system_path():
|
|
"""
|
|
Gets the PATH environment variable.
|
|
|
|
Args:
|
|
None.
|
|
|
|
Returns:
|
|
str: The PATH environment variable.
|
|
"""
|
|
|
|
return os.environ.get("PATH", "")
|
|
|
|
|
|
def get_os_version():
|
|
"""
|
|
Gets the OS distribution and version. This function works on Linux, Windows,
|
|
and macOS. On Linux, if the distro package is installed, it will be used to
|
|
get the OS distribution.
|
|
|
|
Args:
|
|
None.
|
|
|
|
Returns:
|
|
str: The OS distribution and version.
|
|
"""
|
|
|
|
os_name = platform.system()
|
|
sys_id = ""
|
|
|
|
if os_name == "Windows":
|
|
os_distro = "Windows"
|
|
os_version = platform.win32_ver()[0]
|
|
sys_id = f"{os_distro} {os_version}"
|
|
|
|
elif os_name == "Darwin":
|
|
os_distro = "macOS"
|
|
os_uname = " ".join(platform.uname())
|
|
os_version = platform.mac_ver()[0]
|
|
sys_id = f"{os_distro} {os_version} {os_uname}"
|
|
|
|
elif os_name == "Linux":
|
|
os_uname = " ".join(platform.uname())
|
|
try:
|
|
import distro
|
|
|
|
sys_id = distro.name(pretty=True) + " " + os_uname
|
|
except ImportError:
|
|
sys_id = os_uname
|
|
|
|
return sys_id
|
|
|
|
|
|
def get_compilation_flags(flags):
|
|
"""
|
|
Gets the compilation flags used to compile the NuttX source code and splits
|
|
them into a list.
|
|
|
|
Args:
|
|
arg (str): The compilation flags.
|
|
|
|
Returns:
|
|
list: The compilation flags.
|
|
"""
|
|
|
|
if not flags:
|
|
return [""]
|
|
|
|
flag_list = flags.split(" -")
|
|
flag_list[0] = flag_list[0][1:]
|
|
flag_list = ["-" + flag for flag in flag_list]
|
|
|
|
return flag_list
|
|
|
|
|
|
def generate_header(args):
|
|
"""
|
|
Generates the sysinfo.h header file that contains information about the host system
|
|
and NuttX configuration that can be used by NuttX applications.
|
|
|
|
Args:
|
|
args (argparse.Namespace): The command line arguments.
|
|
|
|
Returns:
|
|
str: The contents of the sysinfo.h header file.
|
|
"""
|
|
|
|
info = {}
|
|
output = ""
|
|
build_output = ""
|
|
|
|
output += "/****************************************************************************\n"
|
|
output += " * sysinfo.h\n"
|
|
output += " *\n"
|
|
output += " * Auto-generated by a Python script. Do not edit!\n"
|
|
output += " *\n"
|
|
output += (
|
|
" * This file contains information about the host and target systems that\n"
|
|
)
|
|
output += " * can be used by NuttX applications.\n"
|
|
output += " *\n"
|
|
output += " ****************************************************************************/\n\n"
|
|
|
|
output += "#ifndef __SYSTEM_INFO_H\n"
|
|
output += "#define __SYSTEM_INFO_H\n\n"
|
|
|
|
# NuttX Compilation Flags
|
|
|
|
if args.flags:
|
|
cflags, cxxflags, ldflags = args.flags
|
|
|
|
if cflags:
|
|
cflags = cflags[1:-1]
|
|
if cxxflags:
|
|
cxxflags = cxxflags[1:-1]
|
|
if ldflags:
|
|
ldflags = ldflags[1:-1]
|
|
|
|
info["NUTTX_CFLAGS"] = get_compilation_flags(cflags)
|
|
info["NUTTX_CXXFLAGS"] = get_compilation_flags(cxxflags)
|
|
info["NUTTX_LDFLAGS"] = get_compilation_flags(ldflags)
|
|
|
|
output += "#define NUTTX_CFLAGS_ARRAY_SIZE {}\n".format(
|
|
len(info["NUTTX_CFLAGS"])
|
|
)
|
|
output += "static const char *NUTTX_CFLAGS[NUTTX_CFLAGS_ARRAY_SIZE] =\n{\n"
|
|
for i in range(len(info["NUTTX_CFLAGS"])):
|
|
output += ' "' + info["NUTTX_CFLAGS"][i] + '",\n'
|
|
output += "};\n\n"
|
|
|
|
output += "#define NUTTX_CXXFLAGS_ARRAY_SIZE {}\n".format(
|
|
len(info["NUTTX_CXXFLAGS"])
|
|
)
|
|
output += "static const char *NUTTX_CXXFLAGS[NUTTX_CXXFLAGS_ARRAY_SIZE] =\n{\n"
|
|
for i in range(len(info["NUTTX_CXXFLAGS"])):
|
|
output += ' "' + info["NUTTX_CXXFLAGS"][i] + '",\n'
|
|
output += "};\n\n"
|
|
|
|
output += "#define NUTTX_LDFLAGS_ARRAY_SIZE {}\n".format(
|
|
len(info["NUTTX_LDFLAGS"])
|
|
)
|
|
output += "static const char *NUTTX_LDFLAGS[NUTTX_LDFLAGS_ARRAY_SIZE] =\n{\n"
|
|
for i in range(len(info["NUTTX_LDFLAGS"])):
|
|
output += ' "' + info["NUTTX_LDFLAGS"][i] + '",\n'
|
|
output += "};\n\n"
|
|
|
|
# NuttX Configuration
|
|
|
|
if args.config:
|
|
info["NUTTX_CONFIG"] = []
|
|
config_path = os.path.abspath("./.config")
|
|
try:
|
|
with open(config_path, "r") as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line or line.startswith("#"):
|
|
continue
|
|
info["NUTTX_CONFIG"].append(line)
|
|
|
|
output += "#define NUTTX_CONFIG_ARRAY_SIZE {}\n".format(
|
|
len(info["NUTTX_CONFIG"])
|
|
)
|
|
output += "static const char *NUTTX_CONFIG[NUTTX_CONFIG_ARRAY_SIZE] =\n{\n"
|
|
for i in range(len(info["NUTTX_CONFIG"])):
|
|
output += ' "' + info["NUTTX_CONFIG"][i].replace('"', '\\"') + '",\n'
|
|
output += "};\n\n"
|
|
except FileNotFoundError:
|
|
print("Error: NuttX configuration file not found: {}".format(config_path))
|
|
sys.exit(1)
|
|
|
|
# OS Version
|
|
|
|
info["OS_VERSION"] = get_os_version()
|
|
output += 'static const char OS_VERSION[] = "{}";\n\n'.format(info["OS_VERSION"])
|
|
|
|
# System Path
|
|
|
|
if args.path:
|
|
info["SYSTEM_PATH"] = str(get_system_path()).split(":")
|
|
output += "#define SYSTEM_PATH_ARRAY_SIZE {}\n".format(len(info["SYSTEM_PATH"]))
|
|
output += "static const char *SYSTEM_PATH[SYSTEM_PATH_ARRAY_SIZE] =\n{\n"
|
|
for i in range(len(info["SYSTEM_PATH"])):
|
|
output += ' "' + info["SYSTEM_PATH"][i] + '",\n'
|
|
output += "};\n\n"
|
|
|
|
# Installed Packages
|
|
|
|
if args.packages:
|
|
info["INSTALLED_PACKAGES"] = [str(x) for x in get_installed_packages()]
|
|
output += "#define INSTALLED_PACKAGES_ARRAY_SIZE {}\n".format(
|
|
len(info["INSTALLED_PACKAGES"])
|
|
)
|
|
output += "static const char *INSTALLED_PACKAGES[INSTALLED_PACKAGES_ARRAY_SIZE] =\n{\n"
|
|
for i in range(len(info["INSTALLED_PACKAGES"])):
|
|
output += ' "' + info["INSTALLED_PACKAGES"][i] + '",\n'
|
|
output += "};\n\n"
|
|
|
|
# Python Modules
|
|
|
|
if args.modules:
|
|
info["PYTHON_MODULES"] = [str(x) for x in get_python_modules()]
|
|
output += "#define PYTHON_MODULES_ARRAY_SIZE {}\n".format(
|
|
len(info["PYTHON_MODULES"])
|
|
)
|
|
output += "static const char *PYTHON_MODULES[PYTHON_MODULES_ARRAY_SIZE] =\n{\n"
|
|
for i in range(len(info["PYTHON_MODULES"])):
|
|
output += ' "' + info["PYTHON_MODULES"][i] + '",\n'
|
|
output += "};\n\n"
|
|
|
|
# Vendor Specific
|
|
|
|
# Espressif
|
|
|
|
if args.espressif:
|
|
# Espressif bootloader version
|
|
|
|
info["ESPRESSIF_BOOTLOADER"] = get_espressif_bootloader_version(
|
|
args.espressif[0]
|
|
)
|
|
output += "#define ESPRESSIF_BOOTLOADER_ARRAY_SIZE {}\n".format(
|
|
len(info["ESPRESSIF_BOOTLOADER"])
|
|
)
|
|
output += "static const char *ESPRESSIF_BOOTLOADER[ESPRESSIF_BOOTLOADER_ARRAY_SIZE] =\n{\n"
|
|
build_output = "Bootloader version:\n"
|
|
for key, value in info["ESPRESSIF_BOOTLOADER"].items():
|
|
output += ' "{}: {}",\n'.format(key, value)
|
|
build_output += " {}: {},\n".format(key, value)
|
|
output += "};\n\n"
|
|
build_output += "\n\n"
|
|
|
|
# Espressif toolchain version
|
|
|
|
info["ESPRESSIF_TOOLCHAIN"] = get_espressif_toolchain_version()
|
|
output += "#define ESPRESSIF_TOOLCHAIN_ARRAY_SIZE {}\n".format(
|
|
len(info["ESPRESSIF_TOOLCHAIN"])
|
|
)
|
|
output += "static const char *ESPRESSIF_TOOLCHAIN[ESPRESSIF_TOOLCHAIN_ARRAY_SIZE] =\n{\n"
|
|
build_output += "Toolchain version:\n"
|
|
for key, value in info["ESPRESSIF_TOOLCHAIN"].items():
|
|
output += ' "{}: {}",\n'.format(key, value)
|
|
build_output += " {}: {},\n".format(key, value)
|
|
output += "};\n\n"
|
|
build_output += "\n\n"
|
|
|
|
# Espressif esptool version
|
|
|
|
info["ESPRESSIF_ESPTOOL"] = next(
|
|
(s for s in get_python_modules() if "esptool" in s), "Not found"
|
|
)
|
|
output += 'static const char ESPRESSIF_ESPTOOL[] = "{}";\n\n'.format(
|
|
info["ESPRESSIF_ESPTOOL"].split("-")[1]
|
|
)
|
|
build_output += "Esptool version: {}\n\n".format(
|
|
info["ESPRESSIF_ESPTOOL"].split("-")[1]
|
|
)
|
|
|
|
# Espressif HAL version
|
|
|
|
info["ESPRESSIF_HAL"] = get_espressif_hal_version(args.espressif[1])
|
|
output += 'static const char ESPRESSIF_HAL[] = "{}";\n\n'.format(
|
|
info["ESPRESSIF_HAL"]
|
|
)
|
|
build_output += "HAL version: {}\n\n".format(info["ESPRESSIF_HAL"])
|
|
|
|
if args.espressif_chip and info["ESPRESSIF_ESPTOOL"] not in "Not found":
|
|
info["ESPRESSIF_CHIP_ID"] = get_espressif_chip_id()
|
|
output += 'static const char ESPRESSIF_CHIP_ID[] = "{}";\n\n'.format(
|
|
info["ESPRESSIF_CHIP_ID"]
|
|
)
|
|
build_output += "CHIP ID: = {}\n\n".format(info["ESPRESSIF_CHIP_ID"])
|
|
|
|
info["ESPRESSIF_FLASH_ID"] = get_espressif_flash_id()
|
|
output += "#define ESPRESSIF_FLASH_ID_ARRAY_SIZE {}\n".format(
|
|
len(info["ESPRESSIF_FLASH_ID"])
|
|
)
|
|
output += "static const char *ESPRESSIF_FLASH_ID[ESPRESSIF_FLASH_ID_ARRAY_SIZE] =\n{\n"
|
|
build_output += "Flash ID:\n"
|
|
for each_item in info["ESPRESSIF_FLASH_ID"]:
|
|
output += ' "{}",\n'.format(each_item)
|
|
build_output += " {}\n".format(each_item)
|
|
output += "};\n\n"
|
|
build_output += "\n\n"
|
|
|
|
info["ESPRESSIF_SECURITY_INFO"] = get_espressif_security_info()
|
|
output += "#define ESPRESSIF_SECURITY_INFO_ARRAY_SIZE {}\n".format(
|
|
len(info["ESPRESSIF_SECURITY_INFO"])
|
|
)
|
|
output += "static const char *ESPRESSIF_SECURITY_INFO[ESPRESSIF_SECURITY_INFO_ARRAY_SIZE] =\n{\n"
|
|
build_output += "Security information: \n"
|
|
for each_item in info["ESPRESSIF_SECURITY_INFO"]:
|
|
output += ' "{}",\n'.format(each_item)
|
|
build_output += " {}\n".format(each_item)
|
|
output += "};\n\n"
|
|
build_output += "\n\n"
|
|
|
|
info["ESPRESSIF_FLASH_STAT"] = get_espressif_flash_status()
|
|
output += 'static const char ESPRESSIF_FLASH_STAT[] = "{}";\n\n'.format(
|
|
info["ESPRESSIF_FLASH_STAT"]
|
|
)
|
|
build_output += "Flash status: {}\n\n".format(info["ESPRESSIF_FLASH_STAT"])
|
|
|
|
info["ESPRESSIF_MAC_ADDR"] = get_espressif_mac_address()
|
|
output += 'static const char ESPRESSIF_MAC_ADDR[] = "{}";\n\n'.format(
|
|
info["ESPRESSIF_MAC_ADDR"]
|
|
)
|
|
build_output += "MAC address: {}\n\n".format(info["ESPRESSIF_MAC_ADDR"])
|
|
|
|
elif args.espressif_chip_runtime:
|
|
output += "#define ESPRESSIF_INFO_SIZE 384\n"
|
|
output += "static char ESPRESSIF_INFO[ESPRESSIF_TOOLCHAIN_ARRAY_SIZE] =\n{\n 0\n};\n\n"
|
|
|
|
verbose(info, build_output)
|
|
|
|
output += "#endif /* __SYSTEM_INFO_H */\n"
|
|
|
|
return output
|
|
|
|
|
|
# Main #
|
|
|
|
if __name__ == "__main__":
|
|
"""
|
|
Main function for the script. This function is called when the script is
|
|
executed directly. It parses the command line arguments and calls the
|
|
appropriate functions. It also prints the output generated to stdout.
|
|
|
|
Required arguments:
|
|
nuttx_path: The path to the NuttX source directory.
|
|
|
|
Optional arguments:
|
|
The command line arguments. The available arguments are:
|
|
-h, --help:
|
|
Show the help message and exit.
|
|
-m, --modules:
|
|
Get the list of installed Python modules.
|
|
-k, --packages:
|
|
Get the list of installed system packages.
|
|
-p, --path:
|
|
Get the system PATH environment variable.
|
|
-c, --config:
|
|
Get the NuttX compilation configurations used.
|
|
-f, --flags <CFLAGS> <CXXFLAGS> <LDFLAGS>:
|
|
Provide the NuttX compilation flags used.
|
|
--verbose:
|
|
Enable printing information during build.
|
|
--espressif <ESPTOOL_BINDIR>:
|
|
Get Espressif specific information.
|
|
Requires the path to the bootloader binary directory.
|
|
--espressif_chip:
|
|
Get Espressif specific information about chip.
|
|
Requires device connection during build.
|
|
--espressif_chip_runtime:
|
|
Get Espressif specific information about chip
|
|
on runtime.
|
|
Requires device connection during build.
|
|
"""
|
|
|
|
# Generic arguments
|
|
|
|
parser = argparse.ArgumentParser(add_help=False)
|
|
parser.add_argument("nuttx_path", help="NuttX source directory path.")
|
|
parser.add_argument(
|
|
"-h",
|
|
"--help",
|
|
action="help",
|
|
default=argparse.SUPPRESS,
|
|
help="Show this help message and exit.",
|
|
)
|
|
parser.add_argument(
|
|
"-m",
|
|
"--modules",
|
|
action="store_true",
|
|
help="Get the list of installed Python modules.",
|
|
)
|
|
parser.add_argument(
|
|
"-k",
|
|
"--packages",
|
|
action="store_true",
|
|
help="Get the list of installed system packages.",
|
|
)
|
|
parser.add_argument(
|
|
"-p",
|
|
"--path",
|
|
action="store_true",
|
|
help="Get the system PATH environment variable.",
|
|
)
|
|
parser.add_argument(
|
|
"-c",
|
|
"--config",
|
|
action="store_true",
|
|
help="Get the NuttX compilation configurations used.",
|
|
)
|
|
parser.add_argument(
|
|
"-f",
|
|
"--flags",
|
|
nargs=3,
|
|
default=[],
|
|
metavar=("CFLAGS", "CXXFLAGS", "LDFLAGS"),
|
|
action=validate_flags_arg,
|
|
help="Provide the NuttX compilation and linker flags used.",
|
|
)
|
|
parser.add_argument(
|
|
"--verbose",
|
|
action="store_true",
|
|
help="Enable printing information during build",
|
|
)
|
|
|
|
# Vendor specific arguments
|
|
|
|
parser.add_argument(
|
|
"--espressif",
|
|
nargs=2,
|
|
default=[],
|
|
metavar=("ESPTOOL_BINDIR", "ESP_HAL_DIR"),
|
|
help="Get Espressif specific information. Requires the path to the bootloader binary and ESP HAL directories.",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--espressif_chip",
|
|
action="store_true",
|
|
help="Get Espressif specific information about chip. Requires device connection during build.",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--espressif_chip_runtime",
|
|
action="store_true",
|
|
help="Get Espressif specific information about chip on runtime. Requires device connection during build.",
|
|
)
|
|
|
|
# Parse arguments
|
|
|
|
if len(sys.argv) == 1:
|
|
parser.print_help()
|
|
sys.exit(1)
|
|
|
|
args = parser.parse_args()
|
|
os.chdir(args.nuttx_path)
|
|
header = generate_header(args)
|
|
print(header)
|