Просмотр исходного кода

Adds features for creating RT OpENer

peda1337 7 лет назад
Родитель
Сommit
7466fd2722
3 измененных файлов с 97 добавлено и 14 удалено
  1. 7 0
      source/CMakeLists.txt
  2. 1 1
      source/src/ports/POSIX/CMakeLists.txt
  3. 89 13
      source/src/ports/POSIX/main.c

+ 7 - 0
source/CMakeLists.txt

@@ -60,6 +60,13 @@ if( OpENer_64_BIT_DATA_TYPES_ENABLED )
   add_definitions( -DOPENER_SUPPORT_64BIT_DATATYPES )
 endif( OpENer_64_BIT_DATA_TYPES_ENABLED )
 
+#######################################
+# OpENer RT patch	              #
+#######################################
+set( OpENer_RT OFF CACHE BOOL "Activate OpENer RT" )
+if(OpENer_RT)
+  add_definitions( -DOPENER_RT )
+endif(OpENer_RT)
 #######################################
 # OpENer tracer switches              #
 #######################################

+ 1 - 1
source/src/ports/POSIX/CMakeLists.txt

@@ -16,4 +16,4 @@ add_library( ${OpENer_PLATFORM}PLATFORM ${PLATFORM_SPEC_SRC})
 
 add_executable(OpENer main.c)
 
-target_link_libraries( OpENer CIP Utils SAMPLE_APP ENET_ENCAP PLATFORM_GENERIC ${OpENer_PLATFORM}PLATFORM ${PLATFORM_SPEC_LIBS} ${OpENer_ADD_CIP_OBJECTS} rt cap)
+target_link_libraries( OpENer CIP Utils SAMPLE_APP ENET_ENCAP PLATFORM_GENERIC ${OpENer_PLATFORM}PLATFORM ${PLATFORM_SPEC_LIBS} ${OpENer_ADD_CIP_OBJECTS} rt cap pthread)

+ 89 - 13
source/src/ports/POSIX/main.c

@@ -8,6 +8,13 @@
 #include <signal.h>
 #include <sys/capability.h>
 
+#ifdef OPENER_RT
+#include <pthread.h>
+#include <sys/mman.h>
+#include <sched.h>
+#include <limits.h>
+#endif
+
 #include "generic_networkhandler.h"
 #include "opener_api.h"
 #include "cipcommon.h"
@@ -23,6 +30,14 @@
  */
 void LeaveStack(int signal);
 
+/******************************************************************************/
+/** @brief Signal handler function for ending stack execution
+ *
+ * @param signal the signal we received
+ */
+void *executeEventLoop(
+  );
+
 /*****************************************************************************/
 /** @brief Flag indicating if the stack should end its execution
  */
@@ -36,25 +51,27 @@ int main(int argc,
   cap_value_t capabilies_list[1];
 
   capabilities = cap_get_proc();
-  if(NULL == capabilities) {
+  if (NULL == capabilities) {
     printf("Could not get capabilities\n");
     exit(0);
   }
 
   capabilies_list[0] = CAP_NET_RAW;
-  if(-1 == cap_set_flag(capabilities, CAP_EFFECTIVE, 1, capabilies_list, CAP_SET)) {
+  if (-1
+      == cap_set_flag(capabilities, CAP_EFFECTIVE, 1, capabilies_list,
+                      CAP_SET) ) {
     cap_free(capabilities);
     printf("Could not set CAP_NET_RAW capability\n");
     exit(0);
   }
 
-  if(-1 == cap_set_proc(capabilities)) {
+  if (-1 == cap_set_proc(capabilities) ) {
     cap_free(capabilities);
     printf("Could not push CAP_NET_RAW capability to process\n");
     exit(0);
   }
 
-  if(-1 == cap_free(capabilities)) {
+  if (-1 == cap_free(capabilities) ) {
     printf("Could not free capabilites value\n");
     exit(0);
   }
@@ -70,7 +87,7 @@ int main(int argc,
                                CipConnectionObjectListArrayAllocator,
                                CipConnectionObjectListArrayFree);
     /* fetch Internet address info from the platform */
-    if (kEipStatusError == ConfigureNetworkInterface(arg[1])) {
+    if (kEipStatusError == ConfigureNetworkInterface(arg[1]) ) {
       printf("Network interface %s not found.\n", arg[1]);
       exit(0);
     }
@@ -92,21 +109,70 @@ int main(int argc,
   CipStackInit(unique_connection_id);
 
   /* Setup Network Handles */
-  if ( kEipStatusOk == NetworkHandlerInitialize() ) {
+  if (kEipStatusOk == NetworkHandlerInitialize() ) {
     g_end_stack = 0;
 #ifndef WIN32
     /* register for closing signals so that we can trigger the stack to end */
     signal(SIGHUP, LeaveStack);
 #endif
+#ifdef OPENER_RT
+    /* Memory lock all*/
+    if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
+      OPENER_TRACE_ERR("mlockall failed: %m\n");
+      exit(-2);
+    }
 
-    /* The event loop. Put other processing you need done continually in here */
-    while (1 != g_end_stack) {
-      if ( kEipStatusOk != NetworkHandlerProcessOnce() ) {
-        OPENER_TRACE_ERR("Error in NetworkHandler loop! Exiting OpENer!\n");
-        break;
-      }
+    struct sched_param param;
+    pthread_attr_t attr;
+    pthread_t thread;
+    CipUint ret;
+    ret = pthread_attr_init(&attr);
+    if (ret) {
+      OPENER_TRACE_ERR("init pthread attributes failed\n");
+      exit(-2);
     }
 
+    /* Set stack size  */
+    ret = pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
+    if (ret) {
+      OPENER_TRACE_ERR("setstacksize failed\n");
+      exit(-2);
+    }
+
+    /* Set policy and priority of the thread */
+    ret = pthread_attr_setschedpolicy(&attr, SCHED_RR);
+    if (ret) {
+      OPENER_TRACE_ERR("setschedpolicy failed\n");
+      exit(-2);
+    }
+    param.sched_priority = 80;
+    ret = pthread_attr_setschedparam(&attr, &param);
+    if (ret) {
+      OPENER_TRACE_ERR("pthread setschedparam failed\n");
+      exit(-2);
+    }
+    /* scheduling parameters */
+    ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+    if (ret) {
+      OPENER_TRACE_ERR("setinheritsched failed\n");
+      exit(-2);
+    }
+
+    /* Create a thread with the specified attributes */
+    ret = pthread_create(&thread, &attr, executeEventLoop, NULL);
+    if (ret) {
+      OPENER_TRACE_ERR("create pthread failed\n");
+      exit(-2);
+    }
+
+    /* Join the thread */
+    ret = pthread_join(thread, NULL);
+    if (ret) {
+      OPENER_TRACE_ERR("join pthread failed: %m\n");
+    }
+#else
+    executeEventLoop();
+#endif
     /* clean up network state */
     NetworkHandlerFinish();
   }
@@ -117,7 +183,17 @@ int main(int argc,
 }
 
 void LeaveStack(int signal) {
-  (void) signal; /* kill unused parameter warning */
+  (void) signal;       /* kill unused parameter warning */
   OPENER_TRACE_STATE("got signal HUP\n");
   g_end_stack = 1;
 }
+
+void *executeEventLoop() {
+  /* The event loop. Put other processing you need done continually in here */
+  while (1 != g_end_stack) {
+    if (kEipStatusOk != NetworkHandlerProcessOnce() ) {
+      OPENER_TRACE_ERR("Error in NetworkHandler loop! Exiting OpENer!\n");
+      break;
+    }
+  }
+}