--- 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: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"/>
\ No newline at end of file
--- 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() 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() 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 @@
@@ -17,16 +18,25 @@
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 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 WAITDEBUG_PIPE_SIZE 500
+#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 extern unsigned long common_ticktime__;
@@ -45,16 +55,17 @@
-RT_TASK SuspendDebug_task;
-RT_TASK ResumeDebug_task;
-RT_TASK WaitPythonCommand_task;
-RT_TASK UnLockPython_task;
-RT_TASK LockPython_task;
+RT_PIPE WaitPython_pipe; -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;
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_WAITDEBUG_PIPE_CREATED) { + rt_pipe_delete(&WaitDebug_pipe); + PLC_state &= ~PLC_STATE_WAITDEBUG_PIPE_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_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);
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) { + PLC_state &= ~PLC_STATE_PYTHON_FILE_OPENED; @@ -120,6 +142,7 @@
@@ -135,56 +158,59 @@
#define max_val(a,b) ((a>b)?a:b)
int startPLC(int argc,char **argv)
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);
- PLC_state |= PLC_STATE_PYTHON_WAIT_SEM_CREATED;
+ /*** RT Pipes creation and opening ***/ + /* create Debug_pipe */ + if(rt_pipe_create(&Debug_pipe, "Debug_pipe", DEBUG_PIPE_MINOR, PIPE_SIZE)) + PLC_state |= PLC_STATE_DEBUG_PIPE_CREATED; - /* create python_mutex */
- ret = rt_mutex_create(&python_mutex, "python_mutex");
- PLC_state |= PLC_STATE_PYTHON_MUTEX_CREATED;
+ 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)) + PLC_state |= PLC_STATE_PYTHON_PIPE_CREATED; + 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));
- PLC_state |= PLC_STATE_DEBUG_PIPE_CREATED;
+ if(rt_pipe_create(&WaitDebug_pipe, "Debug_pipe", WAITDEBUG_PIPE_MINOR, PIPE_SIZE)) + PLC_state |= PLC_STATE_WAITDEBUG_PIPE_CREATED; - WaitDebug_pipe_fd = open(WAITDEBUG_PIPE_DEVICE, O_RDWR);
- if (WaitDebug_pipe_fd == -1) {
- PLC_state |= PLC_STATE_DEBUG_FILE_OPENED;
+ if((WaitDebug_pipe_fd = open(WAITDEBUG_PIPE_DEVICE, O_RDWR)) == -1) goto error; + PLC_state |= PLC_STATE_WAITDEBUG_FILE_OPENED; - /* create debug_mutex */
- ret = rt_mutex_create(&debug_mutex, "debug_mutex");
- PLC_state |= PLC_STATE_DEBUG_MUTEX_CREATED;
+ /* create WaitPython_pipe */ + if(rt_pipe_create(&WaitPython_pipe, "Python_pipe", WAITPYTHON_PIPE_MINOR, PIPE_SIZE)) + PLC_state |= PLC_STATE_WAITPYTHON_PIPE_CREATED; - /* create can_driver_task */
- ret = rt_task_create(&PLC_task, "PLC_task", 0, 50, 0);
+ /* 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(__init(argc,argv)) goto error; - /* start can_driver_task */
- ret = rt_task_start(&PLC_task, &PLC_task_proc, NULL);
+ if(rt_task_start(&PLC_task, &PLC_task_proc, NULL)) goto error; @@ -193,29 +219,42 @@
+static long debug_state = DEBUG_FREE; int TryEnterDebugSection(void)
- return rt_mutex_acquire(&debug_mutex, TM_NONBLOCK) == 0;
+ long old_debug_state = AtomicCompareExchange( + return old_debug_state == DEBUG_FREE; 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)
/* 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))
+ res = read(WaitDebug_pipe_fd, &cmd, sizeof(cmd)); + if (res == sizeof(cmd) && cmd == DEBUG_PENDING_DATA) @@ -223,41 +262,46 @@
* This is supposed to unlock debugger thread in WaitDebugData*/
void InitiateDebugTransfer()
+ char msg = DEBUG_PENDING_DATA; /* 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);
+ rt_pipe_write(&WaitDebug_pipe, &msg, sizeof(msg), P_NORMAL);
+int suspendDebug(int disable)
- 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);
+ char cmd = DEBUG_UNLOCK; + while(AtomicCompareExchange( + DEBUG_BUSY) != DEBUG_FREE && + if(read(Debug_pipe_fd, &cmd, sizeof(cmd)) == sizeof(cmd)){
- 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);
+ AtomicCompareExchange( &debug_state, DEBUG_BUSY, DEBUG_FREE);
+#define PYTHON_PENDING_COMMAND 1 +static long python_state = PYTHON_FREE; int WaitPythonCommands(void)
/* 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){ @@ -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); - return rt_mutex_acquire(&python_mutex, TM_NONBLOCK) == 0;
+ return AtomicCompareExchange( + PYTHON_BUSY) == PYTHON_FREE; + char cmd = UNLOCK_PYTHON; + while(AtomicCompareExchange( + PYTHON_BUSY) != PYTHON_FREE && + read(Python_pipe_fd, &cmd, sizeof(cmd)); - if (PLC_state & PLC_STATE_PYTHON_MUTEX_CREATED) {
- rt_task_shadow(&UnLockPython_task, "UnLockPython_task", 0, 0);
- rt_mutex_release(&python_mutex);
+ if(AtomicCompareExchange( + 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. */
- if (PLC_state & PLC_STATE_PYTHON_MUTEX_CREATED) {
- rt_task_shadow(&LockPython_task, "LockPython_task", 0, 0);
- rt_mutex_acquire(&python_mutex, TM_INFINITE);