Xenomai Fix : build
authorEdouard Tisserant
Thu, 22 Sep 2011 17:35:29 +0200
changeset 615 72bc3e53a1fa
parent 614 eed1dcf311a1
child 616 b9271faec96e
Xenomai Fix : build
targets/Xenomai/XSD
targets/Xenomai/__init__.py
targets/Xenomai/plc_Xenomai_main.c
--- a/targets/Xenomai/XSD	Thu Sep 22 17:33:34 2011 +0200
+++ b/targets/Xenomai/XSD	Thu Sep 22 17:35:29 2011 +0200
@@ -2,6 +2,6 @@
                   <xsd:element name="Xenomai">
                     <xsd:complexType>
                       %(toolchain_gcc)s
-                      <xsd:attribute name="XenoConfig" type="xsd:string" use="optional" default="/usr/xenomai/bin/xeno-config"/>
+                      <xsd:attribute name="XenoConfig" type="xsd:string" use="optional" default="xeno-config"/>
                     </xsd:complexType>
-                  </xsd:element>
\ No newline at end of file
+                  </xsd:element>
--- a/targets/Xenomai/__init__.py	Thu Sep 22 17:33:34 2011 +0200
+++ b/targets/Xenomai/__init__.py	Thu Sep 22 17:35:29 2011 +0200
@@ -11,7 +11,7 @@
         # get xeno-config from target parameters
         xeno_config = self.getXenoConfig()
 
-        status, result, err_result = ProcessLogger(self.PluginsRootInstance.logger, xeno_config + " --xeno-ldflags", no_stdout=True).spin()
+        status, result, err_result = ProcessLogger(self.PluginsRootInstance.logger, xeno_config + " --skin=native --ldflags", no_stdout=True).spin()
         if status:
             self.PluginsRootInstance.logger.write_error(_("Unable to get Xenomai's LDFLAGS\n"))
         xeno_ldlags = result.strip()
@@ -22,7 +22,7 @@
         # get xeno-config from target parameters
         xeno_config = self.getXenoConfig()
 
-        status, result, err_result = ProcessLogger(self.PluginsRootInstance.logger, xeno_config + " --xeno-cflags", no_stdout=True).spin()
+        status, result, err_result = ProcessLogger(self.PluginsRootInstance.logger, xeno_config + " --skin=native --cflags", no_stdout=True).spin()
         if status:
             self.PluginsRootInstance.logger.write_error(_("Unable to get Xenomai's CFLAGS\n"))
         xeno_cflags = result.strip()
--- a/targets/Xenomai/plc_Xenomai_main.c	Thu Sep 22 17:33:34 2011 +0200
+++ b/targets/Xenomai/plc_Xenomai_main.c	Thu Sep 22 17:35:29 2011 +0200
@@ -3,6 +3,7 @@
  **/
 
 #include <stdio.h>
+#include <unistd.h>
 #include <string.h>
 #include <time.h>
 #include <signal.h>
@@ -17,16 +18,25 @@
 #include <native/pipe.h>
 
 unsigned int PLC_state = 0;
-#define PLC_STATE_TASK_CREATED                  1
-#define PLC_STATE_PYTHON_MUTEX_CREATED          2
-#define PLC_STATE_PYTHON_WAIT_SEM_CREATED       4
-#define PLC_STATE_DEBUG_MUTEX_CREATED           8
-#define PLC_STATE_DEBUG_FILE_OPENED             16
-#define PLC_STATE_DEBUG_PIPE_CREATED            32
-
-#define WAITDEBUG_PIPE_DEVICE       "/dev/rtp0"
-#define WAITDEBUG_PIPE_MINOR        0
-#define WAITDEBUG_PIPE_SIZE         500
+#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 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 PIPE_SIZE                    1 
 
 /* provided by POUS.C */
 extern unsigned long common_ticktime__;
