Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,9 @@ fabric.properties
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
.idea/caches/build_file_checksums.ser
managed_components/

*.lock

.cache/
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.2)
cmake_minimum_required(VERSION 3.22)

set(SUPPORTED_TARGETS esp32)

Expand Down
2 changes: 1 addition & 1 deletion components/ethernet_helper/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
idf_component_register(SRCS "connect.c"
INCLUDE_DIRS "include"
REQUIRES lwip mdns
REQUIRES lwip mdns esp_wifi esp_eth
)
2 changes: 1 addition & 1 deletion components/ethernet_helper/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ static void start(void)
};
ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());

#ifdef CONFIG_ETHERNET_HELPER_CUSTOM_HOSTNAME
Expand Down
31 changes: 24 additions & 7 deletions components/open62541/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,60 @@ endif()
idf_component_register(
SRCS custom_getaddrinfo.c
REQUIRES lwip vfs freertos ${ADDITIONAL_REQUIRES}
PRIV_INCLUDE_DIRS ${IDF_PATH}/components/freertos/include/freertos
)

set_property(SOURCE ${CMAKE_BINARY_DIR}/open62541/open62541.c PROPERTY GENERATED 1)
set_source_files_properties(${CMAKE_BINARY_DIR}/open62541/open62541.c
PROPERTIES COMPILE_FLAGS "-w")
target_sources(${COMPONENT_LIB} PRIVATE ${CMAKE_BINARY_DIR}/open62541/open62541.c)
target_include_directories(${COMPONENT_LIB} PUBLIC ${CMAKE_BINARY_DIR}/open62541)
target_include_directories(${COMPONENT_LIB} BEFORE PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/compat_includes
${CMAKE_BINARY_DIR}/open62541)

set(open62541_OPTIONS
"-DUA_ARCHITECTURE=freertosLWIP"
"-DUA_ARCHITECTURE=freertos-lwip"
"-DFREERTOS_KERNEL_PATH=${CMAKE_CURRENT_SOURCE_DIR}/freertos_stub"
"-DFREERTOS_PORT_PATH=${CMAKE_CURRENT_SOURCE_DIR}/freertos_stub"
"-DUA_ENABLE_AMALGAMATION=ON"
"-DUA_NAMESPACE_ZERO=FULL"
"-DUA_ENABLE_SUBSCRIPTIONS_EVENTS=ON"
"-DUA_ENABLE_DISCOVERY=ON"
"-DUA_ENABLE_DISCOVERY_MULTICAST=ON"
"-DUA_ENABLE_TYPEDESCRIPTION=OFF"
"-DUA_ENABLE_TYPEDESCRIPTION=ON"
"-DUA_ENABLE_STATUSCODE_DESCRIPTIONS=ON"
"-DUA_LOGLEVEL=300"
"-DUA_ENABLE_NODESET_COMPILER_DESCRIPTIONS=OFF"
"-DUA_FILE_NS0_BLACKLIST=${CMAKE_CURRENT_SOURCE_DIR}/../../nodes_blacklist.txt"
"-DUA_NS0_BLACKLIST=${CMAKE_CURRENT_SOURCE_DIR}/../../nodes_blacklist.txt"
"-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}"
"-DLWIP_LIBRARIES=${CMAKE_BINARY_DIR}/esp-idf/lwip/liblwip.a"
"-DCMAKE_PROJECT_INCLUDE_BEFORE=${CMAKE_CURRENT_SOURCE_DIR}/no_install.cmake"
)


if (USE_ENCRYPTION)
set(open62541_OPTIONS ${open62541_OPTIONS} "-DUA_ENABLE_ENCRYPTION=ON")
endif()

set(open62541_CONFIG_H "${CMAKE_BINARY_DIR}/open62541/src_generated/open62541/config.h")

