Merged from default wxPython4
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Tue, 28 Feb 2023 15:08:43 +0100
branchwxPython4
changeset 3738 9ce94d0d3764
parent 3730 87dac789bdaf (current diff)
parent 3737 0c06de0a39b5 (diff)
child 3739 99263915a91d
Merged from default
Beremiz_service.py
--- a/Beremiz_service.py	Tue Feb 28 15:06:13 2023 +0100
+++ b/Beremiz_service.py	Tue Feb 28 15:08:43 2023 +0100
@@ -186,6 +186,12 @@
     return os.path.join(beremiz_dir, *args)
 
 
+import locale
+# Matiec's standard library relies on libC's locale-dependent
+# string to/from number convertions, but IEC-61131 counts
+# on '.' for decimal point. Therefore locale is reset to "C" */
+locale.setlocale(locale.LC_NUMERIC, "C")
+
 def SetupI18n():
     # Get folder containing translation files
     localedir = os.path.join(beremiz_dir, "locale")
@@ -206,7 +212,6 @@
     # Define locale domain
     loc.AddCatalog(domain)
 
-    import locale
     global default_locale
     default_locale = locale.getdefaultlocale()[1]
 
--- a/modbus/mb_runtime.c	Tue Feb 28 15:06:13 2023 +0100
+++ b/modbus/mb_runtime.c	Tue Feb 28 15:08:43 2023 +0100
@@ -373,6 +373,14 @@
 		clock_gettime(CLOCK_MONOTONIC, &cur_time);
 		fprintf(stderr, "Modbus client thread (%%d) - new cycle (%%ld:%%ld)!\n", client_node_id, cur_time.tv_sec, cur_time.tv_nsec);
 		*/
+		
+		/* Variable use to specify delay to introduce between any two consecutive requests we send out to the same client
+		 * Initially set to 0 since we don't want to introduce a delay before the very first request.
+		 */
+		struct timespec inter_request_delay;
+		inter_request_delay.tv_sec  = 0;
+		inter_request_delay.tv_nsec = 0;
+		
 		int req;
 		for (req=0; req < NUMBER_OF_CLIENT_REQTS; req ++){
 			/* just do the requests belonging to the client */
@@ -392,6 +400,14 @@
             fprintf(stderr, "Modbus client thread (%%d): RUNNING Modbus request %%d  (periodic = %%d  flag_exec_req = %%d)\n", 
                     client_node_id, req, client_nodes[client_requests[req].client_node_id].periodic_act, client_requests[req].flag_exec_req );
             */
+			
+			/* Insert a delay between any two consecutive requests to the same client
+			 * Needed because some clients will ignore our requests if we send them out too fast.
+			 *
+			 * Note that since we don't want to insert a delay before the very first request we will send, the inter_request_delay variable
+			 * is first initialised to 0. It will be set to the correct delay after the first (and second, third, etc..) request has completed.
+			 */
+			clock_nanosleep(CLOCK_MONOTONIC, 0 /* relative sleep */, &inter_request_delay, NULL);
             
 			int res_tmp = __execute_mb_request(req);
 			client_requests[req].tn_error_code = 0; // assume success
@@ -449,7 +465,7 @@
             client_requests[req].flag_mb_error_code = client_requests[req].mb_error_code;
             client_requests[req].flag_tn_error_code = client_requests[req].tn_error_code;
             
-            /* We have just finished excuting a client transcation request.
+            /* We have just finished executing a client transaction request.
              * If the current cycle was activated by user request we reset the flag used to ask to run it
              */
             if (0 != client_requests[req].flag_exec_req) {
@@ -457,6 +473,12 @@
                 client_requests[req].flag_exec_started = 0;   
             }
             
+            /* We have just finished executing a client transaction request.
+             * Set the inter request delay before we send the next request. Value of delay is set by user in beremiz GUI
+             */
+            inter_request_delay.tv_sec  =  client_nodes[client_node_id].req_delay / 1000; /* ms to seconds */
+            inter_request_delay.tv_nsec = (client_nodes[client_node_id].req_delay %% 1000) * 1000 * 1000; /* ms to ns */
+            
             //fprintf(stderr, "Modbus plugin: RUNNING<---> of Modbus request %%d  (periodic = %%d  flag_exec_req = %%d)\n", 
             //        req, client_nodes[client_requests[req].client_node_id].periodic_act, client_requests[req].flag_exec_req );
         }
@@ -956,7 +978,7 @@
  * running (i.e. before or after __init_() ets called)! 
  * 
  * The following functions are never called from other C code. They are 
- * called instead from the python code in runtime/Modbus_config.py, that
+ * called instead from the python code in modbus/web_settings.py, that
  * implements the web server extension for configuring Modbus parameters.
  */
 
