Compare commits
3 Commits
dev
...
host-targe
Author | SHA1 | Date | |
---|---|---|---|
|
7f0dc7b07b | ||
|
1ab4928959 | ||
|
52b86e3440 |
38
esphome/components/host/__init__.py
Normal file
38
esphome/components/host/__init__.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
from esphome.const import (
|
||||||
|
KEY_CORE,
|
||||||
|
KEY_FRAMEWORK_VERSION,
|
||||||
|
KEY_TARGET_FRAMEWORK,
|
||||||
|
KEY_TARGET_PLATFORM,
|
||||||
|
)
|
||||||
|
from esphome.core import CORE
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
import esphome.codegen as cg
|
||||||
|
|
||||||
|
from .const import KEY_HOST
|
||||||
|
|
||||||
|
# force import gpio to register pin schema
|
||||||
|
from .gpio import host_pin_to_code # noqa
|
||||||
|
|
||||||
|
|
||||||
|
CODEOWNERS = ["@esphome/core"]
|
||||||
|
AUTO_LOAD = ["network"]
|
||||||
|
|
||||||
|
|
||||||
|
def set_core_data(config):
|
||||||
|
CORE.data[KEY_HOST] = {}
|
||||||
|
CORE.data[KEY_CORE][KEY_TARGET_PLATFORM] = "host"
|
||||||
|
CORE.data[KEY_CORE][KEY_TARGET_FRAMEWORK] = "host"
|
||||||
|
CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] = cv.Version(1, 0, 0)
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.All(
|
||||||
|
cv.Schema({}),
|
||||||
|
set_core_data,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
cg.add_build_flag("-DUSE_HOST")
|
||||||
|
cg.add_define("ESPHOME_BOARD", "host")
|
||||||
|
cg.add_platformio_option("platform", "platformio/native")
|
5
esphome/components/host/const.py
Normal file
5
esphome/components/host/const.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
|
||||||
|
KEY_HOST = "host"
|
||||||
|
|
||||||
|
host_ns = cg.esphome_ns.namespace("host")
|
74
esphome/components/host/core.cpp
Normal file
74
esphome/components/host/core.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#ifdef USE_HOST
|
||||||
|
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "preferences.h"
|
||||||
|
|
||||||
|
#include <sched.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
|
||||||
|
void IRAM_ATTR HOT yield() { ::sched_yield(); }
|
||||||
|
uint32_t IRAM_ATTR HOT millis() {
|
||||||
|
struct timespec spec;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &spec);
|
||||||
|
time_t seconds = spec.tv_sec;
|
||||||
|
uint32_t ms = round(spec.tv_nsec / 1e6);
|
||||||
|
return ((uint32_t) seconds) * 1000U + ms;
|
||||||
|
}
|
||||||
|
void IRAM_ATTR HOT delay(uint32_t ms) {
|
||||||
|
struct timespec ts;
|
||||||
|
ts.tv_sec = ms / 1000;
|
||||||
|
ts.tv_nsec = (ms % 1000) * 1000000;
|
||||||
|
int res;
|
||||||
|
do {
|
||||||
|
res = nanosleep(&ts, &ts);
|
||||||
|
} while (res != 0 && errno == EINTR);
|
||||||
|
}
|
||||||
|
uint32_t IRAM_ATTR HOT micros() {
|
||||||
|
struct timespec spec;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &spec);
|
||||||
|
time_t seconds = spec.tv_sec;
|
||||||
|
uint32_t us = round(spec.tv_nsec / 1e3);
|
||||||
|
return ((uint32_t) seconds) * 1000000U + us;
|
||||||
|
}
|
||||||
|
void IRAM_ATTR HOT delayMicroseconds(uint32_t us) {
|
||||||
|
struct timespec ts;
|
||||||
|
ts.tv_sec = us / 1000000U;
|
||||||
|
ts.tv_nsec = (us % 1000000U) * 1000U;
|
||||||
|
int res;
|
||||||
|
do {
|
||||||
|
res = nanosleep(&ts, &ts);
|
||||||
|
} while (res != 0 && errno == EINTR);
|
||||||
|
}
|
||||||
|
void arch_restart() { exit(0); }
|
||||||
|
void IRAM_ATTR HOT arch_feed_wdt() {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t progmem_read_byte(const uint8_t *addr) { return *addr; }
|
||||||
|
uint32_t arch_get_cpu_cycle_count() {
|
||||||
|
struct timespec spec;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &spec);
|
||||||
|
time_t seconds = spec.tv_sec;
|
||||||
|
uint32_t us = spec.tv_nsec;
|
||||||
|
return ((uint32_t) seconds) * 1000000000U + us;
|
||||||
|
}
|
||||||
|
uint32_t arch_get_cpu_freq_hz() { return 1000000000U; }
|
||||||
|
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
void loop();
|
||||||
|
int main() {
|
||||||
|
esphome::host::setup_preferences();
|
||||||
|
setup();
|
||||||
|
while (true) {
|
||||||
|
loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_HOST
|
59
esphome/components/host/gpio.cpp
Normal file
59
esphome/components/host/gpio.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#ifdef USE_HOST
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace host {
|
||||||
|
|
||||||
|
static const char *const TAG = "host";
|
||||||
|
|
||||||
|
struct ISRPinArg {
|
||||||
|
uint8_t pin;
|
||||||
|
bool inverted;
|
||||||
|
};
|
||||||
|
|
||||||
|
ISRInternalGPIOPin HostGPIOPin::to_isr() const {
|
||||||
|
auto *arg = new ISRPinArg{}; // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
|
arg->pin = pin_;
|
||||||
|
arg->inverted = inverted_;
|
||||||
|
return ISRInternalGPIOPin((void *) arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HostGPIOPin::attach_interrupt_(void (*func)(void *), void *arg, gpio::InterruptType type) const {
|
||||||
|
ESP_LOGD(TAG, "Attaching interrupt %p to pin %d and mode %d", func, pin_, (uint32_t) type);
|
||||||
|
}
|
||||||
|
void HostGPIOPin::pin_mode(gpio::Flags flags) { ESP_LOGD(TAG, "Setting pin %d mode to %02X", pin_, (uint32_t) flags); }
|
||||||
|
|
||||||
|
std::string HostGPIOPin::dump_summary() const {
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "GPIO%u", pin_);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HostGPIOPin::digital_read() { return inverted_; }
|
||||||
|
void HostGPIOPin::digital_write(bool value) {
|
||||||
|
// pass
|
||||||
|
ESP_LOGD(TAG, "Setting pin %d to %s", pin_, value != inverted_ ? "HIGH" : "LOW");
|
||||||
|
}
|
||||||
|
void HostGPIOPin::detach_interrupt() const {}
|
||||||
|
|
||||||
|
} // namespace host
|
||||||
|
|
||||||
|
using namespace host;
|
||||||
|
|
||||||
|
bool IRAM_ATTR ISRInternalGPIOPin::digital_read() {
|
||||||
|
auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
|
||||||
|
return arg->inverted;
|
||||||
|
}
|
||||||
|
void IRAM_ATTR ISRInternalGPIOPin::digital_write(bool value) {
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
void IRAM_ATTR ISRInternalGPIOPin::clear_interrupt() {
|
||||||
|
auto *arg = reinterpret_cast<ISRPinArg *>(arg_);
|
||||||
|
ESP_LOGD(TAG, "Clearing interrupt for pin %d", arg->pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_HOST
|
37
esphome/components/host/gpio.h
Normal file
37
esphome/components/host/gpio.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef USE_HOST
|
||||||
|
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace host {
|
||||||
|
|
||||||
|
class HostGPIOPin : public InternalGPIOPin {
|
||||||
|
public:
|
||||||
|
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||||
|
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||||
|
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
||||||
|
|
||||||
|
void setup() override { pin_mode(flags_); }
|
||||||
|
void pin_mode(gpio::Flags flags) override;
|
||||||
|
bool digital_read() override;
|
||||||
|
void digital_write(bool value) override;
|
||||||
|
std::string dump_summary() const override;
|
||||||
|
void detach_interrupt() const override;
|
||||||
|
ISRInternalGPIOPin to_isr() const override;
|
||||||
|
uint8_t get_pin() const override { return pin_; }
|
||||||
|
bool is_inverted() const override { return inverted_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void attach_interrupt_(void (*func)(void *), void *arg, gpio::InterruptType type) const override;
|
||||||
|
|
||||||
|
uint8_t pin_;
|
||||||
|
bool inverted_;
|
||||||
|
gpio::Flags flags_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace host
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_HOST
|
73
esphome/components/host/gpio.py
Normal file
73
esphome/components/host/gpio.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from esphome.const import (
|
||||||
|
CONF_ID,
|
||||||
|
CONF_INPUT,
|
||||||
|
CONF_INVERTED,
|
||||||
|
CONF_MODE,
|
||||||
|
CONF_NUMBER,
|
||||||
|
CONF_OPEN_DRAIN,
|
||||||
|
CONF_OUTPUT,
|
||||||
|
CONF_PULLDOWN,
|
||||||
|
CONF_PULLUP,
|
||||||
|
)
|
||||||
|
from esphome import pins
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
import esphome.codegen as cg
|
||||||
|
|
||||||
|
from .const import host_ns
|
||||||
|
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
HostGPIOPin = host_ns.class_("HostGPIOPin", cg.InternalGPIOPin)
|
||||||
|
|
||||||
|
|
||||||
|
def _translate_pin(value):
|
||||||
|
if isinstance(value, dict) or value is None:
|
||||||
|
raise cv.Invalid(
|
||||||
|
"This variable only supports pin numbers, not full pin schemas "
|
||||||
|
"(with inverted and mode)."
|
||||||
|
)
|
||||||
|
if isinstance(value, int):
|
||||||
|
return value
|
||||||
|
try:
|
||||||
|
return int(value)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
if value.startswith("GPIO"):
|
||||||
|
return cv.int_(value[len("GPIO") :].strip())
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def validate_gpio_pin(value):
|
||||||
|
return _translate_pin(value)
|
||||||
|
|
||||||
|
|
||||||
|
HOST_PIN_SCHEMA = cv.All(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(HostGPIOPin),
|
||||||
|
cv.Required(CONF_NUMBER): validate_gpio_pin,
|
||||||
|
cv.Optional(CONF_MODE, default={}): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_INPUT, default=False): cv.boolean,
|
||||||
|
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
|
||||||
|
cv.Optional(CONF_OPEN_DRAIN, default=False): cv.boolean,
|
||||||
|
cv.Optional(CONF_PULLUP, default=False): cv.boolean,
|
||||||
|
cv.Optional(CONF_PULLDOWN, default=False): cv.boolean,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pins.PIN_SCHEMA_REGISTRY.register("host", HOST_PIN_SCHEMA)
|
||||||
|
async def host_pin_to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
num = config[CONF_NUMBER]
|
||||||
|
cg.add(var.set_pin(num))
|
||||||
|
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||||
|
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||||
|
return var
|
33
esphome/components/host/preferences.cpp
Normal file
33
esphome/components/host/preferences.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifdef USE_HOST
|
||||||
|
|
||||||
|
#include "preferences.h"
|
||||||
|
#include <cstring>
|
||||||
|
#include "esphome/core/preferences.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/core/defines.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace host {
|
||||||
|
|
||||||
|
static const char *const TAG = "host.preferences";
|
||||||
|
|
||||||
|
class HostPreferences : public ESPPreferences {
|
||||||
|
public:
|
||||||
|
ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash) override { return {}; }
|
||||||
|
|
||||||
|
ESPPreferenceObject make_preference(size_t length, uint32_t type) override { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
void setup_preferences() {
|
||||||
|
auto *pref = new HostPreferences(); // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
|
global_preferences = pref;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace host
|
||||||
|
|
||||||
|
ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
|
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_HOST
|
13
esphome/components/host/preferences.h
Normal file
13
esphome/components/host/preferences.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef USE_HOST
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace host {
|
||||||
|
|
||||||
|
void setup_preferences();
|
||||||
|
|
||||||
|
} // namespace host
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_HOST
|
@ -113,7 +113,9 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
cv.Optional(CONF_BAUD_RATE, default=115200): cv.positive_int,
|
cv.Optional(CONF_BAUD_RATE, default=115200): cv.positive_int,
|
||||||
cv.Optional(CONF_TX_BUFFER_SIZE, default=512): cv.validate_bytes,
|
cv.Optional(CONF_TX_BUFFER_SIZE, default=512): cv.validate_bytes,
|
||||||
cv.Optional(CONF_DEASSERT_RTS_DTR, default=False): cv.boolean,
|
cv.Optional(CONF_DEASSERT_RTS_DTR, default=False): cv.boolean,
|
||||||
cv.Optional(CONF_HARDWARE_UART, default="UART0"): uart_selection,
|
cv.SplitDefault(CONF_HARDWARE_UART, esp32="UART0", esp8266="UART0"): cv.All(
|
||||||
|
cv.only_on(["esp32", "esp8266"]), uart_selection
|
||||||
|
),
|
||||||
cv.Optional(CONF_LEVEL, default="DEBUG"): is_log_level,
|
cv.Optional(CONF_LEVEL, default="DEBUG"): is_log_level,
|
||||||
cv.Optional(CONF_LOGS, default={}): cv.Schema(
|
cv.Optional(CONF_LOGS, default={}): cv.Schema(
|
||||||
{
|
{
|
||||||
@ -138,12 +140,9 @@ CONFIG_SCHEMA = cv.All(
|
|||||||
@coroutine_with_priority(90.0)
|
@coroutine_with_priority(90.0)
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
baud_rate = config[CONF_BAUD_RATE]
|
baud_rate = config[CONF_BAUD_RATE]
|
||||||
rhs = Logger.new(
|
log = cg.new_Pvariable(config[CONF_ID], baud_rate, config[CONF_TX_BUFFER_SIZE])
|
||||||
baud_rate,
|
if CONF_HARDWARE_UART in config:
|
||||||
config[CONF_TX_BUFFER_SIZE],
|
cg.add(log.set_uart_selection(config[CONF_HARDWARE_UART]))
|
||||||
HARDWARE_UART_TO_UART_SELECTION[config[CONF_HARDWARE_UART]],
|
|
||||||
)
|
|
||||||
log = cg.Pvariable(config[CONF_ID], rhs)
|
|
||||||
cg.add(log.pre_setup())
|
cg.add(log.pre_setup())
|
||||||
|
|
||||||
for tag, level in config[CONF_LOGS].items():
|
for tag, level in config[CONF_LOGS].items():
|
||||||
|
@ -130,12 +130,14 @@ void HOT Logger::log_message_(int level, const char *tag, int offset) {
|
|||||||
if (xPortGetFreeHeapSize() < 2048)
|
if (xPortGetFreeHeapSize() < 2048)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_HOST
|
||||||
|
puts(msg);
|
||||||
|
#endif
|
||||||
|
|
||||||
this->log_callback_.call(level, tag, msg);
|
this->log_callback_.call(level, tag, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Logger(uint32_t baud_rate, size_t tx_buffer_size, UARTSelection uart)
|
Logger::Logger(uint32_t baud_rate, size_t tx_buffer_size) : baud_rate_(baud_rate), tx_buffer_size_(tx_buffer_size) {
|
||||||
: baud_rate_(baud_rate), tx_buffer_size_(tx_buffer_size), uart_(uart) {
|
|
||||||
// add 1 to buffer size for null terminator
|
// add 1 to buffer size for null terminator
|
||||||
this->tx_buffer_ = new char[this->tx_buffer_size_ + 1]; // NOLINT
|
this->tx_buffer_ = new char[this->tx_buffer_size_ + 1]; // NOLINT
|
||||||
}
|
}
|
||||||
@ -217,7 +219,11 @@ void Logger::set_baud_rate(uint32_t baud_rate) { this->baud_rate_ = baud_rate; }
|
|||||||
void Logger::set_log_level(const std::string &tag, int log_level) {
|
void Logger::set_log_level(const std::string &tag, int log_level) {
|
||||||
this->log_levels_.push_back(LogLevelOverride{tag, log_level});
|
this->log_levels_.push_back(LogLevelOverride{tag, log_level});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_ESP32) || defined(USE_ESP8266)
|
||||||
UARTSelection Logger::get_uart() const { return this->uart_; }
|
UARTSelection Logger::get_uart() const { return this->uart_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
void Logger::add_on_log_callback(std::function<void(int, const char *, const char *)> &&callback) {
|
void Logger::add_on_log_callback(std::function<void(int, const char *, const char *)> &&callback) {
|
||||||
this->log_callback_.add(std::move(callback));
|
this->log_callback_.add(std::move(callback));
|
||||||
}
|
}
|
||||||
@ -233,7 +239,10 @@ void Logger::dump_config() {
|
|||||||
ESP_LOGCONFIG(TAG, "Logger:");
|
ESP_LOGCONFIG(TAG, "Logger:");
|
||||||
ESP_LOGCONFIG(TAG, " Level: %s", LOG_LEVELS[ESPHOME_LOG_LEVEL]);
|
ESP_LOGCONFIG(TAG, " Level: %s", LOG_LEVELS[ESPHOME_LOG_LEVEL]);
|
||||||
ESP_LOGCONFIG(TAG, " Log Baud Rate: %u", this->baud_rate_);
|
ESP_LOGCONFIG(TAG, " Log Baud Rate: %u", this->baud_rate_);
|
||||||
|
#if defined(USE_ESP32) || defined(USE_ESP8266)
|
||||||
ESP_LOGCONFIG(TAG, " Hardware UART: %s", UART_SELECTIONS[this->uart_]);
|
ESP_LOGCONFIG(TAG, " Hardware UART: %s", UART_SELECTIONS[this->uart_]);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (auto &it : this->log_levels_) {
|
for (auto &it : this->log_levels_) {
|
||||||
ESP_LOGCONFIG(TAG, " Level for '%s': %s", it.tag.c_str(), LOG_LEVELS[it.level]);
|
ESP_LOGCONFIG(TAG, " Level for '%s': %s", it.tag.c_str(), LOG_LEVELS[it.level]);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ namespace esphome {
|
|||||||
|
|
||||||
namespace logger {
|
namespace logger {
|
||||||
|
|
||||||
|
#if defined(USE_ESP32) || defined(USE_ESP8266)
|
||||||
/** Enum for logging UART selection
|
/** Enum for logging UART selection
|
||||||
*
|
*
|
||||||
* Advanced configuration (pin selection, etc) is not supported.
|
* Advanced configuration (pin selection, etc) is not supported.
|
||||||
@ -31,10 +32,11 @@ enum UARTSelection {
|
|||||||
UART_SELECTION_UART0_SWAP,
|
UART_SELECTION_UART0_SWAP,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
#endif // USE_ESP32 || USE_ESP8266
|
||||||
|
|
||||||
class Logger : public Component {
|
class Logger : public Component {
|
||||||
public:
|
public:
|
||||||
explicit Logger(uint32_t baud_rate, size_t tx_buffer_size, UARTSelection uart);
|
explicit Logger(uint32_t baud_rate, size_t tx_buffer_size);
|
||||||
|
|
||||||
/// Manually set the baud rate for serial, set to 0 to disable.
|
/// Manually set the baud rate for serial, set to 0 to disable.
|
||||||
void set_baud_rate(uint32_t baud_rate);
|
void set_baud_rate(uint32_t baud_rate);
|
||||||
@ -46,8 +48,11 @@ class Logger : public Component {
|
|||||||
uart_port_t get_uart_num() const { return uart_num_; }
|
uart_port_t get_uart_num() const { return uart_num_; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_ESP32) || defined(USE_ESP8266)
|
||||||
|
void set_uart_selection(UARTSelection uart_selection) { uart_ = uart_selection; }
|
||||||
/// Get the UART used by the logger.
|
/// Get the UART used by the logger.
|
||||||
UARTSelection get_uart() const;
|
UARTSelection get_uart() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Set the log level of the specified tag.
|
/// Set the log level of the specified tag.
|
||||||
void set_log_level(const std::string &tag, int log_level);
|
void set_log_level(const std::string &tag, int log_level);
|
||||||
@ -117,7 +122,9 @@ class Logger : public Component {
|
|||||||
char *tx_buffer_{nullptr};
|
char *tx_buffer_{nullptr};
|
||||||
int tx_buffer_at_{0};
|
int tx_buffer_at_{0};
|
||||||
int tx_buffer_size_{0};
|
int tx_buffer_size_{0};
|
||||||
|
#if defined(USE_ESP32) || defined(USE_ESP8266)
|
||||||
UARTSelection uart_{UART_SELECTION_UART0};
|
UARTSelection uart_{UART_SELECTION_UART0};
|
||||||
|
#endif
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
HardwareSerial *hw_serial_{nullptr};
|
HardwareSerial *hw_serial_{nullptr};
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,6 +13,7 @@ CONFIG_SCHEMA = cv.Schema(
|
|||||||
CONF_IMPLEMENTATION,
|
CONF_IMPLEMENTATION,
|
||||||
esp8266=IMPLEMENTATION_LWIP_TCP,
|
esp8266=IMPLEMENTATION_LWIP_TCP,
|
||||||
esp32=IMPLEMENTATION_BSD_SOCKETS,
|
esp32=IMPLEMENTATION_BSD_SOCKETS,
|
||||||
|
host=IMPLEMENTATION_BSD_SOCKETS,
|
||||||
): cv.one_of(
|
): cv.one_of(
|
||||||
IMPLEMENTATION_LWIP_TCP, IMPLEMENTATION_BSD_SOCKETS, lower=True, space="_"
|
IMPLEMENTATION_LWIP_TCP, IMPLEMENTATION_BSD_SOCKETS, lower=True, space="_"
|
||||||
),
|
),
|
||||||
|
@ -119,6 +119,12 @@ struct iovec {
|
|||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef USE_HOST
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif // USE_HOST
|
||||||
|
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
// arduino-esp32 declares a global var called INADDR_NONE which is replaced
|
// arduino-esp32 declares a global var called INADDR_NONE which is replaced
|
||||||
// by the define
|
// by the define
|
||||||
|
@ -1426,6 +1426,7 @@ class SplitDefault(Optional):
|
|||||||
esp32=vol.UNDEFINED,
|
esp32=vol.UNDEFINED,
|
||||||
esp32_arduino=vol.UNDEFINED,
|
esp32_arduino=vol.UNDEFINED,
|
||||||
esp32_idf=vol.UNDEFINED,
|
esp32_idf=vol.UNDEFINED,
|
||||||
|
host=vol.UNDEFINED,
|
||||||
):
|
):
|
||||||
super().__init__(key)
|
super().__init__(key)
|
||||||
self._esp8266_default = vol.default_factory(esp8266)
|
self._esp8266_default = vol.default_factory(esp8266)
|
||||||
@ -1435,6 +1436,7 @@ class SplitDefault(Optional):
|
|||||||
self._esp32_idf_default = vol.default_factory(
|
self._esp32_idf_default = vol.default_factory(
|
||||||
esp32_idf if esp32 is vol.UNDEFINED else esp32
|
esp32_idf if esp32 is vol.UNDEFINED else esp32
|
||||||
)
|
)
|
||||||
|
self._host_default = vol.default_factory(host)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def default(self):
|
def default(self):
|
||||||
@ -1444,6 +1446,8 @@ class SplitDefault(Optional):
|
|||||||
return self._esp32_arduino_default
|
return self._esp32_arduino_default
|
||||||
if CORE.is_esp32 and CORE.using_esp_idf:
|
if CORE.is_esp32 and CORE.using_esp_idf:
|
||||||
return self._esp32_idf_default
|
return self._esp32_idf_default
|
||||||
|
if CORE.is_host:
|
||||||
|
return self._host_default
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@default.setter
|
@default.setter
|
||||||
|
@ -4,10 +4,13 @@ __version__ = "2022.3.0-dev"
|
|||||||
|
|
||||||
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||||
|
|
||||||
|
TARGET_FRAMEWORKS = ["arduino", "esp-idf"]
|
||||||
|
|
||||||
PLATFORM_ESP32 = "esp32"
|
PLATFORM_ESP32 = "esp32"
|
||||||
PLATFORM_ESP8266 = "esp8266"
|
PLATFORM_ESP8266 = "esp8266"
|
||||||
|
PLATFORM_HOST = "host"
|
||||||
|
|
||||||
TARGET_PLATFORMS = [PLATFORM_ESP32, PLATFORM_ESP8266]
|
TARGET_PLATFORMS = [PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_HOST]
|
||||||
|
|
||||||
SOURCE_FILE_EXTENSIONS = {".cpp", ".hpp", ".h", ".c", ".tcc", ".ino"}
|
SOURCE_FILE_EXTENSIONS = {".cpp", ".hpp", ".h", ".c", ".tcc", ".ino"}
|
||||||
HEADER_FILE_EXTENSIONS = {".h", ".hpp", ".tcc"}
|
HEADER_FILE_EXTENSIONS = {".h", ".hpp", ".tcc"}
|
||||||
|
@ -593,6 +593,10 @@ class EsphomeCore:
|
|||||||
def is_esp32(self):
|
def is_esp32(self):
|
||||||
return self.target_platform == "esp32"
|
return self.target_platform == "esp32"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_host(self):
|
||||||
|
return self.target_platform == "host"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def target_framework(self):
|
def target_framework(self):
|
||||||
return self.data[KEY_CORE][KEY_TARGET_FRAMEWORK]
|
return self.data[KEY_CORE][KEY_TARGET_FRAMEWORK]
|
||||||
|
@ -83,6 +83,10 @@
|
|||||||
#define USE_SOCKET_IMPL_LWIP_TCP
|
#define USE_SOCKET_IMPL_LWIP_TCP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_HOST
|
||||||
|
#define USE_SOCKET_IMPL_BSD_SOCKETS
|
||||||
|
#endif
|
||||||
|
|
||||||
// Disabled feature flags
|
// Disabled feature flags
|
||||||
//#define USE_BSEC // Requires a library with proprietary license.
|
//#define USE_BSEC // Requires a library with proprietary license.
|
||||||
|
|
||||||
|
@ -21,6 +21,10 @@
|
|||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include <freertos/FreeRTOS.h>
|
#include <freertos/FreeRTOS.h>
|
||||||
#include <freertos/portmacro.h>
|
#include <freertos/portmacro.h>
|
||||||
|
#elif defined(USE_HOST)
|
||||||
|
#include <cstdio>
|
||||||
|
#include <random>
|
||||||
|
#include <limits>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ESP32_IGNORE_EFUSE_MAC_CRC
|
#ifdef USE_ESP32_IGNORE_EFUSE_MAC_CRC
|
||||||
@ -76,6 +80,11 @@ uint32_t random_uint32() {
|
|||||||
return esp_random();
|
return esp_random();
|
||||||
#elif defined(USE_ESP8266)
|
#elif defined(USE_ESP8266)
|
||||||
return os_random();
|
return os_random();
|
||||||
|
#elif defined(USE_HOST)
|
||||||
|
std::random_device dev;
|
||||||
|
std::mt19937 rng(dev());
|
||||||
|
std::uniform_int_distribution<uint32_t> dist(0, std::numeric_limits<uint32_t>::max());
|
||||||
|
return dist(rng);
|
||||||
#else
|
#else
|
||||||
#error "No random source available for this configuration."
|
#error "No random source available for this configuration."
|
||||||
#endif
|
#endif
|
||||||
@ -87,6 +96,19 @@ bool random_bytes(uint8_t *data, size_t len) {
|
|||||||
return true;
|
return true;
|
||||||
#elif defined(USE_ESP8266)
|
#elif defined(USE_ESP8266)
|
||||||
return os_get_random(data, len) == 0;
|
return os_get_random(data, len) == 0;
|
||||||
|
#elif defined(USE_HOST)
|
||||||
|
FILE *fp = fopen("/dev/urandom", "r");
|
||||||
|
if (fp == nullptr) {
|
||||||
|
ESP_LOGW(TAG, "Could not open /dev/urandom, errno=%d", errno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
size_t read = fread(data, 1, len, fp);
|
||||||
|
if (read != len) {
|
||||||
|
ESP_LOGW(TAG, "Not enough data from /dev/urandom");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return true
|
||||||
#else
|
#else
|
||||||
#error "No random source available for this configuration."
|
#error "No random source available for this configuration."
|
||||||
#endif
|
#endif
|
||||||
|
@ -220,3 +220,13 @@ board_build.esp-idf.sdkconfig_path = .temp/sdkconfig-esp32s2-idf-tidy
|
|||||||
build_flags =
|
build_flags =
|
||||||
${common:esp32-idf.build_flags}
|
${common:esp32-idf.build_flags}
|
||||||
${flags:clangtidy.build_flags}
|
${flags:clangtidy.build_flags}
|
||||||
|
|
||||||
|
[env:host]
|
||||||
|
extends = common
|
||||||
|
platform = platformio/native
|
||||||
|
lib_deps =
|
||||||
|
esphome/noise-c@0.1.1 ; used by api
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
-DUSE_HOST
|
||||||
|
${flags:runtime.build_flags}
|
Loading…
x
Reference in New Issue
Block a user