Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added LwIP support for stm32-cmake #263

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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::<N>` - heap implementation (`heap_<N>.c`), `<N>`: [1-5]

## <a id="lwip"></a> 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
)
```
94 changes: 94 additions & 0 deletions cmake/FindLwIP.cmake
Original file line number Diff line number Diff line change
@@ -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")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file exists from F4 F7 H7 cube only. Although LWIP is in cube F1 F2 F4 F7 H7 because they are more or less up to date. ST updates Middleware only on minor (1.X.0) releases of cube

Edit: this is the pending comment from when I first read your code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh that's interesting. The Cube repositories have LwIP, but I am not even sure whether the processor or the boards support networking applications. I'm browsing the example applications here right now: https://github.com/STMicroelectronics/STM32CubeF4/tree/master/Projects/STM32F429I-Discovery/Applications and I can't see any example applications. Have not checked F7 yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me it appears only F7 and H7 have networking applications

Copy link
Contributor Author

@robamu robamu Jun 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


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
)