@@ -974,7 +996,7 @@
 
 
 
-/* NOTE: We could have the python code in runtime/Modbus_config.py
+/* NOTE: We could have the python code in modbus/web_settings.py
  *       directly access the server_node_t and client_node_t structures,
  *       however this would create a tight coupling between these two
  *       disjoint pieces of code.
@@ -1017,6 +1039,7 @@
 int                __modbus_get_ClientNode_parity     (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.parity;   }
 int                __modbus_get_ClientNode_stop_bits  (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.stop_bits;}
 u64                __modbus_get_ClientNode_comm_period(int nodeid)  {return client_nodes[nodeid].comm_period;                    }
+u64                __modbus_get_ClientNode_req_delay  (int nodeid)  {return client_nodes[nodeid].req_delay;                      }
 const char *       __modbus_get_ClientNode_addr_type  (int nodeid)  {return addr_type_str[client_nodes[nodeid].node_address.naf];}
                                                                                                                         
 const char *       __modbus_get_ServerNode_config_name(int nodeid)  {return server_nodes[nodeid].config_name;                    }
@@ -1037,6 +1060,7 @@
 void __modbus_set_ClientNode_parity     (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.parity    = value;}
 void __modbus_set_ClientNode_stop_bits  (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.stop_bits = value;}
 void __modbus_set_ClientNode_comm_period(int nodeid, u64          value)  {client_nodes[nodeid].comm_period                     = value;}
+void __modbus_set_ClientNode_req_delay  (int nodeid, u64          value)  {client_nodes[nodeid].req_delay                       = value;}
                                                                                                                         
 
 void __modbus_set_ServerNode_host       (int nodeid, const char * value)  {if (strcmp(value,"#ANY#")==0) value = "";
--- a/modbus/mb_runtime.h	Tue Feb 28 15:06:13 2023 +0100
+++ b/modbus/mb_runtime.h	Tue Feb 28 15:08:43 2023 +0100
@@ -124,7 +124,8 @@
 	    node_addr_t	node_address;
 	    int		mb_nd;      // modbus library node used for this client
 	    int		init_state; // store how far along the client's initialization has progressed
-	    u64		comm_period;// period to use when periodically sending requests to remote server
+	    u64		comm_period;// period to use when periodically sending requests to remote server (in ms)
+	    u64		req_delay;  // delay between 2 consecutive requests sent to remote slaves/server (in ms)
 	    int		prev_error; // error code of the last printed error message (0 when no error) 
 	    pthread_t   thread_id;  // thread handling all communication for this client node
 	    pthread_t	timer_thread_id;  // thread handling periodical timer for this client node
--- a/modbus/mb_utils.py	Tue Feb 28 15:06:13 2023 +0100
+++ b/modbus/mb_utils.py	Tue Feb 28 15:08:43 2023 +0100
@@ -140,10 +140,10 @@
     params: child - the correspondent subplugin in Beremiz
     """
     node_init_template = '''/*node %(locnodestr)s*/
-{"%(locnodestr)s", "%(config_name)s", "%(device)s", "", {naf_rtu, {.rtu = {NULL, %(baud)s /*baud*/, %(parity)s /*parity*/, 8 /*data bits*/, %(stopbits)s, 0 /* ignore echo */}}}, -1 /* mb_nd */, 0 /* init_state */, %(coms_period)s /* communication period */}'''
-
-    location = ".".join(map(str, child.GetCurrentLocation()))
-    config_name, device, baud, parity, stopbits, coms_period = GetCTVals(child, range(6))
+{"%(locnodestr)s", "%(config_name)s", "%(device)s", "", {naf_rtu, {.rtu = {NULL, %(baud)s /*baud*/, %(parity)s /*parity*/, 8 /*data bits*/, %(stopbits)s, 0 /* ignore echo */}}}, -1 /* mb_nd */, 0 /* init_state */, %(coms_period)s /* communication period  (ms)*/, %(coms_delay)s /* inter request delay (ms)*/, 0 /* prev_error */}'''
+
+    location = ".".join(map(str, child.GetCurrentLocation()))
+    config_name, device, baud, parity, stopbits, coms_period, coms_delay = GetCTVals(child, range(7))
 
     node_dict = {"locnodestr": location,
                  "config_name": config_name,
@@ -151,7 +151,8 @@
                  "baud": baud,
                  "parity": modbus_serial_parity_dict[parity],
                  "stopbits": stopbits,
-                 "coms_period": coms_period}
+                 "coms_period": coms_period,
+                 "coms_delay": coms_delay}
     return node_init_template % node_dict
 
 