externalproject_add(open62541_build
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/repo
#GIT_REPOSITORY https://github.com/open62541/open62541.git
# Latest tested commit on master branch. Newer may work. You can also use 'master' directly as GIT_TAG value
#GIT_TAG 76a6cab604fb5309c91a8849183417da1383d3d9
BINARY_DIR "${CMAKE_BINARY_DIR}/open62541"
LIST_SEPARATOR "|"
CMAKE_ARGS ${open62541_OPTIONS}
BUILD_COMMAND cmake --build . --target open62541-code-generation
"-DLWIP_INCLUDE_DIRS=${IDF_PATH}/components/lwip/lwip/src/include|${IDF_PATH}/components/lwip/port/include|${IDF_PATH}/components/lwip/include"
PATCH_COMMAND ${CMAKE_COMMAND} -E echo "Patching config.h for ESP32 target"
BUILD_COMMAND
${CMAKE_COMMAND} -DCONFIG_H=${open62541_CONFIG_H} -P
${CMAKE_CURRENT_SOURCE_DIR}/patch_config.cmake
&& cmake --build . --target open62541-amalgamation
INSTALL_COMMAND ""
)

add_dependencies(${COMPONENT_TARGET} open62541_build)
target_compile_options(${COMPONENT_LIB} PUBLIC -DUA_getaddrinfo=custom_getaddrinfo -DUA_ENABLE_AMALGAMATION -DUA_ARCHITECTURE_FREERTOSLWIP -DUA_ARCHITECTURE_FREERTOSLWIP_POSIX_CLOCK)
# Note: UA_getaddrinfo is internally mapped to lwip_getaddrinfo in open62541 v1.5.4.
# The custom_getaddrinfo workaround for ESP32 hostname resolution would need
# a linker-level override (--wrap=lwip_getaddrinfo) if still required.
1 change: 1 addition & 0 deletions components/open62541/compat_includes/FreeRTOS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <freertos/FreeRTOS.h>
1 change: 1 addition & 0 deletions components/open62541/compat_includes/task.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <freertos/task.h>
12 changes: 12 additions & 0 deletions components/open62541/custom_getaddrinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

#include <lwip/netdb.h>
#include <esp_log.h>
#include <string.h>
#include "sdkconfig.h"

int gethostname(char *name, size_t len) {
#ifdef CONFIG_ETHERNET_HELPER_CUSTOM_HOSTNAME
strncpy(name, CONFIG_ETHERNET_HELPER_CUSTOM_HOSTNAME_STR, len - 1);
#else
strncpy(name, CONFIG_LWIP_LOCAL_HOSTNAME, len - 1);
#endif
name[len - 1] = '\0';
return 0;
}

int
custom_getaddrinfo(const char *nodename, const char *servname,
Expand Down
4 changes: 4 additions & 0 deletions components/open62541/freertos_stub/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Stub for FreeRTOS kernel used during open62541 amalgamation generation.
# The real FreeRTOS is provided by ESP-IDF when cross-compiling for ESP32.
cmake_minimum_required(VERSION 3.16)
add_library(freertos_kernel INTERFACE)
6 changes: 6 additions & 0 deletions components/open62541/no_install.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Override install() and export() for the open62541 ExternalProject build.
# We only need the amalgamation, not a proper CMake install.
macro(install)
endmacro()
macro(export)
endmacro()
7 changes: 7 additions & 0 deletions components/open62541/patch_config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Patch open62541 config.h to remove host-detected defines not available on ESP32/FreeRTOS
if(EXISTS "${CONFIG_H}")
file(READ "${CONFIG_H}" config_content)
string(REPLACE "#define UA_HAS_GETIFADDR 1" "/* #undef UA_HAS_GETIFADDR (not available on FreeRTOS/ESP32) */" config_content "${config_content}")
file(WRITE "${CONFIG_H}" "${config_content}")
message(STATUS "Patched ${CONFIG_H}: disabled UA_HAS_GETIFADDR")
endif()
2 changes: 1 addition & 1 deletion components/open62541/repo
Submodule repo updated 871 files
5 changes: 1 addition & 4 deletions main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@

idf_component_register(SRCS "main.c"
PRIV_INCLUDE_DIRS ${IDF_PATH}/components/freertos/include/freertos
REQUIRES open62541 ethernet_helper nvs_flash esp_adc_cal)
REQUIRES open62541 ethernet_helper nvs_flash esp_adc spi_flash)