@@ -45,16 +55,17 @@
 
 RT_TASK PLC_task;
 RT_PIPE WaitDebug_pipe;
-RT_TASK SuspendDebug_task;
-RT_TASK ResumeDebug_task;
-RT_TASK WaitPythonCommand_task;
-RT_TASK UnLockPython_task;
-RT_TASK LockPython_task;
+RT_PIPE WaitPython_pipe;
+RT_PIPE Debug_pipe;
+RT_PIPE Python_pipe;
+int WaitDebug_pipe_fd;
+int WaitPython_pipe_fd;
+int Debug_pipe_fd;
+int Python_pipe_fd;
+
 int PLC_shutdown = 0;
 
-int WaitDebug_pipe_fd = -1;
-
-void PLC_SetTimer(long long next, long long period)
+void PLC_SetTimer(unsigned long long next, unsigned long long period)
 {
   RTIME current_time = rt_timer_read();
   rt_task_set_periodic(&PLC_task, current_time + next, rt_timer_ns2ticks(period));
@@ -74,10 +85,6 @@
 
 static unsigned long __debug_tick;
 
-RT_SEM python_wait_sem;
-RT_MUTEX python_mutex;
-RT_MUTEX debug_mutex;
-
 void PLC_cleanup_all(void)
 {
     if (PLC_state & PLC_STATE_TASK_CREATED) {
@@ -85,31 +92,46 @@
         PLC_state &= ~PLC_STATE_TASK_CREATED;
     }
 
-    if (PLC_state & PLC_STATE_PYTHON_WAIT_SEM_CREATED) {
-        rt_sem_v(&python_wait_sem);
-        rt_sem_delete(&python_wait_sem);
-        PLC_state &= ~ PLC_STATE_PYTHON_WAIT_SEM_CREATED;
-    }
-
-    if (PLC_state & PLC_STATE_PYTHON_MUTEX_CREATED) {
-        rt_mutex_delete(&python_mutex);
-        PLC_state &= ~ PLC_STATE_PYTHON_MUTEX_CREATED;
+    if (PLC_state & PLC_STATE_WAITDEBUG_PIPE_CREATED) {
+        rt_pipe_delete(&WaitDebug_pipe);
+        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);
+        PLC_state &= ~PLC_STATE_WAITDEBUG_PIPE_CREATED;
+    }
+
+    if (PLC_state & PLC_STATE_WAITPYTHON_PIPE_CREATED) {
+        close(WaitPython_pipe_fd);
+        PLC_state &= ~PLC_STATE_WAITPYTHON_FILE_OPENED;
     }
 
     if (PLC_state & PLC_STATE_DEBUG_PIPE_CREATED) {
-        rt_pipe_delete(&WaitDebug_pipe);
+        rt_pipe_delete(&Debug_pipe);
         PLC_state &= ~PLC_STATE_DEBUG_PIPE_CREATED;
     }
 
     if (PLC_state & PLC_STATE_DEBUG_FILE_OPENED) {
-        close(WaitDebug_pipe_fd);
+        close(Debug_pipe_fd);
         PLC_state &= ~PLC_STATE_DEBUG_FILE_OPENED;
     }
 
-    if (PLC_state & PLC_STATE_DEBUG_MUTEX_CREATED) {
-        rt_mutex_delete(&debug_mutex);
-        PLC_state &= ~ PLC_STATE_DEBUG_MUTEX_CREATED;
-    }
+    if (PLC_state & PLC_STATE_PYTHON_PIPE_CREATED) {
+        rt_pipe_delete(&Python_pipe);
+        PLC_state &= ~PLC_STATE_DEBUG_PIPE_CREATED;
+    }
+
+    if (PLC_state & PLC_STATE_PYTHON_PIPE_CREATED) {
+        close(Python_pipe_fd);
+        PLC_state &= ~PLC_STATE_PYTHON_FILE_OPENED;
+    }
+
 }
 
 int stopPLC()
@@ -120,6 +142,7 @@
     __cleanup();
     PLC_cleanup_all();
     __debug_tick = -1;
+    return 0;
 }
 
 //
