Kaynağa Gözat

First Changes for freeRTOS (#1546)

cabralfortiss 6 yıl önce
ebeveyn
işleme
7fac71131f

+ 13 - 0
CMakeLists.txt

@@ -114,6 +114,9 @@ mark_as_advanced(UA_ENABLE_UNIT_TEST_FAILURE_HOOKS)
 set(UA_VXWORKS_WRS_KERNEL OFF CACHE BOOL "Enable if you want to compile for VxWorks as kernel Module")
 mark_as_advanced(UA_VXWORKS_WRS_KERNEL)
 
+set(UA_FREERTOS OFF CACHE BOOL "Enable if you want to compile for freeRTOS")
+mark_as_advanced(UA_FREERTOS)
+
 # Build options for debugging
 option(UA_DEBUG "Enable assertions and additional functionality that should not be included in release builds" OFF)
 mark_as_advanced(UA_DEBUG)
@@ -234,6 +237,16 @@ if(NOT UA_COMPILE_AS_CXX AND (CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID
         remove_definitions(-Werror -Wpedantic -Wno-static-in-inline -fPIC)
         add_definitions(-D_WRS_KERNEL)
     endif()
+    
+    if(UA_FREERTOS)
+       SET(UA_FREERTOS_INCLUDES "" CACHE STRING "Folders to include from the freeRTOS OS")
+       include_directories(${UA_FREERTOS_INCLUDES})
+        # Disable flags for freeRTOS
+        remove_definitions(-fPIC -Wconversion )
+        add_definitions(-DUA_FREERTOS -DLWIP_TIMEVAL_PRIVATE=0 -DLWIP_COMPAT_MUTEX=0 -DLWIP_POSIX_SOCKETS_IO_NAMES=0 -mcpu=cortex-m3 -mthumb -g -Wall -O0 -specs=nano.specs 
+                        -ffunction-sections -fdata-sections  -fno-exceptions -fstack-usage -Wno-unused-variable -Wno-format -Wno-format-security -Wno-format-nonliteral)
+        list(APPEND open62541_LIBRARIES c m stdc++ supc++)
+    endif(UA_FREERTOS)
 
     # Linker
     set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # cmake sets -rdynamic by default

+ 17 - 4
include/ua_config.h.in

@@ -110,10 +110,23 @@ extern "C" {
 # include <malloc.h>
 #endif
 
-#define UA_free(ptr) free(ptr)
-#define UA_malloc(size) malloc(size)
-#define UA_calloc(num, size) calloc(num, size)
-#define UA_realloc(ptr, size) realloc(ptr, size)
+#if !defined(UA_FREERTOS)
+
+# define UA_free(ptr) free(ptr)
+# define UA_malloc(size) malloc(size)
+# define UA_calloc(num, size) calloc(num, size)
+# define UA_realloc(ptr, size) realloc(ptr, size)
+
+#else
+
+# include <FreeRTOS.h>
+
+# define UA_free(ptr) vPortFree(ptr)
+# define UA_malloc(size) pvPortMalloc(size)
+# define UA_calloc(num, size) pvPortCalloc(num, size)
+# define UA_realloc(ptr, size) pvPortRealloc(ptr, size)
+
+#endif
 
 #if defined(__GNUC__) || defined(__clang__)
 # define UA_alloca(size) __builtin_alloca (size)

+ 14 - 0
plugins/ua_clock.c

@@ -40,6 +40,10 @@
 
 #include "ua_types.h"
 
+#if defined(UA_FREERTOS)
+#include <task.h>
+#endif
+
 UA_DateTime UA_DateTime_now(void) {
 #if defined(_WIN32)
     /* Windows filetime has the same definition as UA_DateTime */
@@ -96,9 +100,19 @@ UA_DateTime UA_DateTime_nowMonotonic(void) {
     mach_port_deallocate(mach_task_self(), cclock);
     return (mts.tv_sec * UA_DATETIME_SEC) + (mts.tv_nsec / 100);
 #elif !defined(CLOCK_MONOTONIC_RAW)
+# if defined(UA_FREERTOS)
+    portTickType TaskTime = xTaskGetTickCount();
+    UA_DateTimeStruct UATime;
+    UATime.milliSec = (UA_UInt16) TaskTime;
+    struct timespec ts;
+    ts.tv_sec = UATime.milliSec/1000;
+    ts.tv_nsec = (UATime.milliSec % 1000)* 1000000;
+    return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
+# else
     struct timespec ts;
     clock_gettime(CLOCK_MONOTONIC, &ts);
     return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
+# endif
 #else
     struct timespec ts;
     clock_gettime(CLOCK_MONOTONIC_RAW, &ts);

+ 86 - 35
plugins/ua_network_tcp.c

@@ -31,11 +31,19 @@
 
 #include "ua_network_tcp.h"
 #include "ua_log_stdout.h"
-#include "queue.h"
+#include "../deps/queue.h"
 
 #include <stdio.h> // snprintf
 #include <string.h> // memset
-#include <errno.h>
+
+#if !defined(UA_FREERTOS)
+# include <errno.h>
+#else
+# define AI_PASSIVE 0x01
+# define TRUE 1
+# define FALSE 0
+# define ioctl ioctlsocket
+#endif
 
 #ifdef _WIN32
 # include <winsock2.h>
@@ -46,45 +54,68 @@
 # define OPTVAL_TYPE char
 # define ERR_CONNECTION_PROGRESS WSAEWOULDBLOCK
 # define UA_sleep_ms(X) Sleep(X)
-#else
-# define CLOSESOCKET(S) close(S)
+#else /* _WIN32 */
+# if defined(UA_FREERTOS)
+#  define UA_FREERTOS_HOSTNAME "10.200.4.114"
+static inline int gethostname_freertos(char* name, size_t len){
+  if(strlen(UA_FREERTOS_HOSTNAME) > (len))
+    return -1;
+  strcpy(name, UA_FREERTOS_HOSTNAME);
+  return 0;
+}
+#define gethostname gethostname_freertos
+#  include <lwip/tcpip.h>
+#  include <lwip/netdb.h>
+#  define CLOSESOCKET(S) lwip_close(S)
+#  define sockaddr_storage sockaddr
+#  ifdef BYTE_ORDER
+#   undef BYTE_ORDER
+#  endif
+#  define UA_sleep_ms(X) vTaskDelay(pdMS_TO_TICKS(X))
+# else /* Not freeRTOS */
+#  define CLOSESOCKET(S) close(S)
+#  include <arpa/inet.h>
+#  include <netinet/in.h>
+#  include <netdb.h>
+#  include <sys/ioctl.h>
+#  if defined(_WRS_KERNEL)
+#   include <hostLib.h>
+#   include <selectLib.h>
+#   define UA_sleep_ms(X)                            \
+    {                                                \
+    struct timespec timeToSleep;                     \
+      timeToSleep.tv_sec = X / 1000;                 \
+      timeToSleep.tv_nsec = 1000000 * (X % 1000);    \
+      nanosleep(&timeToSleep, NULL);                 \
+    }
+#  else /* defined(_WRS_KERNEL) */
+#   include <sys/select.h>
+#   define UA_sleep_ms(X) usleep(X * 1000)
+#  endif /* defined(_WRS_KERNEL) */
+# endif /* Not freeRTOS */
+
 # define SOCKET int
 # define WIN32_INT
 # define OPTVAL_TYPE int
 # define ERR_CONNECTION_PROGRESS EINPROGRESS
-# include <arpa/inet.h>
-# include <netinet/in.h>
-# ifndef _WRS_KERNEL
-#  include <sys/select.h>
-#  define UA_sleep_ms(X) usleep(X * 1000)
-# else
-#  include <hostLib.h>
-#  include <selectLib.h>
-#  define UA_sleep_ms(X)                           \
-   {                                               \
-   struct timespec timeToSleep;                    \
-   timeToSleep.tv_sec = X / 1000;                  \
-   timeToSleep.tv_nsec = 1000000 * (X % 1000);     \
-   nanosleep(&timeToSleep, NULL);                  \
-   }
-# endif
-# include <sys/ioctl.h>
+
+
 # include <fcntl.h>
 # include <unistd.h> // read, write, close
-# include <netdb.h>
+
 # ifdef __QNX__
 #  include <sys/socket.h>
 # endif
-#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
-# include <sys/param.h>
-# if defined(BSD)
-#  include<sys/socket.h>
+# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+#  include <sys/param.h>
+#  if defined(BSD)
+#   include<sys/socket.h>
+#  endif
 # endif
-#endif
-# ifndef __CYGWIN__
+# if !defined(__CYGWIN__) && !defined(UA_FREERTOS)
 #  include <netinet/tcp.h>
 # endif
-#endif
+#endif /* _WIN32 */
 
 /* unsigned int for windows and workaround to a glibc bug */
 /* Additionally if GNU_LIBRARY is not defined, it may be using
@@ -241,7 +272,7 @@ socket_set_nonblocking(SOCKET sockfd) {
     u_long iMode = 1;
     if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR)
         return UA_STATUSCODE_BADINTERNALERROR;
-#elif defined(_WRS_KERNEL)
+#elif defined(_WRS_KERNEL) || defined(UA_FREERTOS)
     int on = TRUE;
     if(ioctl(sockfd, FIONBIO, &on) < 0)
       return UA_STATUSCODE_BADINTERNALERROR;
@@ -259,7 +290,7 @@ socket_set_blocking(SOCKET sockfd) {
     u_long iMode = 0;
     if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR)
         return UA_STATUSCODE_BADINTERNALERROR;
-#elif defined(_WRS_KERNEL)
+#elif defined(_WRS_KERNEL) || defined(UA_FREERTOS)
     int on = FALSE;
     if(ioctl(sockfd, FIONBIO, &on) < 0)
       return UA_STATUSCODE_BADINTERNALERROR;
@@ -325,6 +356,7 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd,
         return UA_STATUSCODE_BADUNEXPECTEDERROR;
     }
 
+#if !defined(UA_FREERTOS)
     /* Get the peer name for logging */
     char remote_name[100];
     int res = getnameinfo((struct sockaddr*)remote,
@@ -341,7 +373,7 @@ ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd,
                                                         "getnameinfo failed with error: %s",
                                                 (int)newsockfd, errno_str));
     }
-
+#endif
     /* Allocate and initialize the connection */
     ConnectionEntry *e = (ConnectionEntry*)UA_malloc(sizeof(ConnectionEntry));
     if(!e){
@@ -387,7 +419,9 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
     /* Some Linux distributions have net.ipv6.bindv6only not activated. So
      * sockets can double-bind to IPv4 and IPv6. This leads to problems. Use
      * AF_INET6 sockets only for IPv6. */
+
     int optval = 1;
+#if !defined(UA_FREERTOS)
     if(ai->ai_family == AF_INET6 &&
        setsockopt(newsock, IPPROTO_IPV6, IPV6_V6ONLY,
                   (const char*)&optval, sizeof(optval)) == -1) {
@@ -396,7 +430,7 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
         CLOSESOCKET(newsock);
         return;
     }
-
+#endif
     if(setsockopt(newsock, SOL_SOCKET, SO_REUSEADDR,
                   (const char *)&optval, sizeof(optval)) == -1) {
         UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
@@ -405,6 +439,7 @@ addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) {
         return;
     }
 
+
     if(socket_set_nonblocking(newsock) != UA_STATUSCODE_GOOD) {
         UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
                        "Could not set the server socket to nonblocking");
@@ -461,7 +496,7 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHo
                                         layer->port);
 #endif
         du.data = (UA_Byte*)discoveryUrl;
-    }else{    
+    }else{
         char hostname[256];
         if(gethostname(hostname, 255) == 0) {
             char discoveryUrl[256];
@@ -490,7 +525,13 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHo
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_flags = AI_PASSIVE;
+#if defined(UA_FREERTOS)
+    hints.ai_protocol = IPPROTO_TCP;
+    char hostname[] = UA_FREERTOS_HOSTNAME;
+    if(getaddrinfo(hostname, portno, &hints, &res) != 0)
+#else
     if(getaddrinfo(NULL, portno, &hints, &res) != 0)
+#endif
         return UA_STATUSCODE_BADINTERNALERROR;
 
     /* There might be serveral addrinfos (for different network cards,
@@ -752,6 +793,9 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
     memset(&hints, 0, sizeof(hints));
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;
+#if defined(UA_FREERTOS)
+    hints.ai_protocol = IPPROTO_TCP;
+#endif
     char portStr[6];
 #ifndef _MSC_VER
     snprintf(portStr, 6, "%d", port);
@@ -760,9 +804,16 @@ UA_ClientConnectionTCP(UA_ConnectionConfig conf,
 #endif
     int error = getaddrinfo(hostname, portStr, &hints, &server);
     if(error != 0 || !server) {
-        UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
+#if !defined(UA_FREERTOS)
+      UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
+
                        "DNS lookup of %s failed with error %s",
                        hostname, gai_strerror(error));
+#else
+      UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_NETWORK,
+                        "DNS lookup of %s failed with error",
+                        hostname);
+#endif
         return connection;
     }
 

+ 13 - 7
plugins/ua_network_udp.c

@@ -13,17 +13,23 @@
 # include <errno.h> // errno, EINTR
 # include <fcntl.h> // fcntl
 # include <strings.h> //bzero
+
+#if defined(UA_FREERTOS)
+ # include <lwip/udp.h>
+ # include <lwip/tcpip.h>
+#else
 # ifndef _WRS_KERNEL
 #  include <sys/select.h>
 # else
-# include <selectLib.h>
+#  include <selectLib.h>
 # endif
-# include <netinet/in.h>
-# include <netinet/tcp.h>
-# include <sys/socketvar.h>
-# include <sys/ioctl.h>
-# include <unistd.h> // read, write, close
-# include <arpa/inet.h>
+#  include <netinet/in.h>
+#  include <netinet/tcp.h>
+#  include <sys/socketvar.h>
+#  include <sys/ioctl.h>
+#  include <unistd.h> // read, write, close
+#  include <arpa/inet.h>
+#endif
 #ifdef __QNX__
 #include <sys/socket.h>
 #endif

+ 1 - 1
src/client/ua_client_internal.h

@@ -7,7 +7,7 @@
 
 #include "ua_securechannel.h"
 #include "ua_client_highlevel.h"
-#include "queue.h"
+#include "../../deps/queue.h"
 
  /**************************/
  /* Subscriptions Handling */

+ 1 - 1
src/server/ua_securechannel_manager.h

@@ -12,7 +12,7 @@ extern "C" {
 #include "ua_util.h"
 #include "ua_server.h"
 #include "ua_securechannel.h"
-#include "queue.h"
+#include "../../deps/queue.h"
 
 typedef struct channel_list_entry {
     UA_SecureChannel channel;

+ 1 - 1
src/server/ua_session.h

@@ -9,7 +9,7 @@
 extern "C" {
 #endif
 
-#include "queue.h"
+#include "../deps/queue.h"
 #include "ua_securechannel.h"
 
 #define UA_MAXCONTINUATIONPOINTS 5

+ 1 - 1
src/server/ua_session_manager.h

@@ -9,7 +9,7 @@
 extern "C" {
 #endif
 
-#include "queue.h"
+#include "../../deps/queue.h"
 #include "ua_server.h"
 #include "ua_util.h"
 #include "ua_session.h"

+ 1 - 1
src/ua_securechannel.h

@@ -9,7 +9,7 @@
 extern "C" {
 #endif
 
-#include "queue.h"
+#include "../deps/queue.h"
 #include "ua_types.h"
 #include "ua_transport_generated.h"
 #include "ua_connection_internal.h"

+ 1 - 1
src/ua_util.h

@@ -12,7 +12,7 @@ extern "C" {
 #endif
 
 /* BSD Queue Macros */
-#include "queue.h"
+#include "../deps/queue.h"
 
 /* Macro-Expand for MSVC workarounds */
 #define UA_MACRO_EXPAND(x) x