mirror of
https://github.com/esphome/esphome.git
synced 2025-04-07 03:10:27 +01:00
218 lines
6.2 KiB
Python
218 lines
6.2 KiB
Python
import os
|
|
from typing import Union
|
|
import esphome.codegen as cg
|
|
from esphome.core import CORE
|
|
from esphome.helpers import (
|
|
write_file_if_changed,
|
|
copy_file_if_changed,
|
|
)
|
|
from esphome.const import (
|
|
CONF_VARIANT,
|
|
CONF_BOARD,
|
|
KEY_NAME,
|
|
)
|
|
from .const import (
|
|
ZEPHYR_VARIANT_GENERIC,
|
|
ZEPHYR_VARIANT_NRF_SDK,
|
|
KEY_ZEPHYR,
|
|
KEY_PRJ_CONF,
|
|
KEY_OVERLAY,
|
|
zephyr_ns,
|
|
BOOTLOADER_MCUBOOT,
|
|
KEY_EXTRA_BUILD_FILES,
|
|
KEY_PATH,
|
|
)
|
|
|
|
|
|
AUTO_LOAD = ["preferences"]
|
|
KEY_BOARD = "board"
|
|
|
|
KEY_BOOTLOADER = "bootloader"
|
|
|
|
|
|
def zephyr_set_core_data(config):
|
|
CORE.data[KEY_ZEPHYR] = {}
|
|
CORE.data[KEY_ZEPHYR][KEY_BOARD] = config[CONF_BOARD]
|
|
CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF] = {}
|
|
CORE.data[KEY_ZEPHYR][KEY_OVERLAY] = ""
|
|
CORE.data[KEY_ZEPHYR][KEY_BOOTLOADER] = config[KEY_BOOTLOADER]
|
|
CORE.data[KEY_ZEPHYR][KEY_EXTRA_BUILD_FILES] = {}
|
|
return config
|
|
|
|
|
|
PrjConfValueType = Union[bool, str, int]
|
|
|
|
|
|
def zephyr_add_prj_conf(name: str, value: PrjConfValueType):
|
|
"""Set an zephyr prj conf value."""
|
|
if not CORE.using_zephyr:
|
|
raise ValueError("Not an zephyr project")
|
|
if not name.startswith("CONFIG_"):
|
|
name = "CONFIG_" + name
|
|
if name in CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF]:
|
|
old_value = CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF][name]
|
|
if old_value != value:
|
|
raise ValueError(
|
|
f"{name} alread set with value {old_value}, new value {value}"
|
|
)
|
|
CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF][name] = value
|
|
|
|
|
|
def zephyr_add_overlay(content):
|
|
if not CORE.using_zephyr:
|
|
raise ValueError("Not an zephyr project")
|
|
CORE.data[KEY_ZEPHYR][KEY_OVERLAY] += content
|
|
|
|
|
|
def add_extra_build_file(filename: str, path: str) -> bool:
|
|
"""Add an extra build file to the project."""
|
|
if filename not in CORE.data[KEY_ZEPHYR][KEY_EXTRA_BUILD_FILES]:
|
|
CORE.data[KEY_ZEPHYR][KEY_EXTRA_BUILD_FILES][filename] = {
|
|
KEY_NAME: filename,
|
|
KEY_PATH: path,
|
|
}
|
|
return True
|
|
return False
|
|
|
|
|
|
def add_extra_script(stage: str, filename: str, path: str):
|
|
"""Add an extra script to the project."""
|
|
key = f"{stage}:{filename}"
|
|
if add_extra_build_file(filename, path):
|
|
cg.add_platformio_option("extra_scripts", [key])
|
|
|
|
|
|
def zephyr_to_code(conf):
|
|
cg.add(zephyr_ns.setup_preferences())
|
|
cg.add_build_flag("-DUSE_ZEPHYR")
|
|
if conf[CONF_VARIANT] == ZEPHYR_VARIANT_GENERIC:
|
|
cg.add_platformio_option(
|
|
"platform_packages",
|
|
[
|
|
"platformio/framework-zephyr@^2.30500.231204",
|
|
],
|
|
)
|
|
elif conf[CONF_VARIANT] == ZEPHYR_VARIANT_NRF_SDK:
|
|
cg.add_platformio_option(
|
|
"platform_packages",
|
|
[
|
|
"platformio/framework-zephyr@https://github.com/tomaszduda23/framework-sdk-nrf",
|
|
"platformio/toolchain-gccarmnoneeabi@https://github.com/tomaszduda23/toolchain-sdk-ng",
|
|
],
|
|
)
|
|
# build is done by west so bypass board checking in platformio
|
|
cg.add_platformio_option("boards_dir", CORE.relative_build_path("boards"))
|
|
else:
|
|
raise NotImplementedError
|
|
# c++ support
|
|
zephyr_add_prj_conf("NEWLIB_LIBC", True)
|
|
zephyr_add_prj_conf("CONFIG_FPU", True)
|
|
zephyr_add_prj_conf("NEWLIB_LIBC_FLOAT_PRINTF", True)
|
|
zephyr_add_prj_conf("CPLUSPLUS", True)
|
|
zephyr_add_prj_conf("LIB_CPLUSPLUS", True)
|
|
# preferences
|
|
zephyr_add_prj_conf("SETTINGS", True)
|
|
zephyr_add_prj_conf("NVS", True)
|
|
zephyr_add_prj_conf("FLASH_MAP", True)
|
|
zephyr_add_prj_conf("CONFIG_FLASH", True)
|
|
# watchdog
|
|
zephyr_add_prj_conf("WATCHDOG", True)
|
|
zephyr_add_prj_conf("WDT_DISABLE_AT_BOOT", False)
|
|
# disable console
|
|
zephyr_add_prj_conf("UART_CONSOLE", False)
|
|
zephyr_add_prj_conf("CONSOLE", False)
|
|
# TODO debug only
|
|
zephyr_add_prj_conf("DEBUG_THREAD_INFO", True)
|
|
# zephyr_add_prj_conf("DEBUG", True)
|
|
###
|
|
zephyr_add_prj_conf("USE_SEGGER_RTT", True)
|
|
zephyr_add_prj_conf("RTT_CONSOLE", True)
|
|
zephyr_add_prj_conf("LOG", True)
|
|
zephyr_add_prj_conf("LOG_BLOCK_IN_THREAD", True)
|
|
zephyr_add_prj_conf("LOG_BUFFER_SIZE", 4096)
|
|
zephyr_add_prj_conf("SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL", True)
|
|
|
|
zephyr_add_prj_conf("USB_CDC_ACM_LOG_LEVEL_WRN", True)
|
|
|
|
add_extra_script(
|
|
"pre",
|
|
"pre_build.py",
|
|
os.path.join(os.path.dirname(__file__), "pre_build.py.script"),
|
|
)
|
|
add_extra_script(
|
|
"post",
|
|
"post_build.py",
|
|
os.path.join(os.path.dirname(__file__), "post_build.py.script"),
|
|
)
|
|
|
|
|
|
def _format_prj_conf_val(value: PrjConfValueType) -> str:
|
|
if isinstance(value, bool):
|
|
return "y" if value else "n"
|
|
if isinstance(value, int):
|
|
return str(value)
|
|
if isinstance(value, str):
|
|
return f'"{value}"'
|
|
raise ValueError
|
|
|
|
|
|
# Called by writer.py
|
|
def copy_files():
|
|
want_opts = CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF]
|
|
contents = (
|
|
"\n".join(
|
|
f"{name}={_format_prj_conf_val(value)}"
|
|
for name, value in sorted(want_opts.items())
|
|
)
|
|
+ "\n"
|
|
)
|
|
|
|
write_file_if_changed(CORE.relative_build_path("zephyr/prj.conf"), contents)
|
|
write_file_if_changed(
|
|
CORE.relative_build_path("zephyr/app.overlay"),
|
|
CORE.data[KEY_ZEPHYR][KEY_OVERLAY],
|
|
)
|
|
|
|
write_file_if_changed(
|
|
CORE.relative_build_path("zephyr/child_image/mcuboot.conf"),
|
|
"""
|
|
CONFIG_MCUBOOT_SERIAL=y
|
|
CONFIG_BOOT_SERIAL_PIN_RESET=y
|
|
CONFIG_UART_CONSOLE=n
|
|
CONFIG_BOOT_SERIAL_ENTRANCE_GPIO=n
|
|
CONFIG_BOOT_SERIAL_CDC_ACM=y
|
|
CONFIG_UART_NRFX=n
|
|
CONFIG_LOG=n
|
|
CONFIG_ASSERT_VERBOSE=n
|
|
CONFIG_BOOT_BANNER=n
|
|
CONFIG_PRINTK=n
|
|
CONFIG_CBPRINTF_LIBC_SUBSTS=n
|
|
""",
|
|
)
|
|
|
|
if CORE.data[KEY_ZEPHYR][KEY_BOOTLOADER] == BOOTLOADER_MCUBOOT:
|
|
fake_board_manifest = """
|
|
{
|
|
"frameworks": [
|
|
"zephyr"
|
|
],
|
|
"name": "esphome nrf52",
|
|
"upload": {
|
|
"maximum_ram_size": 248832,
|
|
"maximum_size": 815104
|
|
},
|
|
"url": "https://esphome.io/",
|
|
"vendor": "esphome"
|
|
}
|
|
"""
|
|
write_file_if_changed(
|
|
CORE.relative_build_path(f"boards/{CORE.data[KEY_ZEPHYR][KEY_BOARD]}.json"),
|
|
fake_board_manifest,
|
|
)
|
|
|
|
for _, file in CORE.data[KEY_ZEPHYR][KEY_EXTRA_BUILD_FILES].items():
|
|
copy_file_if_changed(
|
|
file[KEY_PATH],
|
|
CORE.relative_build_path(file[KEY_NAME]),
|
|
)
|