@@ -161,16 +162,17 @@
     params: child - the correspondent subplugin in Beremiz
     """
     node_init_template = '''/*node %(locnodestr)s*/
-{"%(locnodestr)s", "%(config_name)s", "%(host)s", "%(port)s", {naf_tcp, {.tcp = {NULL, NULL, DEF_CLOSE_ON_SILENCE}}}, -1 /* mb_nd */, 0 /* init_state */, %(coms_period)s /* communication period */, 0 /* prev_error */}'''
-
-    location = ".".join(map(str, child.GetCurrentLocation()))
-    config_name, host, port, coms_period = GetCTVals(child, range(4))
+{"%(locnodestr)s", "%(config_name)s", "%(host)s", "%(port)s", {naf_tcp, {.tcp = {NULL, NULL, DEF_CLOSE_ON_SILENCE}}}, -1 /* mb_nd */, 0 /* init_state */, %(coms_period)s /* communication period (ms)*/, %(coms_delay)s /* inter request delay (ms)*/, 0 /* prev_error */}'''
+
+    location = ".".join(map(str, child.GetCurrentLocation()))
+    config_name, host, port, coms_period, coms_delay = GetCTVals(child, range(5))
 
     node_dict = {"locnodestr": location,
                  "config_name": config_name,
                  "host": host,
                  "port": port,
-                 "coms_period": coms_period}
+                 "coms_period": coms_period,
+                 "coms_delay": coms_delay}
     return node_init_template % node_dict
 
 
--- a/modbus/modbus.py	Tue Feb 28 15:06:13 2023 +0100
+++ b/modbus/modbus.py	Tue Feb 28 15:08:43 2023 +0100
@@ -319,11 +319,19 @@
                 </xsd:restriction>
             </xsd:simpleType>
           </xsd:attribute>
+          <xsd:attribute name="Request_Delay_in_ms" use="optional" default="0">
+            <xsd:simpleType>
+                <xsd:restriction base="xsd:integer">
+                    <xsd:minInclusive value="0"/>
+                    <xsd:maxInclusive value="2147483647"/>
+                </xsd:restriction>
+            </xsd:simpleType>
+          </xsd:attribute>
         </xsd:complexType>
       </xsd:element>
     </xsd:schema>
     """
-    # NOTE: Max value of 2147483647 (i32_max) for Invocation_Rate_in_ms
+    # NOTE: Max value of 2147483647 (i32_max) for Invocation_Rate_in_ms and Request_Delay_in_ms
     # corresponds to aprox 25 days.
     CTNChildrenTypes = [("ModbusRequest", _RequestPlug, "Request")]
     # TODO: Replace with CTNType !!!
@@ -565,11 +573,19 @@
                 </xsd:restriction>
             </xsd:simpleType>
           </xsd:attribute>
