diff --git a/README.md b/README.md index b40fc373..01bbe526 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/stm32-cmake-projects). + # 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. 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: + +* `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..a731f096 --- /dev/null +++ b/cmake/FindLwIP.cmake @@ -0,0 +1,94 @@ +# 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 +) + +set(MSG_PREFIX "stm32-FindLwIP |") + +if(LwIP_ROOT MATCHES "LwIP_ROOT-NOTFOUND") + message(WARNING "${MSG_PREFIX} 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 "${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 "${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 "${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 +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 +)