@@ -135,56 +158,59 @@
 #define max_val(a,b) ((a>b)?a:b)
 int startPLC(int argc,char **argv)
 {
-    int ret = 0;
-
     signal(SIGINT, catch_signal);
 
-    /* ne-memory-swapping for this program */
+    /* no memory swapping for that process */
     mlockall(MCL_CURRENT | MCL_FUTURE);
 
     /* Define Ttick to 1ms if common_ticktime not defined */
     Ttick = common_ticktime__?common_ticktime__:1000000;
 
-    /* create python_wait_sem */
-    ret = rt_sem_create(&python_wait_sem, "python_wait_sem", 0, S_FIFO);
-    if (ret) goto error;
-    PLC_state |= PLC_STATE_PYTHON_WAIT_SEM_CREATED;
-
-    /* create python_mutex */
-    ret = rt_mutex_create(&python_mutex, "python_mutex");
-    if (ret) goto error;
-    PLC_state |= PLC_STATE_PYTHON_MUTEX_CREATED;
+    /*** RT Pipes creation and opening ***/
+    /* create Debug_pipe */
+    if(rt_pipe_create(&Debug_pipe, "Debug_pipe", DEBUG_PIPE_MINOR, PIPE_SIZE)) 
+        goto error;
+    PLC_state |= PLC_STATE_DEBUG_PIPE_CREATED;
+
+    /* open Debug_pipe*/
+    if((Debug_pipe_fd = open(DEBUG_PIPE_DEVICE, O_RDWR)) == -1) goto error;
+    PLC_state |= PLC_STATE_DEBUG_FILE_OPENED;
+
+    /* create Python_pipe */
+    if(rt_pipe_create(&Python_pipe, "Python_pipe", PYTHON_PIPE_MINOR, PIPE_SIZE)) 
+        goto error;
+    PLC_state |= PLC_STATE_PYTHON_PIPE_CREATED;
+
+    /* open Python_pipe*/
+    if((Python_pipe_fd = open(PYTHON_PIPE_DEVICE, O_RDWR)) == -1) goto error;
+    PLC_state |= PLC_STATE_PYTHON_FILE_OPENED;
 
     /* create WaitDebug_pipe */
-    ret = rt_pipe_create(&WaitDebug_pipe, "WaitDebug_pipe", WAITDEBUG_PIPE_MINOR,
-          WAITDEBUG_PIPE_SIZE * sizeof(char));
-    if (ret) goto error;
-    PLC_state |= PLC_STATE_DEBUG_PIPE_CREATED;
+    if(rt_pipe_create(&WaitDebug_pipe, "Debug_pipe", WAITDEBUG_PIPE_MINOR, PIPE_SIZE))
+        goto error;
+    PLC_state |= PLC_STATE_WAITDEBUG_PIPE_CREATED;
 
     /* open WaitDebug_pipe*/
-    WaitDebug_pipe_fd = open(WAITDEBUG_PIPE_DEVICE, O_RDWR);
-    if (WaitDebug_pipe_fd == -1) {
-        ret = -EBADF;
+    if((WaitDebug_pipe_fd = open(WAITDEBUG_PIPE_DEVICE, O_RDWR)) == -1) goto error;
+    PLC_state |= PLC_STATE_WAITDEBUG_FILE_OPENED;
+
+    /* create WaitPython_pipe */
+    if(rt_pipe_create(&WaitPython_pipe, "Python_pipe", WAITPYTHON_PIPE_MINOR, PIPE_SIZE))
         goto error;
-    }
-    PLC_state |= PLC_STATE_DEBUG_FILE_OPENED;
-
-    /* create debug_mutex */
-    ret = rt_mutex_create(&debug_mutex, "debug_mutex");
-    if (ret) goto error;
-    PLC_state |= PLC_STATE_DEBUG_MUTEX_CREATED;
-
-    /* create can_driver_task */
-    ret = rt_task_create(&PLC_task, "PLC_task", 0, 50, 0);
-    if (ret) goto error;
+    PLC_state |= PLC_STATE_WAITPYTHON_PIPE_CREATED;
+
+    /* open WaitPython_pipe*/
+    if((WaitPython_pipe_fd = open(WAITPYTHON_PIPE_DEVICE, O_RDWR)) == -1) goto error;
+    PLC_state |= PLC_STATE_WAITPYTHON_FILE_OPENED;
+
+    /*** create PLC task ***/
+    if(rt_task_create(&PLC_task, "PLC_task", 0, 50, 0)) goto error;
     PLC_state |= PLC_STATE_TASK_CREATED;
 
-    ret = __init(argc,argv);
-    if (ret) goto error;
-
-    /* start can_driver_task */
-    ret = rt_task_start(&PLC_task, &PLC_task_proc, NULL);
-    if (ret) goto error;
+    if(__init(argc,argv)) goto error;
+
+    /* start PLC task */
+    if(rt_task_start(&PLC_task, &PLC_task_proc, NULL)) goto error;
 
     return 0;
 
@@ -193,29 +219,42 @@
     return 1;
 }
 