+          <xsd:attribute name="Request_Delay_in_ms" use="optional" default="0">
+            <xsd:simpleType>
+                <xsd:restriction base="xsd:integer">
+                    <xsd:minInclusive value="0"/>
+                    <xsd:maxInclusive value="2147483647"/>
+                </xsd:restriction>
+            </xsd:simpleType>
+          </xsd:attribute>
         </xsd:complexType>
       </xsd:element>
     </xsd:schema>
     """
-    # NOTE: Max value of 2147483647 (i32_max) for Invocation_Rate_in_ms
+    # NOTE: Max value of 2147483647 (i32_max) for Invocation_Rate_in_ms and Request_Delay_in_ms
     # corresponds to aprox 25 days.
     CTNChildrenTypes = [("ModbusRequest", _RequestPlug, "Request")]
     # TODO: Replace with CTNType !!!
--- a/modbus/web_settings.py	Tue Feb 28 15:06:13 2023 +0100
+++ b/modbus/web_settings.py	Tue Feb 28 15:08:43 2023 +0100
@@ -149,7 +149,8 @@
     #                                                                       annotate.Integer, ...)
     ("host"             , _("Remote IP Address")     , ctypes.c_char_p,    MB_StrippedString),
     ("port"             , _("Remote Port Number")    , ctypes.c_char_p,    MB_StrippedString),
-    ("comm_period"      , _("Invocation Rate (ms)")  , ctypes.c_ulonglong, annotate.Integer )
+    ("comm_period"      , _("Invocation Rate (ms)")  , ctypes.c_ulonglong, annotate.Integer ),
+    ("req_delay"        , _("Request Delay (ms)")    , ctypes.c_ulonglong, annotate.Integer )
     ]
 
 RTUclient_parameters = [                                                   
@@ -161,7 +162,8 @@
     ("baud"             , _("Baud Rate")             , ctypes.c_int,       MB_Baud         ),
     ("parity"           , _("Parity")                , ctypes.c_int,       MB_Parity       ),
     ("stop_bits"        , _("Stop Bits")             , ctypes.c_int,       MB_StopBits     ),
-    ("comm_period"      , _("Invocation Rate (ms)")  , ctypes.c_ulonglong, annotate.Integer)
+    ("comm_period"      , _("Invocation Rate (ms)")  , ctypes.c_ulonglong, annotate.Integer),
+    ("req_delay"        , _("Request Delay (ms)")    , ctypes.c_ulonglong, annotate.Integer)
     ]
 
 TCPserver_parameters = [                                                   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/widgetlib/bool_indicator.svg	Tue Feb 28 15:08:43 2023 +0100
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 210 297"
+   version="1.1"
+   id="svg2283"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
+   sodipodi:docname="bool_indicator.svg">
+  <defs
+     id="defs2277" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="462.51005"
+     inkscape:cy="731.33409"
+     inkscape:document-units="mm"
+     inkscape:current-layer="g72"
+     showgrid="false"
+     inkscape:window-width="1850"
+     inkscape:window-height="1036"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     borderlayer="false" />
+  <metadata
+     id="metadata2280">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="g72"
+     transform="matrix(2.7990784,0,0,2.7990784,-196.86918,-137.27685)"
+     style="stroke-width:0.35726044"
+     inkscape:label="HMI:Switch">
+    <text
+       id="text62"
+       y="83.254463"
+       x="112.6369"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.09452516px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       xml:space="preserve"
+       inkscape:label="true"><tspan
+         style="fill:#008000;stroke-width:0.09452516px"
+         y="83.254463"
+         x="112.6369"
+         id="tspan60"
+         sodipodi:role="line">✔</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.09452516px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="112.6369"
+       y="83.254463"
+       id="text66"
+       inkscape:label="false"><tspan
+         sodipodi:role="line"
+         id="tspan64"
+         x="112.6369"
+         y="83.254463"
+         style="fill:#ff0000;stroke-width:0.09452516px">✕</tspan></text>
+  </g>
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svghmi/widgetlib/simple_text_display.svg	Tue Feb 28 15:08:43 2023 +0100
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 210 297"
+   version="1.1"
+   id="svg2283"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
+   sodipodi:docname="display.svg">
+  <defs
+     id="defs2277" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.979899"
+     inkscape:cx="272.49799"
+     inkscape:cy="696.53067"
+     inkscape:document-units="mm"
+     inkscape:current-layer="svg2283"
+     showgrid="false"
+     inkscape:window-width="1850"
+     inkscape:window-height="1036"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     borderlayer="false" />
+  <metadata
+     id="metadata2280">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-weight:normal;font-size:12.10321426px;line-height:125%;font-family:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#ff8c00;fill-opacity:1;stroke:none;stroke-width:0.07564509px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     x="105.0444"
+     y="118.41108"
+     id="text432"
+     inkscape:label="HMI:Display"><tspan
+       sodipodi:role="line"
+       id="tspan430"
+       x="105.0444"
+       y="118.41108"
+       style="text-align:end;text-anchor:end;fill:#ff8c00;stroke-width:0.07564509px">value</tspan></text>
+</svg>
--- a/targets/Linux/XSD	Tue Feb 28 15:06:13 2023 +0100
+++ b/targets/Linux/XSD	Tue Feb 28 15:08:43 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 28 15:06:13 2023 +0100
+++ b/targets/Linux/__init__.py	Tue Feb 28 15:08:43 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 28 15:06:13 2023 +0100
+++ b/targets/Linux/plc_Linux_main.c	Tue Feb 28 15:08:43 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,59 @@
     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)
 {
-    setlocale(LC_NUMERIC, "C");
+
+    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;
 
@@ -120,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);
@@ -133,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/Win32/plc_Win32_main.c	Tue Feb 28 15:06:13 2023 +0100
+++ b/targets/Win32/plc_Win32_main.c	Tue Feb 28 15:08:43 2023 +0100
@@ -82,7 +82,6 @@
 {
 	unsigned long thread_id = 0;
     BOOL tmp;
-    setlocale(LC_NUMERIC, "C");
 
     debug_sem = CreateSemaphore(
                             NULL,           // default security attributes
--- a/targets/beremiz.h	Tue Feb 28 15:06:13 2023 +0100
+++ b/targets/beremiz.h	Tue Feb 28 15:08:43 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
--- a/targets/plc_debug.c	Tue Feb 28 15:06:13 2023 +0100
+++ b/targets/plc_debug.c	Tue Feb 28 15:08:43 2023 +0100
@@ -270,7 +270,7 @@
                 default:
                     break;
                 }
-                force_list_apply_cursor++;                                                      \
+                force_list_apply_cursor++;
             }
 
             /* Reset buffer cursor */