--- 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. */
+}
+