+#define DEBUG_FREE 0
+#define DEBUG_BUSY 1
+static long debug_state = DEBUG_FREE;
+
 int TryEnterDebugSection(void)
 {
-    return rt_mutex_acquire(&debug_mutex, TM_NONBLOCK) == 0;
-}
-
+    long old_debug_state = AtomicCompareExchange(
+        &debug_state,
+        DEBUG_FREE,
+        DEBUG_BUSY);
+    return old_debug_state == DEBUG_FREE;
+}
+
+#define DEBUG_UNLOCK 1
 void LeaveDebugSection(void)
 {
-    rt_mutex_release(&debug_mutex);
+    if(AtomicCompareExchange( &debug_state, 
+        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);
+    }
 }
 
 extern unsigned long __tick;
-/* from plc_debugger.c */
+
+#define DEBUG_PENDING_DATA 1
 int WaitDebugData(unsigned long *tick)
 {
-    char message;
+    char cmd;
     int res;
     *tick = __debug_tick;
     /* Wait signal from PLC thread */
-    if (PLC_state & PLC_STATE_DEBUG_FILE_OPENED) {
-        res = read(WaitDebug_pipe_fd, &message, sizeof(char));
-        if (res == sizeof(char))
-            return 0;
-    }
+    res = read(WaitDebug_pipe_fd, &cmd, sizeof(cmd));
+    if (res == sizeof(cmd) && cmd == DEBUG_PENDING_DATA)
+        return 0;
     return -1;
 }
 
