Merge branch 'no_delay_startup_many_entities' into integration

This commit is contained in:
J. Nick Koston
2026-01-03 09:34:22 -10:00
9 changed files with 67 additions and 51 deletions

View File

@@ -398,7 +398,7 @@ async def to_code(config):
except cv.Invalid:
pass
if CORE.using_zephyr:
if CORE.is_nrf52:
if config[CONF_HARDWARE_UART] == UART0:
zephyr_add_overlay("""&uart0 { status = "okay";};""")
if config[CONF_HARDWARE_UART] == UART1:

View File

@@ -12,6 +12,7 @@ from esphome.components.zephyr import (
zephyr_add_prj_conf,
zephyr_data,
zephyr_set_core_data,
zephyr_setup_preferences,
zephyr_to_code,
)
from esphome.components.zephyr.const import (
@@ -49,7 +50,7 @@ from .const import (
from .gpio import nrf52_pin_to_code # noqa
CODEOWNERS = ["@tomaszduda23"]
AUTO_LOAD = ["zephyr"]
AUTO_LOAD = ["zephyr", "preferences"]
IS_TARGET_PLATFORM = True
_LOGGER = logging.getLogger(__name__)
@@ -194,6 +195,7 @@ async def to_code(config: ConfigType) -> None:
cg.add_platformio_option("board_upload.require_upload_port", "true")
cg.add_platformio_option("board_upload.wait_for_upload_port", "true")
zephyr_setup_preferences()
zephyr_to_code(config)
if dfu_config := config.get(CONF_DFU):
@@ -206,6 +208,18 @@ async def to_code(config: ConfigType) -> None:
if reg0_config[CONF_UICR_ERASE]:
cg.add_define("USE_NRF52_UICR_ERASE")
# c++ support
zephyr_add_prj_conf("CPLUSPLUS", True)
zephyr_add_prj_conf("LIB_CPLUSPLUS", 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)
# use NFC pins as GPIO
zephyr_add_prj_conf("NFCT_PINS_AS_GPIOS", True)
@coroutine_with_priority(CoroPriority.DIAGNOSTICS)
async def _dfu_to_code(dfu_config):

View File

@@ -71,8 +71,15 @@ NRF52_PIN_SCHEMA = cv.All(
@pins.PIN_SCHEMA_REGISTRY.register(PLATFORM_NRF52, NRF52_PIN_SCHEMA)
async def nrf52_pin_to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
num = config[CONF_NUMBER]
port = num // 32
pin_name_prefix = f"P{port}."
var = cg.new_Pvariable(
config[CONF_ID],
cg.RawExpression(f"DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio{port}))"),
32,
pin_name_prefix,
)
cg.add(var.set_pin(num))
# Only set if true to avoid bloating setup() function
# (inverted bit in pin_flags_ bitfield is zero-initialized to false)

View File

@@ -21,7 +21,6 @@ from .const import (
)
CODEOWNERS = ["@tomaszduda23"]
AUTO_LOAD = ["preferences"]
PrjConfValueType = bool | str | int
@@ -111,32 +110,15 @@ def add_extra_script(stage: str, filename: str, path: Path) -> None:
def zephyr_to_code(config):
cg.add(zephyr_ns.setup_preferences())
cg.add_build_flag("-DUSE_ZEPHYR")
cg.set_cpp_standard("gnu++20")
# build is done by west so bypass board checking in platformio
cg.add_platformio_option("boards_dir", CORE.relative_build_path("boards"))
# c++ support
zephyr_add_prj_conf("NEWLIB_LIBC", True)
zephyr_add_prj_conf("CONFIG_FPU", True)
zephyr_add_prj_conf("FPU", True)
zephyr_add_prj_conf("NEWLIB_LIBC_FLOAT_PRINTF", True)
zephyr_add_prj_conf("CPLUSPLUS", True)
zephyr_add_prj_conf("CONFIG_STD_CPP20", 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, False)
# use NFC pins as GPIO
zephyr_add_prj_conf("NFCT_PINS_AS_GPIOS", True)
zephyr_add_prj_conf("STD_CPP20", True)
# <err> os: ***** USAGE FAULT *****
# <err> os: Illegal load of EXC_RETURN into PC
@@ -149,6 +131,14 @@ def zephyr_to_code(config):
)
def zephyr_setup_preferences():
cg.add(zephyr_ns.setup_preferences())
zephyr_add_prj_conf("SETTINGS", True)
zephyr_add_prj_conf("NVS", True)
zephyr_add_prj_conf("FLASH_MAP", True)
zephyr_add_prj_conf("FLASH", True)
def _format_prj_conf_val(value: PrjConfValueType) -> str:
if isinstance(value, bool):
return "y" if value else "n"

View File

@@ -10,8 +10,10 @@
namespace esphome {
#ifdef CONFIG_WATCHDOG
static int wdt_channel_id = -1; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
static const device *const WDT = DEVICE_DT_GET(DT_ALIAS(watchdog0));
#endif
void yield() { ::k_yield(); }
uint32_t millis() { return k_ticks_to_ms_floor32(k_uptime_ticks()); }
@@ -20,6 +22,7 @@ void delayMicroseconds(uint32_t us) { ::k_usleep(us); }
void delay(uint32_t ms) { ::k_msleep(ms); }
void arch_init() {
#ifdef CONFIG_WATCHDOG
if (device_is_ready(WDT)) {
static wdt_timeout_cfg wdt_config{};
wdt_config.flags = WDT_FLAG_RESET_SOC;
@@ -36,12 +39,15 @@ void arch_init() {
wdt_setup(WDT, options);
}
}
#endif
}
void arch_feed_wdt() {
#ifdef CONFIG_WATCHDOG
if (wdt_channel_id >= 0) {
wdt_feed(WDT, wdt_channel_id);
}
#endif
}
void arch_restart() { sys_reboot(SYS_REBOOT_COLD); }
@@ -72,6 +78,7 @@ bool random_bytes(uint8_t *data, size_t len) {
return true;
}
#ifdef USE_NRF52
void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
mac[0] = ((NRF_FICR->DEVICEADDR[1] & 0xFFFF) >> 8) | 0xC0;
mac[1] = NRF_FICR->DEVICEADDR[1] & 0xFFFF;
@@ -80,7 +87,7 @@ void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parame
mac[4] = NRF_FICR->DEVICEADDR[0] >> 8;
mac[5] = NRF_FICR->DEVICEADDR[0];
}
#endif
} // namespace esphome
void setup();

View File

@@ -50,25 +50,7 @@ void ZephyrGPIOPin::attach_interrupt(void (*func)(void *), void *arg, gpio::Inte
}
void ZephyrGPIOPin::setup() {
const struct device *gpio = nullptr;
if (this->pin_ < 32) {
#define GPIO0 DT_NODELABEL(gpio0)
#if DT_NODE_HAS_STATUS(GPIO0, okay)
gpio = DEVICE_DT_GET(GPIO0);
#else
#error "gpio0 is disabled"
#endif
} else {
#define GPIO1 DT_NODELABEL(gpio1)
#if DT_NODE_HAS_STATUS(GPIO1, okay)
gpio = DEVICE_DT_GET(GPIO1);
#else
#error "gpio1 is disabled"
#endif
}
if (device_is_ready(gpio)) {
this->gpio_ = gpio;
} else {
if (!device_is_ready(this->gpio_)) {
ESP_LOGE(TAG, "gpio %u is not ready.", this->pin_);
return;
}
@@ -79,21 +61,22 @@ void ZephyrGPIOPin::pin_mode(gpio::Flags flags) {
if (nullptr == this->gpio_) {
return;
}
auto ret = gpio_pin_configure(this->gpio_, this->pin_ % 32, flags_to_mode(flags, this->inverted_, this->value_));
auto ret = gpio_pin_configure(this->gpio_, this->pin_ % this->gpio_size_,
flags_to_mode(flags, this->inverted_, this->value_));
if (ret != 0) {
ESP_LOGE(TAG, "gpio %u cannot be configured %d.", this->pin_, ret);
}
}
size_t ZephyrGPIOPin::dump_summary(char *buffer, size_t len) const {
return snprintf(buffer, len, "GPIO%u, P%u.%u", this->pin_, this->pin_ / 32, this->pin_ % 32);
return snprintf(buffer, len, "GPIO%u, %s%u", this->pin_, this->pin_name_prefix_, this->pin_ % this->gpio_size_);
}
bool ZephyrGPIOPin::digital_read() {
if (nullptr == this->gpio_) {
return false;
}
return bool(gpio_pin_get(this->gpio_, this->pin_ % 32) != this->inverted_);
return bool(gpio_pin_get(this->gpio_, this->pin_ % this->gpio_size_) != this->inverted_);
}
void ZephyrGPIOPin::digital_write(bool value) {
@@ -103,7 +86,7 @@ void ZephyrGPIOPin::digital_write(bool value) {
if (nullptr == this->gpio_) {
return;
}
gpio_pin_set(this->gpio_, this->pin_ % 32, value != this->inverted_ ? 1 : 0);
gpio_pin_set(this->gpio_, this->pin_ % this->gpio_size_, value != this->inverted_ ? 1 : 0);
}
void ZephyrGPIOPin::detach_interrupt() const {
// TODO

View File

@@ -8,6 +8,11 @@ namespace zephyr {
class ZephyrGPIOPin : public InternalGPIOPin {
public:
ZephyrGPIOPin(const device *gpio, int gpio_size, const char *pin_name_prefix) {
this->gpio_ = gpio;
this->gpio_size_ = gpio_size;
this->pin_name_prefix_ = pin_name_prefix;
}
void set_pin(uint8_t pin) { this->pin_ = pin; }
void set_inverted(bool inverted) { this->inverted_ = inverted; }
void set_flags(gpio::Flags flags) { this->flags_ = flags; }
@@ -25,10 +30,12 @@ class ZephyrGPIOPin : public InternalGPIOPin {
protected:
void attach_interrupt(void (*func)(void *), void *arg, gpio::InterruptType type) const override;
uint8_t pin_;
bool inverted_{};
gpio::Flags flags_{};
const device *gpio_{nullptr};
const char *pin_name_prefix_{nullptr};
gpio::Flags flags_{};
uint8_t pin_;
uint8_t gpio_size_{};
bool inverted_{};
bool value_{false};
};

View File

@@ -1,4 +1,5 @@
#ifdef USE_ZEPHYR
#ifdef CONFIG_SETTINGS
#include <zephyr/kernel.h>
#include "esphome/core/preferences.h"
@@ -154,3 +155,4 @@ ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const
} // namespace esphome
#endif
#endif

View File

@@ -205,7 +205,13 @@ void Component::call() {
this->call_setup();
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
uint32_t setup_time = millis() - start_time;
ESP_LOGCONFIG(TAG, "Setup %s took %ums", LOG_STR_ARG(this->get_component_log_str()), (unsigned) setup_time);
// Only log at CONFIG level if setup took longer than the blocking threshold
// to avoid spamming the log and blocking the event loop
if (setup_time >= WARN_IF_BLOCKING_OVER_MS) {
ESP_LOGCONFIG(TAG, "Setup %s took %ums", LOG_STR_ARG(this->get_component_log_str()), (unsigned) setup_time);
} else {
ESP_LOGV(TAG, "Setup %s took %ums", LOG_STR_ARG(this->get_component_log_str()), (unsigned) setup_time);
}
#endif
break;
}