Skip to content

Commit 83b2218

Browse files
KaSrokaAnas Nashif
authored andcommitted
subsys: net: lib: Add OpenThread platform
OpenThread requires platform definition with standarized API so we have to add wrappers to make it compatible with Zephyr. OpenThread is based on autoconf, this requires more specific CMakeLists.txt which allows to clone specific commit or point to local copy of openthread. Signed-off-by: Kamil Sroka <[email protected]>
1 parent fad1c66 commit 83b2218

File tree

16 files changed

+1308
-0
lines changed

16 files changed

+1308
-0
lines changed

subsys/net/lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ if(CONFIG_HTTP_PARSER_URL
1212
add_subdirectory(http)
1313
endif()
1414

15+
add_subdirectory_ifdef(CONFIG_OPENTHREAD_PLAT openthread)
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
# Invoke OpenThread's external autoconf-based build system.
2+
include(ExternalProject)
3+
4+
set(ep_base ${PROJECT_BINARY_DIR}/ext_proj)
5+
set_property(DIRECTORY PROPERTY "EP_BASE" ${ep_base})
6+
7+
# Construct a list of commands to give to ExternalProject_Add()
8+
#
9+
# See https://cmake.org/cmake/help/latest/module/ExternalProject.html
10+
# for documentation on ExternalProject_Add
11+
set(cmd "")
12+
13+
set(ot_name ot)
14+
list(APPEND cmd
15+
${ot_name}
16+
)
17+
18+
set(ot_STAMP_DIR ${ep_base}/Stamp/${ot_name})
19+
set(ot_INSTALL_DIR ${ep_base}/Install/${ot_name})
20+
21+
#--Download step--------------
22+
if(NOT EXTERNAL_PROJECT_PATH_OPENTHREAD)
23+
# TODO: Point to a Zephyr fork
24+
# Nov. 7
25+
set_ifndef(ot_GIT_REPOSITORY "https://github.com/openthread/openthread.git")
26+
set_ifndef(ot_GIT_TAG a89eb887488dcbab7f5e9237e2bbcaad38140690)
27+
set_ifndef(ot_GIT_PROGRESS 1)
28+
29+
list(APPEND cmd
30+
GIT_REPOSITORY ${ot_GIT_REPOSITORY}
31+
GIT_TAG ${ot_GIT_TAG}
32+
GIT_PROGRESS ${ot_GIT_PROGRESS}
33+
)
34+
endif()
35+
36+
#--Update/Patch step-------------
37+
38+
# An update step is not necessary because we are using a commit hash
39+
# as a tag, and the code behind a hash cannot change.
40+
41+
# UPDATE_DISCONNECTED should be used when updates aren't needed, but
42+
# for some reason we were not able to get this to work, so we use a
43+
# dummy step to fake updating. This ensures that the git repo is not
44+
# downloaded on every 'make' invocation.
45+
list(APPEND cmd
46+
UPDATE_COMMAND
47+
${CMAKE_COMMAND} -E touch ${ot_STAMP_DIR}/${ot_name}-update
48+
)
49+
50+
#--Configure step-------------
51+
if(EXTERNAL_PROJECT_PATH_OPENTHREAD)
52+
set(ot_SOURCE_DIR ${EXTERNAL_PROJECT_PATH_OPENTHREAD})
53+
54+
list(APPEND cmd
55+
SOURCE_DIR ${ot_SOURCE_DIR}
56+
)
57+
58+
else()
59+
set(ot_SOURCE_DIR ${ep_base}/Source/${ot_name}) # TODO: Download dir?
60+
61+
# "If SOURCE_DIR is explicitly set to an existing directory the
62+
# project will be built from it. Otherwise a download step must be
63+
# specified using one of the DOWNLOAD_COMMAND, CVS_*, SVN_*, or URL
64+
# options." -- CMake docs
65+
endif()
66+
67+
# TODO: Can we omit this, does OpenThread need to use install?
68+
# TODO: Move this to host-tools?
69+
find_program(INSTALL install)
70+
71+
# It looks like OpenThread requires a *nix system to build for
72+
# embedded.
73+
#
74+
# https://github.com/openthread/openthread/blob/master/examples/drivers/windows/README.md
75+
76+
# TODO: Use different includes for C and CXX
77+
zephyr_get_include_directories_for_lang_as_string( C includes)
78+
zephyr_get_system_include_directories_for_lang_as_string(C system_includes)
79+
zephyr_get_compile_definitions_for_lang_as_string( C definitions)
80+
81+
zephyr_get_compile_options_for_lang_as_string(C c_options)
82+
zephyr_get_compile_options_for_lang_as_string(CXX cxx_options)
83+
84+
# TODO: What happens if a CFLAG is added after this build script has
85+
# been run?
86+
87+
# TODO: Does OpenThread need all flags, or just some? Should we
88+
# whitelist, or blacklist flags?
89+
90+
91+
# TODO: What is all this? $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
92+
93+
set(exec_prefix zephyr)
94+
95+
set(commoncflags "-DOPENTHREAD_CONFIG_LOG_LEVEL=${CONFIG_OPENTHREAD_LOG_LEVEL}")
96+
set(commoncflags "${commoncflags} -DOPENTHREAD_PROJECT_CORE_CONFIG_FILE=\\\"openthread-core-zephyr-config.h\\\"")
97+
set(commoncflags "${commoncflags} -I${CMAKE_CURRENT_LIST_DIR}/platform")
98+
99+
set(configure_flags
100+
"INSTALL=${INSTALL} -p"
101+
"CPP=${CMAKE_C_COMPILER} -E" # TODO: Find CPP in toolchain-gcc.cmake and use that instead?
102+
"CC=${CMAKE_C_COMPILER}"
103+
"CXX=${CMAKE_CXX_COMPILER}"
104+
OBJC="" # TODO: Omit this?
105+
"OBJCXX=${OBJCXX}" # TODO: Omit this?
106+
"AR=${CMAKE_AR}"
107+
"RANLIB=${CMAKE_RANLILB}"
108+
"NM=${CROSS_COMPILE}nm" # TODO: Find NM in toolchain-gcc.cmake and use that instead?
109+
"STRIP=${CMAKE_STRIP}"
110+
"CPPFLAGS=${definitions} ${commoncflags} ${includes} ${system_includes}"
111+
"CFLAGS=${c_options} ${commoncflags} ${includes} ${system_includes}"
112+
"CXXFLAGS=${cxx_options} ${commoncflags} ${includes} ${system_includes}" # TODO: Do we need includes here?
113+
LDFLAGS="" # TODO: What does a networking stack need to use the linker for?
114+
115+
--host=arm-none-eabi
116+
--prefix=/
117+
--exec-prefix=/${exec_prefix}
118+
--target=arm-none-eabi # TODO: Is Kconfig expressing that OT is ARM-only?
119+
--enable-no-executables-hack
120+
--disable-docs
121+
--with-platform-info=zephyr
122+
)
123+
124+
# TODO: Simplify
125+
set(ZEPHYR_MBEDTLS_CPPFLAGS "${ZEPHYR_MBEDTLS_CPPFLAGS} ")
126+
set(ZEPHYR_MBEDTLS_CPPFLAGS "-DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'")
127+
set(ZEPHYR_MBEDTLS_CPPFLAGS "${ZEPHYR_MBEDTLS_CPPFLAGS} -DMBEDTLS_USER_CONFIG_FILE='\"${CMAKE_CURRENT_SOURCE_DIR}/zephyr-mbedtls-config.h\"'")
128+
set(ZEPHYR_MBEDTLS_CPPFLAGS "${ZEPHYR_MBEDTLS_CPPFLAGS} -I${ot_SOURCE_DIR}/third_party/mbedtls")
129+
set(ZEPHYR_MBEDTLS_CPPFLAGS "${ZEPHYR_MBEDTLS_CPPFLAGS} -I${ot_SOURCE_DIR}/third_party/mbedtls/repo.patched/include")
130+
set(ZEPHYR_MBEDTLS_CPPFLAGS "${ZEPHYR_MBEDTLS_CPPFLAGS} -I${ot_SOURCE_DIR}/third_party/mbedtls/repo.patched/include/mbedtls")
131+
132+
list(APPEND configure_flags
133+
"MBEDTLS_CPPFLAGS=${ZEPHYR_MBEDTLS_CPPFLAGS}"
134+
)
135+
136+
if(CONFIG_OPENTHREAD_COMMISSIONER)
137+
list(APPEND configure_flags
138+
--enable-commissioner
139+
)
140+
endif()
141+
142+
if(CONFIG_OPENTHREAD_JAM_DETECTION)
143+
list(APPEND configure_flags
144+
--enable-jam-detection
145+
)
146+
endif()
147+
148+
if(CONFIG_OPENTHREAD_JOINER)
149+
list(APPEND configure_flags
150+
--enable-joiner
151+
)
152+
endif()
153+
154+
if(CONFIG_OPENTHREAD_SHELL)
155+
list(APPEND configure_flags
156+
--enable-cli-app=all
157+
)
158+
endif()
159+
160+
if(CONFIG_OPENTHREAD_DIAG)
161+
list(APPEND configure_flags
162+
--enable-diag
163+
)
164+
endif()
165+
166+
list(APPEND cmd
167+
CONFIGURE_COMMAND ./configure ${configure_flags}
168+
)
169+
170+
#--Build step-----------------
171+
172+
# Invoke OpenThread's build system from the root of it's source
173+
# directory
174+
# TODO: Support out-of-source builds
175+
set(ot_BINARY_DIR ${ot_SOURCE_DIR})
176+
list(APPEND cmd
177+
BINARY_DIR ${ot_BINARY_DIR}
178+
INSTALL_DIR ${ot_INSTALL_DIR}
179+
)
180+
181+
set(make_flags
182+
-j99 # TODO: Why 99?
183+
--no-print-directory
184+
)
185+
186+
list(APPEND cmd
187+
BUILD_COMMAND make ${make_flags} all
188+
INSTALL_COMMAND make ${make_flags} DESTDIR=${ot_INSTALL_DIR} install
189+
)
190+
191+
# TODO: Find out how to make this work.
192+
set(ot_include_dir ${ot_SOURCE_DIR}/include)
193+
194+
# TODO: Is this only needed by alarm.c?
195+
zephyr_system_include_directories(${ot_include_dir})
196+
197+
# TODO: Why doesn't app get this path from the above function call?
198+
target_include_directories(app SYSTEM PRIVATE ${ot_include_dir})
199+
200+
#set_target_properties(ot_lib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${ot_include_dir})
201+
zephyr_include_directories(${ot_include_dir})
202+
203+
# Determine which libs should be linked in
204+
set(ot_libs
205+
openthread-platform-utils
206+
mbedcrypto
207+
)
208+
if(CONFIG_OPENTHREAD_FTD)
209+
list(APPEND ot_libs openthread-ftd)
210+
set(cli_lib openthread-cli-ftd)
211+
elseif(CONFIG_OPENTHREAD_MTD)
212+
list(APPEND ot_libs openthread-mtd)
213+
set(cli_lib openthread-cli-ftd)
214+
endif()
215+
216+
if(CONFIG_OPENTHREAD_SHELL)
217+
list(APPEND ot_libs ${cli_lib})
218+
endif()
219+
220+
foreach(ot_lib ${ot_libs})
221+
set(build_byproducts ${build_byproducts} ${ot_INSTALL_DIR}/${exec_prefix}/lib/lib${ot_lib}.a)
222+
endforeach()
223+
224+
list(APPEND cmd
225+
BUILD_BYPRODUCTS ${build_byproducts}
226+
)
227+
228+
ExternalProject_Add(${cmd})
229+
230+
ExternalProject_Add_Step(
231+
${ot_name} bootstrap # Names of project and custom step
232+
COMMAND ./bootstrap # Command line invoked by this step
233+
COMMENT "bootstrapping..." # Text printed when step executes
234+
DEPENDEES download # Steps on which this step depends
235+
DEPENDERS configure # Steps that depend on this step
236+
WORKING_DIRECTORY ${ot_SOURCE_DIR}
237+
)
238+
239+
# Create wrapper CMake libraries
240+
foreach(ot_lib ${ot_libs})
241+
add_library(${ot_lib} STATIC IMPORTED GLOBAL)
242+
add_dependencies( # TODO: Necessary?
243+
${ot_lib}
244+
${ot_name}
245+
)
246+
set_target_properties(${ot_lib} PROPERTIES IMPORTED_LOCATION
247+
${ot_INSTALL_DIR}/${exec_prefix}/lib/lib${ot_lib}.a
248+
)
249+
zephyr_append_cmake_library(${ot_lib})
250+
endforeach()
251+
252+
add_subdirectory(platform)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
zephyr_library_named(openthread_platform)
2+
zephyr_library_sources(
3+
alarm.c
4+
flash.c
5+
logging.c
6+
misc.c
7+
platform.c
8+
radio.c
9+
random.c
10+
spi.c
11+
)
12+
13+
zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_SHELL shell.c)
14+
15+
# The source files here use header files from the OpenThread project
16+
# target_link_libraries(app ot_lib) # Better?
17+
add_dependencies(openthread_platform ot)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2018 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <kernel.h>
8+
#include <string.h>
9+
#include <inttypes.h>
10+
11+
#include <openthread/platform/alarm-milli.h>
12+
#include <openthread/platform/platform.h>
13+
14+
#define SYS_LOG_DOMAIN "openthread-plat"
15+
#define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
16+
#include <logging/sys_log.h>
17+
#include <stdio.h>
18+
19+
#include "platform-zephyr.h"
20+
21+
static bool timer_fired;
22+
23+
static void ot_timer_fired(struct k_timer *timer)
24+
{
25+
ARG_UNUSED(timer);
26+
27+
timer_fired = true;
28+
PlatformEventSignalPending();
29+
}
30+
31+
K_TIMER_DEFINE(ot_timer, ot_timer_fired, NULL);
32+
33+
void platformAlarmInit(void)
34+
{
35+
/* Intentionally empty */
36+
}
37+
38+
uint32_t otPlatAlarmMilliGetNow(void)
39+
{
40+
return k_uptime_get_32();
41+
}
42+
43+
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t t0, uint32_t dt)
44+
{
45+
ARG_UNUSED(aInstance);
46+
47+
s64_t reftime = (s64_t)t0 + (s64_t)dt;
48+
s64_t delta = -k_uptime_delta(&reftime);
49+
50+
if (delta > 0) {
51+
k_timer_start(&ot_timer, K_MSEC(delta), 0);
52+
} else {
53+
ot_timer_fired(NULL);
54+
}
55+
}
56+
57+
void otPlatAlarmMilliStop(otInstance *aInstance)
58+
{
59+
ARG_UNUSED(aInstance);
60+
61+
k_timer_stop(&ot_timer);
62+
}
63+
64+
65+
void platformAlarmProcess(otInstance *aInstance)
66+
{
67+
if (timer_fired) {
68+
timer_fired = false;
69+
otPlatAlarmMilliFired(aInstance);
70+
}
71+
}

0 commit comments

Comments
 (0)