@@ -223,41 +262,46 @@
  * This is supposed to unlock debugger thread in WaitDebugData*/
 void InitiateDebugTransfer()
 {
-    char message = 1;
+    char msg = DEBUG_PENDING_DATA;
     /* remember tick */
     __debug_tick = __tick;
     /* signal debugger thread it can read data */
-    if (PLC_state & PLC_STATE_DEBUG_PIPE_CREATED)
-        rt_pipe_write(&WaitDebug_pipe, &message, sizeof(char), P_NORMAL);
-}
-
-void suspendDebug(void)
-{
-    __DEBUG = 0;
-    if (PLC_state & PLC_STATE_DEBUG_MUTEX_CREATED) {
-        rt_task_shadow(&SuspendDebug_task, "SuspendDebug_task", 0, 0);
-        /* Prevent PLC to enter debug code */
-        rt_mutex_acquire(&debug_mutex, TM_INFINITE);
-    }
+    rt_pipe_write(&WaitDebug_pipe, &msg, sizeof(msg), P_NORMAL);
+}
+
+int suspendDebug(int disable)
+{
+    char cmd = DEBUG_UNLOCK;
+    while(AtomicCompareExchange(
+            &debug_state,
+            DEBUG_FREE,
+            DEBUG_BUSY) != DEBUG_FREE &&
+            cmd == DEBUG_UNLOCK){
+       if(read(Debug_pipe_fd, &cmd, sizeof(cmd)) == sizeof(cmd)){
+           return -1;
+       }
+    }
+    __DEBUG = !disable;
+    return 0;
 }
 
 void resumeDebug(void)
 {
-    __DEBUG = 1;
-    if (PLC_state & PLC_STATE_DEBUG_MUTEX_CREATED) {
-        rt_task_shadow(&ResumeDebug_task, "ResumeDebug_task", 0, 0);
-        /* Let PLC enter debug code */
-        rt_mutex_release(&debug_mutex);
-    }
-}
-
-/* from plc_python.c */
+    AtomicCompareExchange( &debug_state, DEBUG_BUSY, DEBUG_FREE);
+}
+
+#define PYTHON_PENDING_COMMAND 1
+
+#define PYTHON_FREE 0
+#define PYTHON_BUSY 1
+static long python_state = PYTHON_FREE;
+
 int WaitPythonCommands(void)
-{
+{ 
+    char cmd;
     /* Wait signal from PLC thread */
-    if (PLC_state & PLC_STATE_PYTHON_WAIT_SEM_CREATED) {
-        rt_task_shadow(&WaitPythonCommand_task, "WaitPythonCommand_task", 0, 0);
-        return rt_sem_p(&python_wait_sem, TM_INFINITE);
+    if(read(WaitPython_pipe_fd, &cmd, sizeof(cmd))==sizeof(cmd) && cmd==PYTHON_PENDING_COMMAND){
+        return 0;
     }
     return -1;
 }
@@ -265,27 +309,41 @@
 /* Called by PLC thread on each new python command*/
 void UnBlockPythonCommands(void)
 {
-    /* signal debugger thread it can read data */
-    rt_sem_v(&python_wait_sem);
+    char msg = PYTHON_PENDING_COMMAND;
+    rt_pipe_write(&WaitPython_pipe, &msg, sizeof(msg), P_NORMAL);
 }
 
 int TryLockPython(void)
 {
-    return rt_mutex_acquire(&python_mutex, TM_NONBLOCK) == 0;
+    return AtomicCompareExchange(
+        &python_state,
+        PYTHON_FREE,
+        PYTHON_BUSY) == PYTHON_FREE;
+}
+
+#define UNLOCK_PYTHON 1
+void LockPython(void)
+{
+    char cmd = UNLOCK_PYTHON;
+    while(AtomicCompareExchange(
+            &python_state,
+            PYTHON_FREE,
+            PYTHON_BUSY) != PYTHON_FREE &&
+            cmd == UNLOCK_PYTHON){
+       read(Python_pipe_fd, &cmd, sizeof(cmd));
+    }
 }
 
 void UnLockPython(void)
 {
-    if (PLC_state & PLC_STATE_PYTHON_MUTEX_CREATED) {
-        rt_task_shadow(&UnLockPython_task, "UnLockPython_task", 0, 0);
-        rt_mutex_release(&python_mutex);
-    }
-}
-
-void LockPython(void)
-{
-    if (PLC_state & PLC_STATE_PYTHON_MUTEX_CREATED) {
-        rt_task_shadow(&LockPython_task, "LockPython_task", 0, 0);
-        rt_mutex_acquire(&python_mutex, TM_INFINITE);
-    }
-}
+    if(AtomicCompareExchange(
+            &python_state,
+            PYTHON_BUSY,
+            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);
+        }/* otherwise, no signaling from non real time */
+    }    /* as plc does not wait for lock. */
+}
+