浏览代码

Merge pull request #770 from antmicro/zephyr-rtos-port

Zephyr RTOS port
bel2125 6 年之前
父节点
当前提交
2a034d3bac
共有 3 个文件被更改,包括 195 次插入59 次删除
  1. 85 28
      CMakeLists.txt
  2. 108 31
      src/civetweb.c
  3. 2 0
      zephyr/module.yml

+ 85 - 28
CMakeLists.txt

@@ -13,7 +13,7 @@ set(CMAKE_DISABLE_SOURCE_CHANGES ON)
 set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
 
 # Make sure we can import out CMake functions
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
 
 # Load in the needed CMake modules
 include(CheckIncludeFiles)
@@ -38,8 +38,10 @@ determine_target_architecture(CIVETWEB_ARCHITECTURE)
 include(GNUInstallDirs)
 
 # Detect the platform reliably
-if(NOT MACOSX AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
-   SET(DARWIN YES)
+if(${KERNEL_NAME} MATCHES "zephyr")
+    SET(ZEPHYR YES)
+elseif(NOT MACOSX AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    SET(DARWIN YES)
 elseif(NOT BSD AND ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
     SET(FREEBSD YES)
 elseif(NOT LINUX AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@@ -294,27 +296,6 @@ else()
   add_c_compiler_flag(-std=${CIVETWEB_C_STANDARD})
 endif()
 
-#Warnings: enable everything
-add_c_compiler_flag(-Wall)
-add_c_compiler_flag(-Wextra)
-add_c_compiler_flag(-Wshadow)
-add_c_compiler_flag(-Wconversion)
-add_c_compiler_flag(-Wmissing-prototypes)
-add_c_compiler_flag(-Weverything)
-add_c_compiler_flag(-Wparentheses)
-add_c_compiler_flag(/W4) # VisualStudio highest warning level
-
-#Warnings: Disable some warnings
-add_c_compiler_flag(-Wno-padded) # padding in structures by compiler
-add_c_compiler_flag(-Wno-unused-macros) # so what?
-Check_C_Compiler_Flag( HAVE_NO_RESERVED_ID_MACROS -Wno-reserved-id-macros)
-if (HAVE_NO_RESERVED_ID_MACROS)
-add_c_compiler_flag(-Wno-reserved-id-macros) # for system headers
-endif (HAVE_NO_RESERVED_ID_MACROS)
-add_c_compiler_flag(-Wno-format-nonliteral) # printf(myFormatStringVar, ...)
-add_c_compiler_flag(-Wno-cast-qual) # const cast
-add_c_compiler_flag(/Wd4820) # padding
-
 if (MINGW)
   add_c_compiler_flag(-Wno-format)
 endif()
@@ -322,9 +303,6 @@ if (NOT CIVETWEB_ALLOW_WARNINGS)
   add_c_compiler_flag(-Werror)
   add_c_compiler_flag(/WX)
 endif()
-add_c_compiler_flag(-pedantic-errors)
-add_c_compiler_flag(-fvisibility=hidden)
-add_c_compiler_flag(-fstack-protector-strong RELEASE)
 if (${CIVETWEB_ENABLE_LTO})
   add_c_compiler_flag(-flto RELEASE)
 endif()
@@ -335,7 +313,6 @@ if (HAVE_C_FLAG_FSANITIZE_ADDRESS)
   add_c_compiler_flag(-static-asan DEBUG)
 endif()
 endif()
-add_c_compiler_flag(-fstack-protector-all DEBUG)
 if (MINGW)
   add_c_compiler_flag(-mwindows)
 endif()
@@ -417,6 +394,79 @@ if (CIVETWEB_ENABLE_CXX)
   add_cxx_compiler_flag(--coverage COVERAGE)
 endif()
 
+if (NOT ZEPHYR)
+  #Warnings: enable everything
+  add_c_compiler_flag(-Wall)
+  add_c_compiler_flag(-Wextra)
+  add_c_compiler_flag(-Wshadow)
+  add_c_compiler_flag(-Wconversion)
+  add_c_compiler_flag(-Wmissing-prototypes)
+  add_c_compiler_flag(-Weverything)
+  add_c_compiler_flag(-Wparentheses)
+  add_c_compiler_flag(/W4) # VisualStudio highest warning level
+
+  #Warnings: Disable some warnings
+  add_c_compiler_flag(-Wno-padded) # padding in structures by compiler
+  add_c_compiler_flag(-Wno-unused-macros) # so what?
+  Check_C_Compiler_Flag( HAVE_NO_RESERVED_ID_MACROS -Wno-reserved-id-macros)
+  if (HAVE_NO_RESERVED_ID_MACROS)
+  add_c_compiler_flag(-Wno-reserved-id-macros) # for system headers
+  endif (HAVE_NO_RESERVED_ID_MACROS)
+  add_c_compiler_flag(-Wno-format-nonliteral) # printf(myFormatStringVar, ...)
+  add_c_compiler_flag(-Wno-cast-qual) # const cast
+  add_c_compiler_flag(/Wd4820) # padding
+
+  add_c_compiler_flag(-pedantic-errors)
+  add_c_compiler_flag(-fvisibility=hidden)
+  add_c_compiler_flag(-fstack-protector-strong RELEASE)
+  add_c_compiler_flag(-fstack-protector-all DEBUG)
+else()
+  # This policy is needed to override options with variables
+  cmake_policy(SET CMP0077 NEW)
+
+  # Configure what you need/support in Zephyr
+  set(CIVETWEB_SERVE_NO_FILES ON)
+  set(CIVETWEB_SERVE_NO_FILESYSTEMS ON)
+  set(CIVETWEB_DISABLE_CGI ON)
+  set(CIVETWEB_DISABLE_CACHING ON)
+  set(CIVETWEB_ENABLE_SSL OFF)
+  set(CIVETWEB_ENABLE_SSL_DYNAMIC_LOADING OFF)
+
+  set(CIVETWEB_ENABLE_LUA OFF)
+  set(CIVETWEB_ENABLE_DUKTAPE OFF)
+  set(CIVETWEB_ENABLE_MEMORY_DEBUGGING OFF)
+  set(CIVETWEB_ENABLE_SERVER_EXECUTABLE OFF)
+  set(CIVETWEB_ENABLE_ASAN OFF)
+  set(CIVETWEB_INSTALL_EXECUTABLE OFF)
+
+  set(CIVETWEB_THREAD_STACK_SIZE 0)
+
+  set(BUILD_SHARED_LIBS OFF)
+
+  add_definitions(-DMG_EXTERNAL_FUNCTION_mg_cry_internal_impl)
+  add_definitions(-DMG_EXTERNAL_FUNCTION_log_access)
+
+  add_definitions(-DNO_ALTERNATIVE_QUEUE)
+  add_definitions(-DZEPHYR_VERSION=${KERNEL_VERSION_STRING})
+
+  zephyr_interface_library_named(CIVETWEB)
+
+  target_include_directories(CIVETWEB INTERFACE src)
+  target_include_directories(CIVETWEB INTERFACE include)
+  target_include_directories(CIVETWEB INTERFACE ${CMAKE_SOURCE_DIR}/src)
+
+  zephyr_include_directories(include)
+
+  zephyr_library()
+  zephyr_library_sources(
+    src/civetweb.c
+  )
+
+  zephyr_library_link_libraries(CIVETWEB)
+  target_link_libraries(CIVETWEB INTERFACE zephyr_interface)
+endif()
+
+
 # Set up the definitions
 if (${CMAKE_BUILD_TYPE} MATCHES "[Dd]ebug")
   add_definitions(-DDEBUG)
@@ -435,6 +485,9 @@ endif()
 if (CIVETWEB_SERVE_NO_FILES)
   add_definitions(-DNO_FILES)
 endif()
+if (CIVETWEB_SERVE_NO_FILESYSTEMS)
+  add_definitions(-DNO_FILESYSTEMS)
+endif()
 if (CIVETWEB_DISABLE_CGI)
   add_definitions(-DNO_CGI)
 endif()
@@ -476,6 +529,10 @@ add_c_compiler_flag(-m64)
 endif()
 # TODO: add support for -march
 
+if (ZEPHYR)
+  return()
+endif()
+
 # Build the targets
 add_subdirectory(src)
 

+ 108 - 31
src/civetweb.c

@@ -162,6 +162,39 @@ mg_static_assert(sizeof(void *) >= sizeof(int), "data type size check");
 #define PATH_MAX FILENAME_MAX
 #endif /* __SYMBIAN32__ */
 
+#if defined(__ZEPHYR__)
+#include <time.h>
+
+#include <zephyr.h>
+#include <posix/time.h>
+#include <net/socket.h>
+#include <posix/pthread.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <fcntl.h>
+
+#include <libc_extensions.h>
+
+/* Max worker threads is the max of pthreads minus the main application thread
+ * and minus the main civetweb thread, thus -2
+ */
+#define MAX_WORKER_THREADS	(CONFIG_MAX_PTHREAD_COUNT - 2)
+
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+#define ZEPHYR_STACK_SIZE	USE_STACK_SIZE
+#else
+#define ZEPHYR_STACK_SIZE	8096
+#endif
+
+K_THREAD_STACK_DEFINE(civetweb_main_stack, ZEPHYR_STACK_SIZE);
+K_THREAD_STACK_ARRAY_DEFINE(civetweb_worker_stacks, MAX_WORKER_THREADS, ZEPHYR_STACK_SIZE);
+
+static int zephyr_worker_stack_index;
+
+#endif
 
 #if !defined(CIVETWEB_HEADER_INCLUDED)
 /* Include the header file here, so the CivetWeb interface is defined for the
@@ -260,7 +293,7 @@ __cyg_profile_func_exit(void *this_fn, void *call_site)
 
 
 /* Some ANSI #includes are not available on Windows CE */
-#if !defined(_WIN32_WCE)
+#if !defined(_WIN32_WCE) && !defined(__ZEPHYR__)
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -375,16 +408,6 @@ _civet_safe_clock_gettime(int clk_id, struct timespec *t)
 #endif
 
 
-#include <ctype.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
 /********************************************************************/
 /* CivetWeb configuration defines */
 /********************************************************************/
@@ -765,33 +788,47 @@ struct mg_pollfd {
 
 #else /* defined(_WIN32) - WINDOWS vs UNIX include block */
 
-#include <arpa/inet.h>
 #include <inttypes.h>
+#include <stdint.h>
+
+typedef const void *SOCK_OPT_TYPE;
+
+#if defined(ANDROID)
+typedef unsigned short int in_port_t;
+#endif
+
+#if !defined(__ZEPHYR__)
+#include <ctype.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <arpa/inet.h>
 #include <netdb.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
-#include <stdint.h>
 #include <sys/poll.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/utsname.h>
 #include <sys/wait.h>
-typedef const void *SOCK_OPT_TYPE;
-
-#if defined(ANDROID)
-typedef unsigned short int in_port_t;
-#endif
-
 #include <dirent.h>
 #include <grp.h>
 #include <pwd.h>
 #include <unistd.h>
+#include <pthread.h>
+#endif
+
 #define vsnprintf_impl vsnprintf
 
 #if !defined(NO_SSL_DL) && !defined(NO_SSL)
 #include <dlfcn.h>
 #endif
-#include <pthread.h>
+
 #if defined(__MACH__)
 #define SSL_LIB "libssl.dylib"
 #define CRYPTO_LIB "libcrypto.dylib"
@@ -5871,6 +5908,11 @@ set_close_on_exec(int fd,
                   const struct mg_connection *conn /* may be null */,
                   struct mg_context *ctx /* may be null */)
 {
+#if defined(__ZEPHYR__)
+	(void) fd;
+	(void) conn;
+	(void) ctx;
+#else
 	if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
 		if (conn || ctx) {
 			struct mg_connection fc;
@@ -5880,6 +5922,7 @@ set_close_on_exec(int fd,
 			                strerror(ERRNO));
 		}
 	}
+#endif
 }
 
 
@@ -5893,7 +5936,9 @@ mg_start_thread(mg_thread_func_t func, void *param)
 	(void)pthread_attr_init(&attr);
 	(void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+#if defined(__ZEPHYR__)
+	pthread_attr_setstack(&attr, &civetweb_main_stack, ZEPHYR_STACK_SIZE);
+#elif defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
 	/* Compile-time option to control stack size,
 	 * e.g. -DUSE_STACK_SIZE=16384 */
 	(void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
@@ -5918,7 +5963,11 @@ mg_start_thread_with_id(mg_thread_func_t func,
 
 	(void)pthread_attr_init(&attr);
 
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+#if defined(__ZEPHYR__)
+	pthread_attr_setstack(&attr,
+			      &civetweb_worker_stacks[zephyr_worker_stack_index++],
+			      ZEPHYR_STACK_SIZE);
+#elif defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
 	/* Compile-time option to control stack size,
 	 * e.g. -DUSE_STACK_SIZE=16384 */
 	(void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
@@ -13357,8 +13406,7 @@ mg_set_handler_type(struct mg_context *phys_ctx,
 	}
 
 	tmp_rh =
-	    (struct mg_handler_info *)mg_calloc_ctx(sizeof(struct mg_handler_info),
-	                                            1,
+	    (struct mg_handler_info *)mg_calloc_ctx(1, sizeof(struct mg_handler_info),
 	                                            phys_ctx);
 	if (tmp_rh == NULL) {
 		mg_unlock_context(phys_ctx);
@@ -14306,6 +14354,7 @@ parse_port_string(const struct vec *vec, struct socket *so, int *ip_version)
 	unsigned int a, b, c, d, port;
 	int ch, len;
 	const char *cb;
+	char *endptr;
 #if defined(USE_IPV6)
 	char buf[100] = {0};
 #endif
@@ -14359,7 +14408,9 @@ parse_port_string(const struct vec *vec, struct socket *so, int *ip_version)
 		*ip_version = 4;
 #endif
 
-	} else if (sscanf(vec->ptr, "%u%n", &port, &len) == 1) {
+	} else if (is_valid_port(port = strtoul(vec->ptr, &endptr, 0))
+		   && vec->ptr != endptr) {
+		len = endptr - vec->ptr;
 		/* If only port is specified, bind to IPv4, INADDR_ANY */
 		so->lsa.sin.sin_port = htons((uint16_t)port);
 		*ip_version = 4;
@@ -14918,7 +14969,7 @@ check_acl(struct mg_context *phys_ctx, uint32_t remote_ip)
 }
 
 
-#if !defined(_WIN32)
+#if !defined(_WIN32) && !defined(__ZEPHYR__)
 static int
 set_uid_option(struct mg_context *phys_ctx)
 {
@@ -16168,6 +16219,7 @@ set_tcp_nodelay(SOCKET sock, int nodelay_on)
 }
 
 
+#if !defined(__ZEPHYR__)
 static void
 close_socket_gracefully(struct mg_connection *conn)
 {
@@ -16290,6 +16342,7 @@ close_socket_gracefully(struct mg_connection *conn)
 	closesocket(conn->client.sock);
 	conn->client.sock = INVALID_SOCKET;
 }
+#endif
 
 
 static void
@@ -16339,7 +16392,11 @@ close_connection(struct mg_connection *conn)
 	}
 #endif
 	if (conn->client.sock != INVALID_SOCKET) {
+#if defined(__ZEPHYR__)
+		closesocket(conn->client.sock);
+#else
 		close_socket_gracefully(conn);
+#endif
 		conn->client.sock = INVALID_SOCKET;
 	}
 
@@ -17996,12 +18053,14 @@ static unsigned __stdcall worker_thread(void *thread_func_param)
 static void *
 worker_thread(void *thread_func_param)
 {
+#if !defined(__ZEPHYR__)
 	struct sigaction sa;
 
 	/* Ignore SIGPIPE */
 	memset(&sa, 0, sizeof(sa));
 	sa.sa_handler = SIG_IGN;
 	sigaction(SIGPIPE, &sa, NULL);
+#endif
 
 	worker_thread_run((struct mg_connection *)thread_func_param);
 	return NULL;
@@ -18017,7 +18076,9 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 	struct socket so;
 	char src_addr[IP_ADDR_STR_LEN];
 	socklen_t len = sizeof(so.rsa);
+#if !defined(__ZEPHYR__)
 	int on = 1;
+#endif
 
 	if ((so.sock = accept(listener->sock, &so.rsa.sa, &len))
 	    == INVALID_SOCKET) {
@@ -18041,6 +18102,7 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 			                    strerror(ERRNO));
 		}
 
+#if !defined(__ZEPHYR__)
 		/* Set TCP keep-alive. This is needed because if HTTP-level
 		 * keep-alive
 		 * is enabled, and client resets the connection, server won't get
@@ -18060,6 +18122,7 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 			    __func__,
 			    strerror(ERRNO));
 		}
+#endif
 
 		/* Disable TCP Nagle's algorithm. Normally TCP packets are coalesced
 		 * to effectively fill up the underlying IP packet payload and
@@ -18229,12 +18292,14 @@ static unsigned __stdcall master_thread(void *thread_func_param)
 static void *
 master_thread(void *thread_func_param)
 {
+#if !defined(__ZEPHYR__)
 	struct sigaction sa;
 
 	/* Ignore SIGPIPE */
 	memset(&sa, 0, sizeof(sa));
 	sa.sa_handler = SIG_IGN;
 	sigaction(SIGPIPE, &sa, NULL);
+#endif
 
 	master_thread_run((struct mg_context *)thread_func_param);
 	return NULL;
@@ -18408,6 +18473,8 @@ get_system_name(char **sysName)
 #else
 	*sysName = mg_strdup("Symbian");
 #endif
+#elif defined(__ZEPHYR__)
+	*sysName = mg_strdup("Zephyr OS");
 #else
 	struct utsname name;
 	memset(&name, 0, sizeof(name));
@@ -18623,7 +18690,7 @@ mg_start(const struct mg_callbacks *callbacks,
 	    !init_ssl_ctx(ctx, NULL) ||
 #endif
 	    !set_ports_option(ctx) ||
-#if !defined(_WIN32)
+#if !defined(_WIN32) && !defined(__ZEPHYR__)
 	    !set_uid_option(ctx) ||
 #endif
 	    !set_acl_option(ctx)) {
@@ -18660,8 +18727,8 @@ mg_start(const struct mg_callbacks *callbacks,
 
 #if defined(ALTERNATIVE_QUEUE)
 	ctx->client_wait_events =
-	    (void **)mg_calloc_ctx(sizeof(ctx->client_wait_events[0]),
-	                           ctx->cfg_worker_threads,
+	    (void **)mg_calloc_ctx(ctx->cfg_worker_threads,
+	                           sizeof(ctx->client_wait_events[0]),
 	                           ctx);
 	if (ctx->client_wait_events == NULL) {
 		mg_cry_ctx_internal(ctx,
@@ -18674,8 +18741,8 @@ mg_start(const struct mg_callbacks *callbacks,
 	}
 
 	ctx->client_socks =
-	    (struct socket *)mg_calloc_ctx(sizeof(ctx->client_socks[0]),
-	                                   ctx->cfg_worker_threads,
+	    (struct socket *)mg_calloc_ctx(ctx->cfg_worker_threads,
+	                                   sizeof(ctx->client_socks[0]),
 	                                   ctx);
 	if (ctx->client_socks == NULL) {
 		mg_cry_ctx_internal(ctx,
@@ -19034,6 +19101,16 @@ mg_get_system_info(char *buffer, int buflen)
 		            (unsigned)si.dwNumberOfProcessors,
 		            (unsigned)si.dwActiveProcessorMask);
 		system_info_length += mg_str_append(&buffer, end, block);
+#elif defined(__ZEPHYR__)
+		mg_snprintf(NULL,
+		            NULL,
+		            block,
+		            sizeof(block),
+		            ",%s\"os\" : \"%s %s\"",
+		            eol,
+		            "Zephyr OS",
+		            ZEPHYR_VERSION);
+		system_info_length += mg_str_append(&buffer, end, block);
 #else
 		struct utsname name;
 		memset(&name, 0, sizeof(name));

+ 2 - 0
zephyr/module.yml

@@ -0,0 +1,2 @@
+build:
+  cmake: .