From 90185a3b9d3296472995844b6f58d99182991346 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 20:03:36 +0200 Subject: [PATCH 1/4] Added LwIP support for stm32-cmake This feature allows using the LwIP source code and OS abstraction layer provided by STM to build networking applications for STM MCUs with stm32-cmake. It uses the CMakeLists.txt already contained in the LwIP sources. It is difficult to provide examples for LwIP code for various reasons: 1. Networking code often requires special code which is board and architecture specific. Examples: PHY or linker scripts for special lwip sections 2. STM licenses a lot of their example code differently than the rest of the HAL repositories. This license might be incompatible to the MIT license. A separate project is linked in the README example section for a basic UDP echoserver on the H743ZI board. The README was updated with intructions on how to use the LwIP support. --- README.md | 32 ++++++++++++++++ cmake/FindLwIP.cmake | 87 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 cmake/FindLwIP.cmake diff --git a/README.md b/README.md index b40fc373..b03e83d1 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,11 @@ It uses cmake and GCC, along with newlib (libc), STM32Cube. Supports F0 F1 F2 F3 You can opt to use the FreeRTOS CMSIS implementation provided by the Cube repository by supplying `USE_CMSIS_RTOS=ON` or `USE_CMSIS_RTOS_V2` to CMake. +The `lwip` support does not have a dedicated example because most STM devices have different PHYs +and/or there is machine and linker script specific code which makes it difficult to create a +generic example. You can find an UDP echo server application for the H743ZI board +[here](https://github.com/robamu-org/stm32h743-cmake-minimal). + # Usage First of all you need to configure toolchain and library paths using CMake variables. There are @@ -287,3 +292,30 @@ Other FreeRTOS libraries, with `FREERTOS_NAMESPACE` being set as specified in th * `${FREERTOS_NAMESPACE}::StreamBuffer` - stream buffer (`stream_buffer.c`) * `${FREERTOS_NAMESPACE}::Timers` - timers (`timers.c`) * `${FREERTOS_NAMESPACE}::Heap::` - heap implementation (`heap_.c`), ``: [1-5] + +## LwIP + +[cmake/FindLwIP](cmake/FindLwIP.cmake) - finds LwIP sources in STM32Cube repository and format them +as `IMPORTED` targets. You should should have a `lwipopts.h` in the application includes +for this to work. If you want to use the Netconn or Socket API, you need to link against +the CMSIS support like specified in the [FreeRTOS section](#freertos). + +Available LwIP libraries: + +* `LwIP::IPv4` - IPv4 support +* `LwIP::IPv6` - IPv6 support +* `LwIP::SYS` - System support (`sys_arch.c`) +* `LwIP::API` - Support for Netconn and Socket API. Will also link `LwIP::SYS` automatically +* `LwIP::NETIF` - Netif sources support + +Typical usage when using Raw API to implement a simple UDP echoserver + +```cmake +find_package(LwIP REQUIRED) +target_link_libraries(${TARGET_NAME} PRIVATE + ... + LwIP + LwIP::IPv4 + LwIP::NETIF +) +``` diff --git a/cmake/FindLwIP.cmake b/cmake/FindLwIP.cmake new file mode 100644 index 00000000..d6ad1f5d --- /dev/null +++ b/cmake/FindLwIP.cmake @@ -0,0 +1,87 @@ +# If NO_SYS is set to 0 and the Netconn or Socket API is used, the user should link against +# the CMSIS RTOS or RTOS_V2 support because the sys_arch.c LwIP OS port layer makes use of +# CMSIS calls. +find_path(LwIP_ROOT + NAMES CMakeLists.txt + PATHS "${STM32_CUBE_${FAMILY}_PATH}/Middlewares/Third_Party/LwIP" + NO_DEFAULT_PATH +) + +if(LwIP_ROOT MATCHES "LwIP_ROOT-NOTFOUND") + message(WARNING "LwIP root foolder not found. LwIP might not be supported") +endif() + +set(LWIP_DIR ${LwIP_ROOT}) + +find_path(LwIP_SOURCE_PATH + NAMES Filelists.cmake + PATHS "${STM32_CUBE_${FAMILY}_PATH}/Middlewares/Third_Party/LwIP/src" + NO_DEFAULT_PATH +) + +if(LwIP_SOURCE_PATH MATCHES "LwIP_SOURCE_PATH-NOTFOUND") + message(WARNING "LwIP filelist CMake file not found. Build might fail") +endif() + +if(IS_DIRECTORY "${LwIP_SOURCE_PATH}/include") + set(LwIP_INCLUDE_DIR "${LwIP_SOURCE_PATH}/include") +else() + message(WARNING "LwIP include directory not found. Build might fail") +endif() + +if(IS_DIRECTORY "${LwIP_ROOT}/system") + set(LwIP_SYS_INCLUDE_DIR "${LwIP_ROOT}/system") + set(LwIP_SYS_SOURCES "${LwIP_ROOT}/system/OS/sys_arch.c") +else() + message(WARNING "LwIP system include directory not found. Build might fail") +endif() + +# Use Filelists.cmake to get list of sources to compile +include("${LwIP_SOURCE_PATH}/Filelists.cmake") + +if(NOT (TARGET LwIP)) + add_library(LwIP INTERFACE IMPORTED) + target_sources(LwIP INTERFACE ${lwipcore_SRCS}) + target_include_directories(LwIP INTERFACE + ${LwIP_INCLUDE_DIR} ${LwIP_SYS_INCLUDE_DIR} + ) +endif() + +# Compile the system components which use CMSIS RTOS. This is necessary for the NETIF and Socket API +# This target also requires that the application was linked against the CMSIS RTOS support +if(NOT (TARGET LwIP::SYS)) + add_library(LwIP::SYS INTERFACE IMPORTED) + target_sources(LwIP::SYS INTERFACE ${LwIP_SYS_SOURCES}) + target_link_libraries(LwIP::SYS INTERFACE LwIP) +endif() + +if(NOT (TARGET LwIP::IPv4)) + add_library(LwIP::IPv4 INTERFACE IMPORTED) + target_sources(LwIP::IPv4 INTERFACE ${lwipcore4_SRCS}) + target_link_libraries(LwIP::IPv4 INTERFACE LwIP) +endif() + +if(NOT (TARGET LwIP::IPv6)) + add_library(LwIP::IPv6 INTERFACE IMPORTED) + target_sources(LwIP::IPv6 INTERFACE ${lwipcore6_SRCS}) + target_link_libraries(LwIP::IPv6 INTERFACE LwIP) +endif() + +if(NOT (TARGET LwIP::API)) + add_library(LwIP::API INTERFACE IMPORTED) + target_sources(LwIP::API INTERFACE ${lwipapi_SRCS}) + target_link_libraries(LwIP::API INTERFACE LwIP::SYS) +endif() + +if(NOT (TARGET LwIP::NETIF)) + add_library(LwIP::NETIF INTERFACE IMPORTED) + target_sources(LwIP::NETIF INTERFACE ${lwipnetif_SRCS}) + target_link_libraries(LwIP::NETIF INTERFACE LwIP) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LwIP + REQUIRED_VARS LwIP_ROOT LwIP_INCLUDE_DIR LwIP_SYS_INCLUDE_DIR + FOUND_VAR LwIP_FOUND + HANDLE_COMPONENTS +) From c755ed4101b6cf247b21e9318c39a5da18e9b5ec Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 20:18:33 +0200 Subject: [PATCH 2/4] improved phrasing --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b03e83d1..80d9fb24 100644 --- a/README.md +++ b/README.md @@ -296,9 +296,9 @@ Other FreeRTOS libraries, with `FREERTOS_NAMESPACE` being set as specified in th ## LwIP [cmake/FindLwIP](cmake/FindLwIP.cmake) - finds LwIP sources in STM32Cube repository and format them -as `IMPORTED` targets. You should should have a `lwipopts.h` in the application includes -for this to work. If you want to use the Netconn or Socket API, you need to link against -the CMSIS support like specified in the [FreeRTOS section](#freertos). +as `IMPORTED` targets. This requires a `lwipopts.h` in the application include path to work. +If the Netconn or Socket API is used, the CMSIS support needs to be linked like specified in +the [FreeRTOS section](#freertos). Available LwIP libraries: From a8e267ccd400e82707b10561a224f2d8155cedf3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 Aug 2021 13:30:48 +0200 Subject: [PATCH 3/4] updated link in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 80d9fb24..01bbe526 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ It uses cmake and GCC, along with newlib (libc), STM32Cube. Supports F0 F1 F2 F3 The `lwip` support does not have a dedicated example because most STM devices have different PHYs and/or there is machine and linker script specific code which makes it difficult to create a generic example. You can find an UDP echo server application for the H743ZI board -[here](https://github.com/robamu-org/stm32h743-cmake-minimal). +[here](https://github.com/robamu-org/stm32-cmake-projects). # Usage From 470f7492e23b0a43e5806e12da7c697ecf09bebf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 7 Jun 2022 23:14:04 +0200 Subject: [PATCH 4/4] check whether Filelists.cmake actually exists --- cmake/FindLwIP.cmake | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/cmake/FindLwIP.cmake b/cmake/FindLwIP.cmake index d6ad1f5d..a731f096 100644 --- a/cmake/FindLwIP.cmake +++ b/cmake/FindLwIP.cmake @@ -7,8 +7,10 @@ find_path(LwIP_ROOT NO_DEFAULT_PATH ) +set(MSG_PREFIX "stm32-FindLwIP |") + if(LwIP_ROOT MATCHES "LwIP_ROOT-NOTFOUND") - message(WARNING "LwIP root foolder not found. LwIP might not be supported") + message(WARNING "${MSG_PREFIX} LwIP root foolder not found. LwIP might not be supported") endif() set(LWIP_DIR ${LwIP_ROOT}) @@ -20,20 +22,25 @@ find_path(LwIP_SOURCE_PATH ) if(LwIP_SOURCE_PATH MATCHES "LwIP_SOURCE_PATH-NOTFOUND") - message(WARNING "LwIP filelist CMake file not found. Build might fail") + message(WARNING "${MSG_PREFIX} LwIP filelist CMake file not found. Build might fail") endif() if(IS_DIRECTORY "${LwIP_SOURCE_PATH}/include") set(LwIP_INCLUDE_DIR "${LwIP_SOURCE_PATH}/include") else() - message(WARNING "LwIP include directory not found. Build might fail") + message(WARNING "${MSG_PREFIX} LwIP include directory not found. Build might fail") endif() if(IS_DIRECTORY "${LwIP_ROOT}/system") set(LwIP_SYS_INCLUDE_DIR "${LwIP_ROOT}/system") set(LwIP_SYS_SOURCES "${LwIP_ROOT}/system/OS/sys_arch.c") else() - message(WARNING "LwIP system include directory not found. Build might fail") + message(WARNING "${MSG_PREFIX} LwIP system include directory not found. Build might fail") +endif() + +if(NOT EXISTS "${LwIP_SOURCE_PATH}/Filelists.cmake") + message(WARNING "${MSG_PREFIX} ${LwIP_SOURCE_PATH}/Filelists.cmake file not found.") + message(FATAL_ERROR "${MSG_PREFIX} Please ensure that the LwIP version is at least 2.1.0") endif() # Use Filelists.cmake to get list of sources to compile