Runtime: Add RealTime checkbox in Linux target options to enable PREEMPT_RT scheduling.
authorEdouard Tisserant
Tue, 21 Feb 2023 11:47:11 +0100
changeset 3732 929276eea252
parent 3731 549763a28934
child 3735 c9a1a8ede8d9
Runtime: Add RealTime checkbox in Linux target options to enable PREEMPT_RT scheduling.
targets/Linux/XSD
targets/Linux/__init__.py
targets/Linux/plc_Linux_main.c
targets/beremiz.h
--- a/targets/Linux/XSD	Tue Feb 21 11:38:45 2023 +0100
+++ b/targets/Linux/XSD	Tue Feb 21 11:47:11 2023 +0100
@@ -1,6 +1,7 @@
 
                   <xsd:element name="Linux">
                     <xsd:complexType>
+                      <xsd:attribute name="RealTime" type="xsd:boolean" use="optional" default="false"/>
                       %(toolchain_gcc)s
                     </xsd:complexType>
-                  </xsd:element>
\ No newline at end of file
+                  </xsd:element>
--- a/targets/Linux/__init__.py	Tue Feb 21 11:38:45 2023 +0100
+++ b/targets/Linux/__init__.py	Tue Feb 21 11:47:11 2023 +0100
@@ -32,7 +32,11 @@
     extension = ".so"
 
     def getBuilderCFLAGS(self):
-        return toolchain_gcc.getBuilderCFLAGS(self) + ["-fPIC"]
+        additional_cflags = ["-fPIC"]
+        build_for_realtime = self.CTRInstance.GetTarget().getcontent().getRealTime()
+        if build_for_realtime:
+            additional_cflags.append("-DREALTIME_LINUX")
+        return toolchain_gcc.getBuilderCFLAGS(self) + additional_cflags
 
     def getBuilderLDFLAGS(self):
         return toolchain_gcc.getBuilderLDFLAGS(self) + ["-shared", "-lrt"]
--- a/targets/Linux/plc_Linux_main.c	Tue Feb 21 11:38:45 2023 +0100
+++ b/targets/Linux/plc_Linux_main.c	Tue Feb 21 11:47:11 2023 +0100
@@ -11,6 +11,9 @@
 #include <pthread.h>
 #include <locale.h>
 #include <semaphore.h>
+#ifdef REALTIME_LINUX
+#include <sys/mman.h>
+#endif
 
 static unsigned long __debug_tick;
 
@@ -105,10 +108,60 @@
     pthread_exit(0);
 }
 
+#define _LogError(text,...) \
+    {\
+        char mstr[256];\
+        snprintf(mstr, 255, text, ##__VA_ARGS__);\
+        LogMessage(LOG_CRITICAL, mstr, strlen(mstr));\
+    }
 #define maxval(a,b) ((a>b)?a:b)
 int startPLC(int argc,char **argv)
 {
 
+    int ret;
+	pthread_attr_t *pattr = NULL;
+
+#ifdef REALTIME_LINUX
+	struct sched_param param;
+	pthread_attr_t attr;
+
+    /* Lock memory */
+    ret = mlockall(MCL_CURRENT|MCL_FUTURE);
+    if(ret == -1) {
+		_LogError("mlockall failed: %m\n");
+		return ret;
+    }
+
+	/* Initialize pthread attributes (default values) */
+	ret = pthread_attr_init(&attr);
+	if (ret) {
+		_LogError("init pthread attributes failed\n");
+		return ret;
+	}
+
+	/* Set scheduler policy and priority of pthread */
+	ret = pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
+	if (ret) {
+		_LogError("pthread setschedpolicy failed\n");
+		return ret;
+	}
+	param.sched_priority = PLC_THREAD_PRIORITY;
+	ret = pthread_attr_setschedparam(&attr, &param);
+	if (ret) {
+		_LogError("pthread setschedparam failed\n");
+		return ret;
+	}
+
+	/* Use scheduling parameters of attr */
+	ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+	if (ret) {
+		_LogError("pthread setinheritsched failed\n");
+		return ret;
+	}
+
+	pattr = &attr;
+#endif
+
     PLC_shutdown = 0;
 
     pthread_mutex_init(&debug_wait_mutex, NULL);
@@ -119,7 +172,7 @@
     pthread_mutex_lock(&debug_wait_mutex);
     pthread_mutex_lock(&python_wait_mutex);
 
-    if(  __init(argc,argv) == 0 ){
+    if((ret = __init(argc,argv)) == 0 ){
 
         /* Signal to wakeup PLC thread when period changes */
         signal(SIGUSR1, PLCThreadSignalHandler);
@@ -132,9 +185,13 @@
         period_ns = common_ticktime__;
         clock_gettime(CLOCK_MONOTONIC, &next_abs_time);
 
-        pthread_create(&PLC_thread, NULL, (void*) &PLC_thread_proc, NULL);
+        ret = pthread_create(&PLC_thread, pattr, (void*) &PLC_thread_proc, NULL);
+		if (ret) {
+			_LogError("create pthread failed\n");
+			return ret;
+		}
     }else{
-        return 1;
+        return ret;
     }
     return 0;
 }
--- a/targets/beremiz.h	Tue Feb 21 11:38:45 2023 +0100
+++ b/targets/beremiz.h	Tue Feb 21 11:47:11 2023 +0100
@@ -32,4 +32,13 @@
 int unblock_RT_to_nRT_signal(void* handle);
 void nRT_reschedule(void);
 
+
+#ifdef REALTIME_LINUX
+
+#ifndef PLC_THREAD_PRIORITY
+#define PLC_THREAD_PRIORITY 80
 #endif
+ 
+#endif
+
+#endif