mirror of
https://github.com/esphome/esphome.git
synced 2024-11-09 16:57:47 +01:00
Initial attempt at supporting ESP-IDF 5.0.0 (#4364)
* requirements: add pyparsing >= 3.0
ESP-IDF >= 5.0 requires pyparsing's rest_of_file, which was introduced
in version 3.0.
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
* esp32: fix build with ESP-IDF >= 5
We need to include esp_timer.h to be able to use esp_timer_get_time().
This header existed in ESP-IDF < 5 so we don't need if guards.
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
* ota: fix build with ESP-IDF >= 5
As of version 5, esp_task_wdt_init() takes a struct as argument. We also
need to include spi_flash_mmap.h.
[split unrelated change into separate commits, maintain ESP-IDF < 5
compat, use esp_task_wdt_reconfigure, add commit message]
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
* core: fix build with ESP-IDF >= 5
These header files already existed in ESP-IDF < 5 so skip if guards.
[add commit message]
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
* wifi: fix build with ESP-IDF >= 5
ESP-IDF 4.1 introduced the esp-netif API as successor to the tcp_adapter
API. The tcp_adapter API was removed in ESP-IDF 5.0.0. Part of the wifi
component was already migrated to the new API. Migrate the leftover uses
of the old API to the new API to fix build on ESP-IDF >= 5.
The version of ESP-IDF currently in use (4.4.4) supports the new API, so
we don't need any if guards to maintain backwards compatibility.
Also replace xQueueHandle, which is a pre FreeRTOS v8.0.0 data type,
with QueueHandle_t, so we don't need to enable backward compatibility
(CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY).
This reverts part of commit d42f35de5d
to wifi_component_esp_idf.cpp,
as the esp-netif API handles that internally.
[replace pre FreeRTOS v8.0.0 data type, add commit message]
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
* mdns: fix build with ESP-IDF >= 5
In ESP-IDF 5.0.0, the mdns component was removed and moved to another
repository. Since the mdns component in esphome is always built, we
need to add the mdns component from the esp-protocols repository. This
component depends on ESP-IDF >= 5.0, so we need to add a version guard.
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
* docker: install python3-venv
As of version 6.0.1, platform-espressif32 requires python3-venv.
Switching between esp-idf 4.4.4 and 5.0 causes problems with esp-idf
python dependencies installed by PlatformIO. They've solved this by
using venv. Install python3-venv so that platform-espressif32 6.0.1 and
later can be used, and we don't need to wipe the dependencies manually
when switching esp-idf versions.
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
---------
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
Co-authored-by: Stijn Tintel <stijn@linux-ipv6.be>
This commit is contained in:
parent
4c39631428
commit
c0ad5d1d16
7 changed files with 82 additions and 53 deletions
|
@ -24,6 +24,7 @@ RUN \
|
|||
python3-setuptools=52.0.0-4 \
|
||||
python3-pil=8.1.2+dfsg-0.3+deb11u1 \
|
||||
python3-cryptography=3.3.2-1 \
|
||||
python3-venv=3.9.2-3 \
|
||||
iputils-ping=3:20210202-1 \
|
||||
git=1:2.30.2-1 \
|
||||
curl=7.74.0-1.3+deb11u7 \
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <freertos/task.h>
|
||||
#include <esp_idf_version.h>
|
||||
#include <esp_task_wdt.h>
|
||||
#include <esp_timer.h>
|
||||
#include <soc/rtc.h>
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 4
|
||||
|
|
|
@ -4,10 +4,13 @@ from esphome.const import (
|
|||
CONF_PROTOCOL,
|
||||
CONF_SERVICES,
|
||||
CONF_SERVICE,
|
||||
KEY_CORE,
|
||||
KEY_FRAMEWORK_VERSION,
|
||||
)
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
from esphome.components.esp32 import add_idf_component
|
||||
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
DEPENDENCIES = ["network"]
|
||||
|
@ -79,6 +82,16 @@ async def to_code(config):
|
|||
elif CORE.is_rp2040:
|
||||
cg.add_library("LEAmDNS", None)
|
||||
|
||||
if CORE.using_esp_idf and CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] >= cv.Version(
|
||||
5, 0, 0
|
||||
):
|
||||
add_idf_component(
|
||||
"mdns",
|
||||
"https://github.com/espressif/esp-protocols.git",
|
||||
"mdns-v1.0.9",
|
||||
"components/mdns",
|
||||
)
|
||||
|
||||
if config[CONF_DISABLED]:
|
||||
return
|
||||
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#include <esp_ota_ops.h>
|
||||
#include "esphome/components/md5/md5.h"
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||
#include <spi_flash_mmap.h>
|
||||
#endif
|
||||
|
||||
namespace esphome {
|
||||
namespace ota {
|
||||
|
||||
|
@ -16,9 +20,28 @@ OTAResponseTypes IDFOTABackend::begin(size_t image_size) {
|
|||
if (this->partition_ == nullptr) {
|
||||
return OTA_RESPONSE_ERROR_NO_UPDATE_PARTITION;
|
||||
}
|
||||
esp_task_wdt_init(15, false); // The following function takes longer than the 5 seconds timeout of WDT
|
||||
|
||||
// The following function takes longer than the 5 seconds timeout of WDT
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||
esp_task_wdt_config_t wdtc;
|
||||
wdtc.timeout_ms = 15000;
|
||||
wdtc.idle_core_mask = 0;
|
||||
wdtc.trigger_panic = false;
|
||||
esp_task_wdt_reconfigure(&wdtc);
|
||||
#else
|
||||
esp_task_wdt_init(15, false);
|
||||
#endif
|
||||
|
||||
esp_err_t err = esp_ota_begin(this->partition_, image_size, &this->update_handle_);
|
||||
esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false); // Set the WDT back to the configured timeout
|
||||
|
||||
// Set the WDT back to the configured timeout
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||
wdtc.timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S;
|
||||
esp_task_wdt_reconfigure(&wdtc);
|
||||
#else
|
||||
esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false);
|
||||
#endif
|
||||
|
||||
if (err != ESP_OK) {
|
||||
esp_ota_abort(this->update_handle_);
|
||||
this->update_handle_ = 0;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#ifdef USE_WIFI_WPA2_EAP
|
||||
#include <esp_wpa2.h>
|
||||
#endif
|
||||
#include "dhcpserver/dhcpserver.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/dns.h"
|
||||
|
||||
|
@ -32,7 +33,7 @@ namespace wifi {
|
|||
static const char *const TAG = "wifi_esp32";
|
||||
|
||||
static EventGroupHandle_t s_wifi_event_group; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
static xQueueHandle s_event_queue; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
static QueueHandle_t s_event_queue; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
static esp_netif_t *s_sta_netif = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
static esp_netif_t *s_ap_netif = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
static bool s_sta_started = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
@ -414,17 +415,17 @@ bool WiFiComponent::wifi_sta_ip_config_(optional<ManualIP> manual_ip) {
|
|||
if (!this->wifi_mode_(true, {}))
|
||||
return false;
|
||||
|
||||
tcpip_adapter_dhcp_status_t dhcp_status;
|
||||
esp_err_t err = tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &dhcp_status);
|
||||
esp_netif_dhcp_status_t dhcp_status;
|
||||
esp_err_t err = esp_netif_dhcpc_get_status(s_sta_netif, &dhcp_status);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGV(TAG, "tcpip_adapter_dhcpc_get_status failed: %s", esp_err_to_name(err));
|
||||
ESP_LOGV(TAG, "esp_netif_dhcpc_get_status failed: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!manual_ip.has_value()) {
|
||||
// Use DHCP client
|
||||
if (dhcp_status != TCPIP_ADAPTER_DHCP_STARTED) {
|
||||
err = tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA);
|
||||
// No manual IP is set; use DHCP client
|
||||
if (dhcp_status != ESP_NETIF_DHCP_STARTED) {
|
||||
err = esp_netif_dhcpc_start(s_sta_netif);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGV(TAG, "Starting DHCP client failed! %d", err);
|
||||
}
|
||||
|
@ -433,43 +434,29 @@ bool WiFiComponent::wifi_sta_ip_config_(optional<ManualIP> manual_ip) {
|
|||
return true;
|
||||
}
|
||||
|
||||
tcpip_adapter_ip_info_t info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
esp_netif_ip_info_t info; // struct of ip4_addr_t with ip, netmask, gw
|
||||
info.ip.addr = static_cast<uint32_t>(manual_ip->static_ip);
|
||||
info.gw.addr = static_cast<uint32_t>(manual_ip->gateway);
|
||||
info.netmask.addr = static_cast<uint32_t>(manual_ip->subnet);
|
||||
|
||||
err = tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
|
||||
err = esp_netif_dhcpc_stop(s_sta_netif);
|
||||
if (err != ESP_OK && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED) {
|
||||
ESP_LOGV(TAG, "tcpip_adapter_dhcpc_stop failed: %s", esp_err_to_name(err));
|
||||
ESP_LOGV(TAG, "esp_netif_dhcpc_stop failed: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
err = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &info);
|
||||
err = esp_netif_set_ip_info(s_sta_netif, &info);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGV(TAG, "tcpip_adapter_set_ip_info failed: %s", esp_err_to_name(err));
|
||||
ESP_LOGV(TAG, "esp_netif_set_ip_info failed: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
ip_addr_t dns;
|
||||
#if LWIP_IPV6
|
||||
dns.type = IPADDR_TYPE_V4;
|
||||
#endif
|
||||
esp_netif_dns_info_t dns;
|
||||
if (uint32_t(manual_ip->dns1) != 0) {
|
||||
#if LWIP_IPV6
|
||||
dns.u_addr.ip4.addr = static_cast<uint32_t>(manual_ip->dns1);
|
||||
#else
|
||||
dns.addr = static_cast<uint32_t>(manual_ip->dns1);
|
||||
#endif
|
||||
dns_setserver(0, &dns);
|
||||
dns.ip.u_addr.ip4.addr = static_cast<uint32_t>(manual_ip->dns1);
|
||||
esp_netif_set_dns_info(s_sta_netif, ESP_NETIF_DNS_MAIN, &dns);
|
||||
}
|
||||
if (uint32_t(manual_ip->dns2) != 0) {
|
||||
#if LWIP_IPV6
|
||||
dns.u_addr.ip4.addr = static_cast<uint32_t>(manual_ip->dns2);
|
||||
#else
|
||||
dns.addr = static_cast<uint32_t>(manual_ip->dns2);
|
||||
#endif
|
||||
dns_setserver(1, &dns);
|
||||
dns.ip.u_addr.ip4.addr = static_cast<uint32_t>(manual_ip->dns2);
|
||||
esp_netif_set_dns_info(s_sta_netif, ESP_NETIF_DNS_BACKUP, &dns);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -478,10 +465,10 @@ bool WiFiComponent::wifi_sta_ip_config_(optional<ManualIP> manual_ip) {
|
|||
network::IPAddress WiFiComponent::wifi_sta_ip() {
|
||||
if (!this->has_sta())
|
||||
return {};
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
esp_err_t err = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip);
|
||||
esp_netif_ip_info_t ip;
|
||||
esp_err_t err = esp_netif_get_ip_info(s_sta_netif, &ip);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGV(TAG, "tcpip_adapter_get_ip_info failed: %s", esp_err_to_name(err));
|
||||
ESP_LOGV(TAG, "esp_netif_get_ip_info failed: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
return {ip.ip.addr};
|
||||
|
@ -601,9 +588,9 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
|||
if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_STA_START) {
|
||||
ESP_LOGV(TAG, "Event: WiFi STA start");
|
||||
// apply hostname
|
||||
err = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, App.get_name().c_str());
|
||||
err = esp_netif_set_hostname(s_sta_netif, App.get_name().c_str());
|
||||
if (err != ERR_OK) {
|
||||
ESP_LOGW(TAG, "tcpip_adapter_set_hostname failed: %s", esp_err_to_name(err));
|
||||
ESP_LOGW(TAG, "esp_netif_set_hostname failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
|
||||
s_sta_started = true;
|
||||
|
@ -651,7 +638,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
|||
} else if (data->event_base == IP_EVENT && data->event_id == IP_EVENT_STA_GOT_IP) {
|
||||
const auto &it = data->data.ip_got_ip;
|
||||
#if LWIP_IPV6_AUTOCONFIG
|
||||
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
|
||||
esp_netif_create_ip6_linklocal(s_sta_netif);
|
||||
#endif
|
||||
ESP_LOGV(TAG, "Event: Got IP static_ip=%s gateway=%s", format_ip4_addr(it.ip_info.ip).c_str(),
|
||||
format_ip4_addr(it.ip_info.gw).c_str());
|
||||
|
@ -770,8 +757,7 @@ bool WiFiComponent::wifi_ap_ip_config_(optional<ManualIP> manual_ip) {
|
|||
if (!this->wifi_mode_({}, true))
|
||||
return false;
|
||||
|
||||
tcpip_adapter_ip_info_t info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
esp_netif_ip_info_t info;
|
||||
if (manual_ip.has_value()) {
|
||||
info.ip.addr = static_cast<uint32_t>(manual_ip->static_ip);
|
||||
info.gw.addr = static_cast<uint32_t>(manual_ip->gateway);
|
||||
|
@ -781,17 +767,17 @@ bool WiFiComponent::wifi_ap_ip_config_(optional<ManualIP> manual_ip) {
|
|||
info.gw.addr = static_cast<uint32_t>(network::IPAddress(192, 168, 4, 1));
|
||||
info.netmask.addr = static_cast<uint32_t>(network::IPAddress(255, 255, 255, 0));
|
||||
}
|
||||
tcpip_adapter_dhcp_status_t dhcp_status;
|
||||
tcpip_adapter_dhcps_get_status(TCPIP_ADAPTER_IF_AP, &dhcp_status);
|
||||
err = tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP);
|
||||
esp_netif_dhcp_status_t dhcp_status;
|
||||
esp_netif_dhcps_get_status(s_sta_netif, &dhcp_status);
|
||||
err = esp_netif_dhcps_stop(s_sta_netif);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGV(TAG, "tcpip_adapter_dhcps_stop failed! %d", err);
|
||||
ESP_LOGV(TAG, "esp_netif_dhcps_stop failed! %d", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
err = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info);
|
||||
err = esp_netif_set_ip_info(s_sta_netif, &info);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGV(TAG, "tcpip_adapter_set_ip_info failed! %d", err);
|
||||
ESP_LOGV(TAG, "esp_netif_set_ip_info failed! %d", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -804,17 +790,17 @@ bool WiFiComponent::wifi_ap_ip_config_(optional<ManualIP> manual_ip) {
|
|||
start_address[3] += 100;
|
||||
lease.end_ip.addr = static_cast<uint32_t>(start_address);
|
||||
ESP_LOGV(TAG, "DHCP server IP lease end: %s", start_address.str().c_str());
|
||||
err = tcpip_adapter_dhcps_option(TCPIP_ADAPTER_OP_SET, TCPIP_ADAPTER_REQUESTED_IP_ADDRESS, &lease, sizeof(lease));
|
||||
err = esp_netif_dhcps_option(s_sta_netif, ESP_NETIF_OP_SET, ESP_NETIF_REQUESTED_IP_ADDRESS, &lease, sizeof(lease));
|
||||
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGV(TAG, "tcpip_adapter_dhcps_option failed! %d", err);
|
||||
ESP_LOGV(TAG, "esp_netif_dhcps_option failed! %d", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
err = tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP);
|
||||
err = esp_netif_dhcps_start(s_sta_netif);
|
||||
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGV(TAG, "tcpip_adapter_dhcps_start failed! %d", err);
|
||||
ESP_LOGV(TAG, "esp_netif_dhcps_start failed! %d", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -860,8 +846,8 @@ bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
|
|||
return true;
|
||||
}
|
||||
network::IPAddress WiFiComponent::wifi_soft_ap_ip() {
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip);
|
||||
esp_netif_ip_info_t ip;
|
||||
esp_netif_get_ip_info(s_sta_netif, &ip);
|
||||
return {ip.ip.addr};
|
||||
}
|
||||
bool WiFiComponent::wifi_disconnect_() { return esp_wifi_disconnect(); }
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#elif defined(USE_ESP32_FRAMEWORK_ARDUINO)
|
||||
#include <Esp.h>
|
||||
#elif defined(USE_ESP_IDF)
|
||||
#include "esp_mac.h"
|
||||
#include "esp_random.h"
|
||||
#include "esp_system.h"
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/portmacro.h>
|
||||
|
|
|
@ -16,3 +16,6 @@ zeroconf==0.56.0
|
|||
# esp-idf requires this, but doesn't bundle it by default
|
||||
# https://github.com/espressif/esp-idf/blob/220590d599e134d7a5e7f1e683cc4550349ffbf8/requirements.txt#L24
|
||||
kconfiglib==13.7.1
|
||||
|
||||
# esp-idf >= 5.0 requires this
|
||||
pyparsing >= 3.0
|
||||
|
|
Loading…
Reference in a new issue