# HG changeset patch # User Edouard Tisserant # Date 1676976431 -3600 # Node ID 929276eea25290dd5dc8a20325f768e929de7ad5 # Parent 549763a289346b676aac5d58213d50969de6db9e Runtime: Add RealTime checkbox in Linux target options to enable PREEMPT_RT scheduling. diff -r 549763a28934 -r 929276eea252 targets/Linux/XSD --- 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 @@ + %(toolchain_gcc)s - \ No newline at end of file + diff -r 549763a28934 -r 929276eea252 targets/Linux/__init__.py --- 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"] diff -r 549763a28934 -r 929276eea252 targets/Linux/plc_Linux_main.c --- 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 #include #include +#ifdef REALTIME_LINUX +#include +#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, ¶m); + 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; } diff -r 549763a28934 -r 929276eea252 targets/beremiz.h --- 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