--- a/targets/Xenomai/plc_Xenomai_main.c Thu Jul 29 11:59:28 2021 +0200
+++ b/targets/Xenomai/plc_Xenomai_main.c Mon Aug 16 22:49:08 2021 +0200
@@ -18,27 +18,11 @@
unsigned int PLC_state = 0;
#define PLC_STATE_TASK_CREATED 1
-#define PLC_STATE_DEBUG_FILE_OPENED 2
-#define PLC_STATE_DEBUG_PIPE_CREATED 4
-#define PLC_STATE_PYTHON_FILE_OPENED 8
-#define PLC_STATE_PYTHON_PIPE_CREATED 16
-#define PLC_STATE_WAITDEBUG_FILE_OPENED 32
-#define PLC_STATE_WAITDEBUG_PIPE_CREATED 64
-#define PLC_STATE_WAITPYTHON_FILE_OPENED 128
-#define PLC_STATE_WAITPYTHON_PIPE_CREATED 256
-#define PLC_STATE_SVGHMI_FILE_OPENED 512
-#define PLC_STATE_SVGHMI_PIPE_CREATED 1024
-
-#define WAITDEBUG_PIPE_DEVICE "/dev/rtp0"
-#define WAITDEBUG_PIPE_MINOR 0
-#define DEBUG_PIPE_DEVICE "/dev/rtp1"
-#define DEBUG_PIPE_MINOR 1
-#define WAITPYTHON_PIPE_DEVICE "/dev/rtp2"
-#define WAITPYTHON_PIPE_MINOR 2
-#define PYTHON_PIPE_DEVICE "/dev/rtp3"
-#define PYTHON_PIPE_MINOR 3
-#define SVGHMI_PIPE_DEVICE "/dev/rtp4"
-#define SVGHMI_PIPE_MINOR 4
+#define PLC_STATE_DEBUG_PIPE_CREATED 2
+#define PLC_STATE_PYTHON_PIPE_CREATED 8
+#define PLC_STATE_WAITDEBUG_PIPE_CREATED 16
+#define PLC_STATE_WAITPYTHON_PIPE_CREATED 32
+
#define PIPE_SIZE 1
// rt-pipes commands
@@ -68,16 +52,36 @@
}
RT_TASK PLC_task;
-RT_PIPE WaitDebug_pipe;
-RT_PIPE WaitPython_pipe;
-RT_PIPE Debug_pipe;
-RT_PIPE Python_pipe;
-RT_PIPE svghmi_pipe;
-int WaitDebug_pipe_fd;
-int WaitPython_pipe_fd;
-int Debug_pipe_fd;
-int Python_pipe_fd;
-int svghmi_pipe_fd;
+void *WaitDebug_handle;
+void *WaitPython_handle;
+void *Debug_handle;
+void *Python_handle;
+void *svghmi_handle;
+
+struct RT_to_nRT_signal_s {
+ int used;
+ RT_PIPE pipe;
+ int pipe_fd;
+ char *name;
+};
+typedef struct RT_to_nRT_signal_s RT_to_nRT_signal_t;
+
+#define max_RT_to_nRT_signals 16
+
+static RT_to_nRT_signal_t RT_to_nRT_signal_pool[max_RT_to_nRT_signals];
+
+int recv_RT_to_nRT_signal(void* handle, char* payload){
+ RT_to_nRT_signal_t *sig = (RT_to_nRT_signal_t*)handle;
+ if(!sig->used) return -EINVAL;
+ return read(sig->pipe_fd, payload, 1);
+}
+
+int send_RT_to_nRT_signal(void* handle, char payload){
+ RT_to_nRT_signal_t *sig = (RT_to_nRT_signal_t*)handle;
+ if(!sig->used) return -EINVAL;
+ return rt_pipe_write(&sig->pipe, &payload, 1, P_NORMAL);
+}
+
int PLC_shutdown = 0;
@@ -102,17 +106,85 @@
{
/* explicitely finish python thread */
char msg = PYTHON_FINISH;
- rt_pipe_write(&WaitPython_pipe, &msg, sizeof(msg), P_NORMAL);
+ send_RT_to_nRT_signal(WaitPython_handle, msg);
}
{
/* explicitely finish debug thread */
char msg = DEBUG_FINISH;
- rt_pipe_write(&WaitDebug_pipe, &msg, sizeof(msg), P_NORMAL);
+ send_RT_to_nRT_signal(WaitDebug_handle, msg);
}
}
static unsigned long __debug_tick;
+#define _LogAndReturnNull(text) \
+ {\
+ char mstr[256] = text " for ";\
+ strncat(mstr, name, 255);\
+ LogMessage(LOG_CRITICAL, mstr, strlen(mstr));\
+ return NULL;\
+ }
+
+void *create_RT_to_nRT_signal(char* name){
+ int new_index = -1;
+ RT_to_nRT_signal_t *sig;
+ char pipe_dev[64];
+
+ /* find a free slot */
+ for(int i=0; i < max_RT_to_nRT_signals; i++){
+ sig = &RT_to_nRT_signal_pool[i];
+ if(!sig->used){
+ new_index = i;
+ break;
+ }
+ }
+
+ /* fail if none found */
+ if(new_index == -1) {
+ _LogAndReturnNull("Maximum count of RT-PIPE reached while creating pipe");
+ }
+
+ /* create rt pipe */
+ if(rt_pipe_create(&sig->pipe, name, new_index, PIPE_SIZE) < 0){
+ _LogAndReturnNull("Failed opening real-time end of RT-PIPE");
+ }
+
+ /* open pipe's userland */
+ snprintf(pipe_dev, 64, "/dev/rtp%d", new_index);
+ if((sig->pipe_fd = open(pipe_dev, O_RDWR)) == -1){
+ rt_pipe_delete(&sig->pipe);
+ _LogAndReturnNull("Failed opening non-real-time end of RT-PIPE");
+ }
+
+ sig->used = 1;
+ sig->name = name;
+
+ return sig;
+}
+
+void delete_RT_to_nRT_signal(void* handle){
+ RT_to_nRT_signal_t *sig = (RT_to_nRT_signal_t*)handle;
+
+ if(!sig->used) return;
+
+ rt_pipe_delete(&sig->pipe);
+
+ close(sig->pipe_fd);
+
+ sig->used = 0;
+}
+
+int wait_RT_to_nRT_signal(void* handle){
+ char cmd;
+ int ret = recv_RT_to_nRT_signal(handle, &cmd);
+ return (ret == 1) ? 0 : ((ret == 0) ? ENODATA : -ret);
+}
+
+int unblock_RT_to_nRT_signal(void* handle){
+ int ret = send_RT_to_nRT_signal(handle, 0);
+ return (ret == 1) ? 0 : ((ret == 0) ? EINVAL : -ret);
+}
+
void PLC_cleanup_all(void)
{
if (PLC_state & PLC_STATE_TASK_CREATED) {
@@ -120,56 +192,25 @@
PLC_state &= ~PLC_STATE_TASK_CREATED;
}
- if (PLC_state & PLC_STATE_SVGHMI_PIPE_CREATED) {
- rt_pipe_delete(&svghmi_pipe);
- PLC_state &= ~PLC_STATE_SVGHMI_PIPE_CREATED;
- }
-
- if (PLC_state & PLC_STATE_SVGHMI_FILE_OPENED) {
- close(svghmi_pipe_fd);
- PLC_state &= ~PLC_STATE_SVGHMI_FILE_OPENED;
- }
-
if (PLC_state & PLC_STATE_WAITDEBUG_PIPE_CREATED) {
- rt_pipe_delete(&WaitDebug_pipe);
+ delete_RT_to_nRT_signal(WaitDebug_handle);
PLC_state &= ~PLC_STATE_WAITDEBUG_PIPE_CREATED;
}
- if (PLC_state & PLC_STATE_WAITDEBUG_FILE_OPENED) {
- close(WaitDebug_pipe_fd);
- PLC_state &= ~PLC_STATE_WAITDEBUG_FILE_OPENED;
- }
-
if (PLC_state & PLC_STATE_WAITPYTHON_PIPE_CREATED) {
- rt_pipe_delete(&WaitPython_pipe);
+ delete_RT_to_nRT_signal(WaitPython_handle);
PLC_state &= ~PLC_STATE_WAITPYTHON_PIPE_CREATED;
}
- if (PLC_state & PLC_STATE_WAITPYTHON_FILE_OPENED) {
- close(WaitPython_pipe_fd);
- PLC_state &= ~PLC_STATE_WAITPYTHON_FILE_OPENED;
- }
-
if (PLC_state & PLC_STATE_DEBUG_PIPE_CREATED) {
- rt_pipe_delete(&Debug_pipe);
+ delete_RT_to_nRT_signal(Debug_handle);
PLC_state &= ~PLC_STATE_DEBUG_PIPE_CREATED;
}
- if (PLC_state & PLC_STATE_DEBUG_FILE_OPENED) {
- close(Debug_pipe_fd);
- PLC_state &= ~PLC_STATE_DEBUG_FILE_OPENED;
- }
-
if (PLC_state & PLC_STATE_PYTHON_PIPE_CREATED) {
- rt_pipe_delete(&Python_pipe);
+ delete_RT_to_nRT_signal(Python_handle);
PLC_state &= ~PLC_STATE_PYTHON_PIPE_CREATED;
}
-
- if (PLC_state & PLC_STATE_PYTHON_FILE_OPENED) {
- close(Python_pipe_fd);
- PLC_state &= ~PLC_STATE_PYTHON_FILE_OPENED;
- }
-
}
int stopPLC()
@@ -213,59 +254,28 @@
/* no memory swapping for that process */
mlockall(MCL_CURRENT | MCL_FUTURE);
+
+ /* memory initialization */
PLC_shutdown = 0;
-
- /*** RT Pipes creation and opening ***/
+ bzero(RT_to_nRT_signal_pool, sizeof(RT_to_nRT_signal_pool));
+
+ /*** RT Pipes ***/
/* create Debug_pipe */
- if(rt_pipe_create(&Debug_pipe, "Debug_pipe", DEBUG_PIPE_MINOR, PIPE_SIZE) < 0)
- _startPLCLog(FO "Debug_pipe real-time end");
+ if(Debug_handle = create_RT_to_nRT_signal("Debug_pipe")) goto error;
PLC_state |= PLC_STATE_DEBUG_PIPE_CREATED;
-
- /* open Debug_pipe*/
- if((Debug_pipe_fd = open(DEBUG_PIPE_DEVICE, O_RDWR)) == -1)
- _startPLCLog(FO DEBUG_PIPE_DEVICE);
- PLC_state |= PLC_STATE_DEBUG_FILE_OPENED;
-
+
/* create Python_pipe */
- if(rt_pipe_create(&Python_pipe, "Python_pipe", PYTHON_PIPE_MINOR, PIPE_SIZE) < 0)
- _startPLCLog(FO "Python_pipe real-time end");
+ if(Python_handle = create_RT_to_nRT_signal("Python_pipe")) goto error;
PLC_state |= PLC_STATE_PYTHON_PIPE_CREATED;
- /* open Python_pipe*/
- if((Python_pipe_fd = open(PYTHON_PIPE_DEVICE, O_RDWR)) == -1)
- _startPLCLog(FO PYTHON_PIPE_DEVICE);
- PLC_state |= PLC_STATE_PYTHON_FILE_OPENED;
-
/* create WaitDebug_pipe */
- if(rt_pipe_create(&WaitDebug_pipe, "WaitDebug_pipe", WAITDEBUG_PIPE_MINOR, PIPE_SIZE) < 0)
- _startPLCLog(FO "WaitDebug_pipe real-time end");
+ if(WaitDebug_handle = create_RT_to_nRT_signal("WaitDebug_pipe")) goto error;
PLC_state |= PLC_STATE_WAITDEBUG_PIPE_CREATED;
- /* open WaitDebug_pipe*/
- if((WaitDebug_pipe_fd = open(WAITDEBUG_PIPE_DEVICE, O_RDWR)) == -1)
- _startPLCLog(FO WAITDEBUG_PIPE_DEVICE);
- PLC_state |= PLC_STATE_WAITDEBUG_FILE_OPENED;
-
/* create WaitPython_pipe */
- if(rt_pipe_create(&WaitPython_pipe, "WaitPython_pipe", WAITPYTHON_PIPE_MINOR, PIPE_SIZE) < 0)
- _startPLCLog(FO "WaitPython_pipe real-time end");
+ if(WaitPython_handle = create_RT_to_nRT_signal("WaitPython_pipe")) goto error;
PLC_state |= PLC_STATE_WAITPYTHON_PIPE_CREATED;
- /* open WaitPython_pipe*/
- if((WaitPython_pipe_fd = open(WAITPYTHON_PIPE_DEVICE, O_RDWR)) == -1)
- _startPLCLog(FO WAITPYTHON_PIPE_DEVICE);
- PLC_state |= PLC_STATE_WAITPYTHON_FILE_OPENED;
-
- /* create svghmi_pipe */
- if(rt_pipe_create(&svghmi_pipe, "svghmi_pipe", SVGHMI_PIPE_MINOR, PIPE_SIZE) < 0)
- _startPLCLog(FO "svghmi_pipe real-time end");
- PLC_state |= PLC_STATE_SVGHMI_PIPE_CREATED;
-
- /* open svghmi_pipe*/
- if((svghmi_pipe_fd = open(SVGHMI_PIPE_DEVICE, O_RDWR)) == -1)
- _startPLCLog(FO SVGHMI_PIPE_DEVICE);
- PLC_state |= PLC_STATE_SVGHMI_FILE_OPENED;
-
/*** create PLC task ***/
if(rt_task_create(&PLC_task, "PLC_task", 0, 50, T_JOINABLE))
_startPLCLog("Failed creating PLC task");
@@ -309,7 +319,7 @@
DEBUG_BUSY, DEBUG_FREE) == DEBUG_BUSY){
char msg = DEBUG_UNLOCK;
/* signal to NRT for wakeup */
- rt_pipe_write(&Debug_pipe, &msg, sizeof(msg), P_NORMAL);
+ send_RT_to_nRT_signal(Debug_handle, msg);
}
}
@@ -321,8 +331,8 @@
int res;
if (PLC_shutdown) return -1;
/* Wait signal from PLC thread */
- res = read(WaitDebug_pipe_fd, &cmd, sizeof(cmd));
- if (res == sizeof(cmd) && cmd == DEBUG_PENDING_DATA){
+ recv_RT_to_nRT_signal(WaitDebug_handle, &cmd);
+ if (res == 1 && cmd == DEBUG_PENDING_DATA){
*tick = __debug_tick;
return 0;
}
@@ -337,7 +347,7 @@
/* remember tick */
__debug_tick = __tick;
/* signal debugger thread it can read data */
- rt_pipe_write(&WaitDebug_pipe, &msg, sizeof(msg), P_NORMAL);
+ send_RT_to_nRT_signal(WaitDebug_handle, msg);
}
int suspendDebug(int disable)
@@ -349,7 +359,7 @@
DEBUG_FREE,
DEBUG_BUSY) != DEBUG_FREE &&
cmd == DEBUG_UNLOCK){
- if(read(Debug_pipe_fd, &cmd, sizeof(cmd)) != sizeof(cmd)){
+ if(recv_RT_to_nRT_signal(Debug_handle, &cmd) != 1){
return -1;
}
}
@@ -373,7 +383,7 @@
char cmd;
if (PLC_shutdown) return -1;
/* Wait signal from PLC thread */
- if(read(WaitPython_pipe_fd, &cmd, sizeof(cmd))==sizeof(cmd) && cmd==PYTHON_PENDING_COMMAND){
+ if(recv_RT_to_nRT_signal(WaitPython_handle, &cmd) == 1 && cmd==PYTHON_PENDING_COMMAND){
return 0;
}
return -1;
@@ -383,7 +393,7 @@
void UnBlockPythonCommands(void)
{
char msg = PYTHON_PENDING_COMMAND;
- rt_pipe_write(&WaitPython_pipe, &msg, sizeof(msg), P_NORMAL);
+ send_RT_to_nRT_signal(WaitPython_handle, msg);
}
int TryLockPython(void)
@@ -404,7 +414,7 @@
PYTHON_FREE,
PYTHON_BUSY) != PYTHON_FREE &&
cmd == UNLOCK_PYTHON){
- read(Python_pipe_fd, &cmd, sizeof(cmd));
+ recv_RT_to_nRT_signal(Python_handle, &cmd);
}
}
@@ -416,23 +426,11 @@
PYTHON_FREE) == PYTHON_BUSY){
if(rt_task_self()){/*is that the real time task ?*/
char cmd = UNLOCK_PYTHON;
- rt_pipe_write(&Python_pipe, &cmd, sizeof(cmd), P_NORMAL);
+ send_RT_to_nRT_signal(Python_handle, cmd);
}/* otherwise, no signaling from non real time */
} /* as plc does not wait for lock. */
}
-void SVGHMI_SuspendFromPythonThread(void)
-{
- char cmd = 1; /*whatever*/
- read(svghmi_pipe_fd, &cmd, sizeof(cmd));
-}
-
-void SVGHMI_WakeupFromRTThread(void)
-{
- char cmd;
- rt_pipe_write(&svghmi_pipe, &cmd, sizeof(cmd), P_NORMAL);
-}
-
#ifndef HAVE_RETAIN
int CheckRetainBuffer(void)
{