lwip/linux: Add lwip support for networking component under linux

linux/lwip: Wrap some IO posix functions
* to workaourd the FreeRTOS EINTR issue (when building without lwip)
* to correctly choose the sub-system based on fd (when building with
lwip) -- passing control to either linux/system or to lwip
This commit also addapts tapio-if to provide DHCP client by default and
configurable settings for static IP
This commit is contained in:
David Cermak 2023-04-03 20:31:51 +02:00 committed by David Čermák
parent 0bfffa0160
commit b2af4d9689
31 changed files with 277 additions and 88 deletions

View File

@ -282,8 +282,8 @@ test_sockets_on_host:
- grep "Socket unable to connect" test.log
# test the udp-client example with lwip sockets
- cd ${IDF_PATH}/examples/protocols/sockets/udp_client
- echo 'CONFIG_EXAMPLE_IPV4_ADDR="127.0.0.1"' >> sdkconfig.defaults
- idf.py --preview set-target linux
- cat sdkconfig.ci.linux > sdkconfig
- idf.py build
- timeout 5 ./build/udp_client.elf >test.log || true
- grep "Message sent" test.log

View File

@ -32,8 +32,15 @@ if(NOT ${IDF_TARGET} STREQUAL "linux")
# due to cyclic dependencies present in IDF for lwip/esp_netif/mbedtls
idf_component_get_property(lwip lwip COMPONENT_LIB)
set_property(TARGET ${lwip} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 5)
else()
# Check if LWIP in the build for linux target to adapt esp-tls compatibility layer
idf_build_get_property(build_components BUILD_COMPONENTS)
if("lwip" IN_LIST build_components)
target_compile_definitions(${COMPONENT_LIB} PRIVATE ESP_TLS_WITH_LWIP=1)
endif()
endif()
if(CONFIG_ESP_TLS_USE_SECURE_ELEMENT)
idf_component_optional_requires(PRIVATE espressif__esp-cryptoauthlib esp-cryptoauthlib)
endif()

View File

@ -17,9 +17,10 @@
#include "esp_tls.h"
#include "esp_tls_private.h"
#include "esp_tls_error_capture_internal.h"
#include <fcntl.h>
#include <errno.h>
#if CONFIG_IDF_TARGET_LINUX
#if CONFIG_IDF_TARGET_LINUX && !ESP_TLS_WITH_LWIP
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
@ -36,7 +37,7 @@ static inline char *ip6addr_ntoa(const ip6_addr_t *addr)
return (char *)inet_ntop(AF_INET6, addr->s6_addr, str, 40);
}
#endif
#endif // CONFIG_IDF_TARGET_LINUX && !ESP_TLS_WITH_LWIP
static const char *TAG = "esp-tls";

View File