# Build static library, do not build test executables
option(BUILD_SHARED_LIBS OFF)
option(BUILD_TESTING OFF)

# ESP32 is little endian
#add_definitions(-DUA_ENABLE_AMALGAMATION -DUA_ARCHITECTURE_FREERTOSLWIP -DUA_ARCHITECTURE_FREERTOSLWIP_POSIX_CLOCK)
#add_definitions(-Wno-ignored-qualifiers)

# Unfortunately the library performs install and export. Would
# have been nice if devs made that an option like BUILD_SHARED_LIBS
Expand Down
4 changes: 4 additions & 0 deletions main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependencies:
espressif/mdns:
version: ^1.0.0
idf: '>=5.0'
70 changes: 34 additions & 36 deletions main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <esp_event.h>
#include <esp_log.h>
#include <esp_system.h>
#include <esp_flash.h>
#include <sys/param.h>
#include <nvs_flash.h>

Expand All @@ -19,7 +20,11 @@
#include "freertos/task.h"

#include "esp_netif.h"
#include "esp_chip_info.h"
#include "ethernet_helper.h"
#ifdef CONFIG_ETHERNET_HELPER_WIFI
#include "esp_wifi.h"
#endif

#ifdef CONFIG_IDF_TARGET_ESP32
#define CHIP_NAME "ESP32"
Expand All @@ -29,12 +34,12 @@
#define CHIP_NAME "ESP32-S2 Beta"
#endif

#ifndef UA_ARCHITECTURE_FREERTOSLWIP
#error UA_ARCHITECTURE_FREERTOSLWIP needs to be defined
#endif

#include <open62541.h>

#if !defined(UA_ARCHITECTURE_LWIP) || !defined(UA_ARCHITECTURE_FREERTOS)
#error UA_ARCHITECTURE_LWIP and UA_ARCHITECTURE_FREERTOS need to be defined
#endif

#include <esp_task_wdt.h>
#include <esp_sntp.h>