@ -1,7 +1,7 @@
if(NOT ${IDF_TARGET} STREQUAL "linux")
set(req lwip esp_event)
else()
set(req linux)
set(req linux esp_event)
endif()
idf_component_register(SRCS "esp_http_client.c"

View File

@ -1,14 +1,12 @@
set(priv_req mbedtls)
set(priv_inc_dir "src/util")
set(requires http_parser)
set(requires http_parser esp_event)
if(NOT ${IDF_TARGET} STREQUAL "linux")
list(APPEND priv_req lwip esp_timer)
list(APPEND priv_inc_dir "src/port/esp32")
list(APPEND requires esp_event)
else()
list(APPEND priv_inc_dir "src/port/linux")
list(APPEND priv_req pthread)
list(APPEND requires linux)
endif()
idf_component_register(SRCS "src/httpd_main.c"

View File

@ -6,6 +6,7 @@
#include <string.h>
#include "esp_chip_info.h"
#include "esp_mac.h"
void esp_chip_info(esp_chip_info_t *out_info)
{
@ -18,3 +19,15 @@ void esp_chip_info(esp_chip_info_t *out_info)
out_info->revision = 0;
out_info->cores = 1;
}
esp_err_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
{
// Provide Locally Administered (OUI range) MAC address on POSIX/Linux
mac[0] = 0x02;
mac[1] = 0x12;
mac[2] = 0x34;
mac[3] = 0x56;
mac[4] = 0x78;
mac[5] = 0xab;
return ESP_OK;
}

View File

@ -60,6 +60,18 @@ if(${target} STREQUAL "linux")
if(NOT CONFIG_FREERTOS_SMP)
list(APPEND srcs "${kernel_dir}/portable/${arch}/port_idf.c")
endif()
# Check if we need to address the FreeRTOS EINTR coexistence with linux system calls
# if we're building without lwIP, we need to use linux system select which will receive
# EINTR event on every FreeRTOS interrupt, we workaround this problem by wrapping select()
# to bypass and silence the EINTR events
set(BYPASS_EINTR_ISSUE 0)
idf_build_get_property(build_components BUILD_COMPONENTS)
if(NOT "lwip" IN_LIST build_components)
set(BYPASS_EINTR_ISSUE 1)
list(APPEND srcs esp_additions/arch/linux/FreeRTOSSimulator_wrappers.c)
endif()
else()
list(APPEND srcs
"app_startup.c"
@ -99,6 +111,9 @@ idf_component_register(SRCS "${srcs}"
if(${target} STREQUAL "linux")
target_compile_definitions(${COMPONENT_LIB} PUBLIC "projCOVERAGE_TEST=0")
target_link_libraries(${COMPONENT_LIB} PUBLIC pthread)
if(BYPASS_EINTR_ISSUE)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=select")
endif()
else()
idf_component_get_property(COMPONENT_DIR freertos COMPONENT_DIR)

View File

@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <pthread.h>
#include "esp_err.h"
#include "errno.h"
/** This module addresses the FreeRTOS simulator's coexistence with linux system calls from user apps.
* It's only included when building without lwIP, so we need to use linux system's select() which would receive
* EINTR event on every FreeRTOS interrupt; we workaround this problem by wrapping select()
* to bypass and silence these events.
*/
extern int __real_select (int fd, fd_set * rfds, fd_set * wfds, fd_set *efds, struct timeval *tval);
static inline int64_t get_us(void)
{
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
return spec.tv_nsec / 1000 + spec.tv_sec * 1000000;
}
int __wrap_select (int fd, fd_set * rfds, fd_set * wfds, fd_set *efds, struct timeval *tval)
{
int ret;
struct timeval *tv = tval;
int64_t start = 0;
int64_t timeout_us = 0;
if (tv != NULL) {
start = get_us();
timeout_us = tval->tv_sec * 1000000 + tval->tv_usec;
struct timeval timeval_local = { .tv_sec = tval->tv_sec, .tv_usec = tval->tv_usec };
tv = &timeval_local; // this (tv != NULL) indicates that we should handle timeouts
}
while ((ret = __real_select(fd, rfds, wfds, efds, tv)) < 0 && errno == EINTR) {
if (tv != NULL) {
int64_t now = get_us();
timeout_us -= now - start;
if (timeout_us < 0) {
errno = 0;
ret = 0;
break;
}
start = now;
tv->tv_usec = timeout_us % 1000000;
tv->tv_sec = timeout_us / 1000000;
}
}
return ret;
}

View File

@ -3,6 +3,5 @@ if(NOT "${target}" STREQUAL "linux")
return()
endif()
idf_component_register(SRCS esp_event_stubs.c
INCLUDE_DIRS include ${IDF_PATH}/components/esp_event/include
idf_component_register(INCLUDE_DIRS include
REQUIRED_IDF_TARGETS linux)

View File

@ -1,18 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_err.h"
#include "esp_event.h"
esp_err_t esp_event_loop_create_default(void)
{
return ESP_OK;
}
esp_err_t esp_event_post(esp_event_base_t event_base, int32_t event_id,
const void* event_data, size_t event_data_size, TickType_t ticks_to_wait)
{
return ESP_OK;
}

View File

@ -9,7 +9,7 @@
extern "C" {
#endif
#if CONFIG_IDF_TARGET_LINUX
#if CONFIG_IDF_TARGET_LINUX && !defined(__containerof)
#define __containerof(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

View File

@ -13,6 +13,7 @@ set(include_dirs
port/freertos/include/
port/${target}/include
port/${target}/include/arch
port/${target}/include/sys
)
set(srcs
@ -142,6 +143,9 @@ if(NOT ${target} STREQUAL "linux")
else()
list(APPEND srcs "port/${target}/no_vfs_syscalls.c")
endif()
else()
# This wraps some posix IO functions to conditionally pass control to lwip
list(APPEND srcs "port/${target}/vfs_lwip.c")
endif()
if(CONFIG_LWIP_ICMP)
@ -206,4 +210,13 @@ if(${target} STREQUAL "linux")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${COMPONENT_LIB} PRIVATE Threads::Threads)
set(WRAP_FUNCTIONS select
read
fcntl
write
close)
foreach(wrap ${WRAP_FUNCTIONS})
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=${wrap}")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __wrap_${wrap}")
endforeach()
endif()

View File

@ -4,9 +4,13 @@
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef LWIP_HDR_ESP_LWIPOPTS_H
// ignore when included from lwipopts.h since lwip provides all necessary definitions
#else
// otherwise include system fcntl
#include_next <sys/fcntl.h>
#include "sdkconfig.h"
#ifdef LWIP_HDR_LINUX_SYS_SOCKETS_H
// only if we prefer linux system sockets, include from system paths
#include_next <fcntl.h>
#elif CONFIG_IDF_TARGET_LINUX
// need to declare, as on linux we bypass IDF vfs and wrap posix io functions
extern int fcntl(int s, int cmd, ...);
#endif
// ignore otherwise (typically included from lwipopts.h) since lwip provides all necessary definitions

View File

@ -3,11 +3,11 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef LWIP_HDR_LINUX_SYS_SOCKETS_H
#define LWIP_HDR_LINUX_SYS_SOCKETS_H
#pragma once
#ifdef LWIP_HDR_LINUX_SYS_SOCKETS_H
/* only if we prefer linux system sockets, include from system paths */
#include_next <sys/socket.h>
#else
/* Include lwip sockets by default */
#include "lwip/sockets.h"
#else
/* Otherwise use system sockets if LWIP_HDR_LINUX_SYS_SOCKETS_H already defined */
#include_next <sys/socket.h>
#endif /* LWIP_HDR_LINUX_SYS_SOCKETS_H */

View File

@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/socket.h>
#include <stdarg.h>
extern int __real_fcntl(int s, int cmd, ...);
extern int __real_close(int s);
extern ssize_t __real_write (int fd, const void *buf, size_t n);
extern ssize_t __real_read (int fd, void *buf, size_t n);
extern int __real_select (int fd, fd_set * rfds, fd_set * wfds, fd_set *efds, struct timeval *tval);
ssize_t __wrap_write (int fd, const void *buf, size_t n)
{
#ifdef CONFIG_LWIP_MAX_SOCKETS
if (fd >= LWIP_SOCKET_OFFSET)
return lwip_write(fd, buf, n);
#endif
return __real_write(fd, buf, n);
}
ssize_t __wrap_read (int fd, void *buf, size_t n)
{
#ifdef CONFIG_LWIP_MAX_SOCKETS
if (fd >= LWIP_SOCKET_OFFSET)
return lwip_read(fd, buf, n);
#endif
return __real_read(fd, buf, n);
}
int __wrap_select (int fd, fd_set * rds, fd_set * wfds, fd_set *efds, struct timeval *tval)
{
#ifdef CONFIG_LWIP_MAX_SOCKETS
if (fd >= LWIP_SOCKET_OFFSET)
return lwip_select(fd, rds, wfds, efds, tval);
#endif
return __real_select(fd, rds, wfds, efds, tval);
}
int __wrap_fcntl(int fd, int cmd, ...)
{
va_list args;
#ifdef CONFIG_LWIP_MAX_SOCKETS
if (fd >= LWIP_SOCKET_OFFSET) {
va_start(args, cmd);
int arg = va_arg(args, int);
va_end(args);
return lwip_fcntl(fd, cmd, arg);
}
#endif
return __real_fcntl(fd, cmd, args);
}
int __wrap_close(int fd)
{
#ifdef CONFIG_LWIP_MAX_SOCKETS
if (fd >= LWIP_SOCKET_OFFSET)
return lwip_close(fd);
#endif
return __real_close(fd);
}

View File

@ -22,3 +22,13 @@ idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
REQUIRES ${req})
if(${IDF_TARGET} STREQUAL "linux")
# Check if LWIP in the build for linux target to add esp_timer to the dependencies
# since socks_proxy transport needs it and lwip & linux build could use it
idf_build_get_property(build_components BUILD_COMPONENTS)
if("lwip" IN_LIST build_components)
idf_component_get_property(esp_timer esp_timer COMPONENT_LIB)
target_link_libraries(${COMPONENT_LIB} PUBLIC ${esp_timer})
endif()
endif()

View File

@ -3,7 +3,7 @@ menu "Example Connection Configuration"
config EXAMPLE_CONNECT_LWIP_TAPIF
bool "connect using lwip to linux tap interface"
depends on IDF_TARGET_LINUX && ESP_NETIF_TCPIP_LWIP
default n
default y
if EXAMPLE_CONNECT_LWIP_TAPIF
config EXAMPLE_CONNECT_IPV4
@ -18,24 +18,28 @@ menu "Example Connection Configuration"
help
Set to true to setup link local address and wait until it's valid
config EXAMPLE_CONNECT_WAIT_FOR_IP
bool "run DHCP and wait for IP"
default y
config EXAMPLE_CONNECT_TAPIF_IP_ADDR
string "Static IP address"
default "192.168.5.100"
depends on EXAMPLE_CONNECT_IPV4
depends on EXAMPLE_CONNECT_IPV4 && !EXAMPLE_CONNECT_WAIT_FOR_IP
help
Set static IP address.
config EXAMPLE_CONNECT_TAPIF_NETMASK
string "Static netmask address"
default "255.255.255.0"
depends on EXAMPLE_CONNECT_IPV4
depends on EXAMPLE_CONNECT_IPV4 && !EXAMPLE_CONNECT_WAIT_FOR_IP
help
Set static netmask address.
config EXAMPLE_CONNECT_TAPIF_GW
string "Static gateway address"
default "192.168.5.1"
depends on EXAMPLE_CONNECT_IPV4
depends on EXAMPLE_CONNECT_IPV4 && !EXAMPLE_CONNECT_WAIT_FOR_IP
help
Set static gateway address.

View File

@ -110,6 +110,8 @@ sudo iptables -A FORWARD -i tap0 -o eth0 -j ACCEPT
It's also possible to configure the lwip interface to use DHCP client (common setup for most default network interfaces, such as Ethernet or WiFi station)
and set up a DHCP server on the host machine to assign the IP address dynamically.
This component sets up a DHCP client if `CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP` is enabled and waits for assigning an IP address. See below the description of DHCP client workflow for tap interface:
1) **Configure and set the `esp-netif` up**
* Same as in [API usage](#Usage-of-the-API), but update the base esp-netif config `3c)` to enable DHCP client
@ -125,14 +127,17 @@ and set up a DHCP server on the host machine to assign the IP address dynamicall
esp_netif_action_connected(tap_netif, 0, 0, 0);
```
* Wait for the IP address to be assigned.
This could be implemented as a wait loop below, as the esp-event currently doesn't support IP events on Linux target.
This could be implemented using an event handler
```cpp
esp_netif_inherent_config_t base_cfg = {
...
.get_ip_event = TAP0_GOT_IP,
...
};
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, TAP0_GOT_IP, event_handler, NULL));
// wait for the IP event (e.g. using signalling semaphores from the handler)
// ...
esp_netif_ip_info_t ip_info = {};
while (ip_info.ip.addr == 0) {
ESP_LOGI("tap-init", "No IP assigned, waiting...");
usleep(1000000);
esp_netif_get_ip_info(tap_netif, &ip_info);
}
ESP_LOGI("tap-init", "Assigned IP address:"IPSTR ",", IP2STR(&ip_info.ip));
```

View File

@ -4,26 +4,25 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include "esp_err.h"
#include "esp_log.h"
#include <stdlib.h>
#include "esp_netif.h"
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_netif.h"
// Use linux system sockets to connect to tap interface
#define LWIP_HDR_LINUX_SYS_SOCKETS_H
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <lwip/sys.h>
#include "errno.h"
#define LWIP_HDR_LINUX_SYS_SOCKETS_H
#include <linux/if.h>
#include <linux/if_tun.h>
#include <esp_netif_net_stack.h>
#define DEVTAP "/dev/net/tun"
#define DEVTAP_NAME "tap0"

View File

@ -7,6 +7,26 @@
#include "esp_netif.h" // esp-netif
#include "tapio.h" // esp-netif's driver side
#include "lwip/tapif.h" // esp-netif's network stack side
#include "esp_log.h"
#if CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
#include "esp_event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
static const char *TAG = "linux_connect";
static EventGroupHandle_t s_events;
static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
xEventGroupSetBits(s_events, 1);
}
#endif // CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
#define TAP0_GOT_IP (0x1234)
esp_err_t example_connect(void)
{
@ -25,14 +45,20 @@ esp_err_t example_connect(void)
};
// configure inherent esp-netif parameters
esp_netif_ip_info_t ip_info = {};
esp_netif_flags_t netif_flags = (ESP_NETIF_FLAG_EVENT_IP_MODIFIED | ESP_NETIF_FLAG_AUTOUP);
#if !CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
ip_info.ip.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_IP_ADDR);
ip_info.netmask.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_NETMASK);
ip_info.gw.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_GW);
#else
netif_flags |= ESP_NETIF_DHCP_CLIENT;
#endif
esp_netif_inherent_config_t base_cfg = {
.if_key = "TAP",
.flags = ESP_NETIF_FLAG_AUTOUP,
.ip_info = &ip_info,
.flags = netif_flags,
.get_ip_event = TAP0_GOT_IP,
.route_prio = 100
};
@ -46,6 +72,15 @@ esp_err_t example_connect(void)
// create the interface and attach it to the tapio-handle
esp_netif_t *tap_netif = esp_netif_new(&cfg);
esp_netif_attach(tap_netif, driver_cfg.handle);
#if CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
ESP_LOGI(TAG, "Waiting for IP addresses...");
esp_netif_action_connected(tap_netif, 0, 0, 0);
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, TAP0_GOT_IP, event_handler, NULL));
s_events = xEventGroupCreate();
xEventGroupWaitBits(s_events, 1, pdFALSE, pdFALSE, portMAX_DELAY);
esp_netif_get_ip_info(tap_netif, &ip_info);
ESP_LOGI(TAG, "Assigned IP address:"IPSTR ",", IP2STR(&ip_info.ip));
#endif // CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
#endif // EXAMPLE_CONNECT_LWIP_TAPIF
return ESP_OK;
}

View File

@ -5,8 +5,7 @@ cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
if(${IDF_TARGET} STREQUAL "linux")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/"
"$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs)
set(COMPONENTS main)
endif()

View File

@ -3,7 +3,7 @@
# (If this was a component, we would set COMPONENT_EMBED_TXTFILES here.)
set(requires "")
if(${IDF_TARGET} STREQUAL "linux")
list(APPEND requires esp_stubs esp-tls esp_http_client protocol_examples_common nvs_flash)
list(APPEND requires esp_stubs esp_event esp-tls esp_http_client protocol_examples_common nvs_flash)
endif()
idf_component_register(SRCS "esp_http_client_example.c"
INCLUDE_DIRS "."

View File

@ -22,11 +22,9 @@
#include "esp_crt_bundle.h"
#endif
#if !CONFIG_IDF_TARGET_LINUX
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#endif
#include "esp_http_client.h"

View File

@ -5,8 +5,7 @@ cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
if(${IDF_TARGET} STREQUAL "linux")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/"
"$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
set(COMPONENTS main)
endif()

View File

@ -6,9 +6,6 @@
#include <stdlib.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_event.h"
extern void app_main(void);
esp_err_t esp_netif_init(void)
{
@ -19,10 +16,3 @@ esp_err_t example_connect(void)
{
return ESP_OK;
}
int main(void)
{
app_main();
return 0;
}

View File

@ -1,8 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "esp_err.h"
esp_err_t esp_event_loop_create_default(void);

View File

@ -8,4 +8,12 @@
#include <ifaddrs.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
esp_err_t esp_netif_init(void);
#ifdef __cplusplus
}
#endif

View File

@ -4,8 +4,7 @@ cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
if("${IDF_TARGET}" STREQUAL "linux")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/"
"$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs")
set(COMPONENTS main)
endif()

View File

@ -1,5 +1,5 @@
if(${IDF_TARGET} STREQUAL "linux")
set(requires esp_stubs protocol_examples_common nvs_flash)
set(requires esp_event esp_stubs protocol_examples_common nvs_flash)
endif()
if("${CONFIG_EXAMPLE_IPV4}" STREQUAL y)

View File

@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.16)
if("${IDF_TARGET}" STREQUAL "linux")
# This example uses an extra component with common functionality for lwip's port on linux target
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_tapif_io)
set(COMPONENTS main esp_netif protocol_examples_tapif_io startup esp_hw_support esp_system nvs_flash)
set(COMPONENTS main esp_netif lwip protocol_examples_tapif_io startup esp_hw_support esp_system nvs_flash)
else()
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection on ESP target
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)

View File

@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="linux"
CONFIG_EXAMPLE_IPV4_ADDR="127.0.0.1"
CONFIG_EXAMPLE_CONNECT_LWIP_TAPIF=n