Expand All @@ -54,16 +59,16 @@ RTC_DATA_ATTR static int boot_count = 0;
static UA_StatusCode
UA_ServerConfig_setUriName(UA_ServerConfig *uaServerConfig, const char *uri, const char *name) {
// delete pre-initialized values
UA_String_deleteMembers(&uaServerConfig->applicationDescription.applicationUri);
UA_LocalizedText_deleteMembers(&uaServerConfig->applicationDescription.applicationName);
UA_String_clear(&uaServerConfig->applicationDescription.applicationUri);
UA_LocalizedText_clear(&uaServerConfig->applicationDescription.applicationName);

uaServerConfig->applicationDescription.applicationUri = UA_String_fromChars(uri);
uaServerConfig->applicationDescription.applicationName.locale = UA_STRING_NULL;
uaServerConfig->applicationDescription.applicationName.text = UA_String_fromChars(name);

for (size_t i = 0; i < uaServerConfig->endpointsSize; i++) {
UA_String_deleteMembers(&uaServerConfig->endpoints[i].server.applicationUri);
UA_LocalizedText_deleteMembers(
UA_String_clear(&uaServerConfig->endpoints[i].server.applicationUri);
UA_LocalizedText_clear(
&uaServerConfig->endpoints[i].server.applicationName);

UA_String_copy(&uaServerConfig->applicationDescription.applicationUri,
Expand Down Expand Up @@ -103,30 +108,21 @@ static void opcua_task(void *arg) {
caps[1] = UA_String_fromChars("NA");
config->mdnsConfig.serverCapabilities = caps;

// We need to set the default IP address for mDNS since internally it's not able to detect it.
tcpip_adapter_ip_info_t default_ip;
esp_err_t ret = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &default_ip);
if ((ESP_OK == ret) && (default_ip.ip.addr != INADDR_ANY)) {
config->mdnsIpAddressListSize = 1;
config->mdnsIpAddressList = (uint32_t *)UA_malloc(sizeof(uint32_t)*config->mdnsIpAddressListSize);
memcpy(config->mdnsIpAddressList, &default_ip.ip.addr, sizeof(uint32_t));
} else {
ESP_LOGI(TAG_OPC, "Could not get default IP Address!");
}
#endif
UA_ServerConfig_setUriName(config, appUri, "open62541 ESP32 Demo");

#ifndef CONFIG_ETHERNET_HELPER_CUSTOM_HOSTNAME
#ifndef ETHERNET_HELPER_STATIC_IP4
#ifndef CONFIG_ETHERNET_HELPER_STATIC_IP4
#error You need to set a static IP or a custom hostname with menuconfig
#else
UA_String str = UA_STRING(CONFIG_ETHERNET_HELPER_STATIC_IP4_ADDRESS);
#define UA_SERVER_HOSTNAME CONFIG_ETHERNET_HELPER_STATIC_IP4_ADDRESS
#endif
#else
UA_String str = UA_STRING(CONFIG_ETHERNET_HELPER_CUSTOM_HOSTNAME_STR);
#define UA_SERVER_HOSTNAME CONFIG_ETHERNET_HELPER_CUSTOM_HOSTNAME_STR
#endif
UA_String_clear(&config->customHostname);
UA_String_copy(&str, &config->customHostname);
config->serverUrls = (UA_String *)UA_Array_new(1, &UA_TYPES[UA_TYPES_STRING]);
config->serverUrlsSize = 1;
config->serverUrls[0] = UA_STRING_ALLOC("opc.tcp://" UA_SERVER_HOSTNAME ":4840");

printf("xPortGetFreeHeapSize before create = %d bytes\n", xPortGetFreeHeapSize());

Expand Down Expand Up @@ -168,10 +164,10 @@ void time_sync_notification_cb(struct timeval *tv)
static void initialize_sntp(void)
{
ESP_LOGI(TAG, "Initializing SNTP");
sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, "pool.ntp.org");
sntp_set_time_sync_notification_cb(time_sync_notification_cb);
sntp_init();
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
esp_sntp_setservername(0, "pool.ntp.org");
esp_sntp_set_time_sync_notification_cb(time_sync_notification_cb);
esp_sntp_init();
}

static bool obtain_time(void)
Expand All @@ -185,7 +181,7 @@ static bool obtain_time(void)
memset(&timeinfo, 0, sizeof(struct tm));
int retry = 0;
const int retry_count = 10;
while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry <= retry_count) {
while (esp_sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry <= retry_count) {
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
vTaskDelay(2000 / portTICK_PERIOD_MS);
ESP_ERROR_CHECK(esp_task_wdt_reset());
Expand Down Expand Up @@ -239,11 +235,11 @@ void app_main(void)
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");

spi_flash_init();

printf("silicon revision %d, ", chip_info.revision);

printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
uint32_t flash_size = 0;
esp_flash_get_size(NULL, &flash_size);
printf("%dMB %s flash\n", (int)(flash_size / (1024 * 1024)),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");

printf("Heap Info:\n");
Expand All @@ -259,10 +255,12 @@ void app_main(void)
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());

ESP_ERROR_CHECK(esp_task_wdt_init(10, true));
// Remove idle tasks from watchdog
ESP_ERROR_CHECK(esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(0)));
ESP_ERROR_CHECK(esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(1)));
const esp_task_wdt_config_t wdt_config = {
.timeout_ms = 10000,
.idle_core_mask = 0,
.trigger_panic = true,
};
ESP_ERROR_CHECK(esp_task_wdt_init(&wdt_config));

/* Register event handlers to stop the server when Wi-Fi or Ethernet is disconnected,
* and re-start it upon connection.
Expand All @@ -280,4 +278,4 @@ void app_main(void)

ESP_ERROR_CHECK(ethernet_helper_connect());

}
}
Loading