Fixed bug : Segmentation fault or locks when stop PLC if no CAN network.
--- a/plugins/canfestival/canfestival.py Fri Apr 10 07:53:42 2009 +0200
+++ b/plugins/canfestival/canfestival.py Fri Apr 10 07:55:55 2009 +0200
@@ -278,6 +278,7 @@
"board_decls" : "",
"nodes_init" : "",
"nodes_open" : "",
+ "nodes_stop" : "",
"nodes_close" : "",
"nodes_send_sync" : "",
"nodes_proceed_sync" : "",
@@ -361,7 +362,7 @@
child_data.getCAN_Baudrate())
format_dict["nodes_open"] += 'NODE_OPEN(%s)\n '%(nodename)
format_dict["nodes_close"] += 'NODE_CLOSE(%s)\n '%(nodename)
-
+ format_dict["nodes_stop"] += 'NODE_STOP(%s)\n '%(nodename)
if sys.platform == 'win32':
if self.CanFestivalInstance.getDebug_mode() and os.path.isfile(os.path.join("%s"%(format_dict["candriver"] + '_DEBUG.dll'))):
format_dict["candriver"] += '_DEBUG.dll'
--- a/plugins/canfestival/cf_runtime.c Fri Apr 10 07:53:42 2009 +0200
+++ b/plugins/canfestival/cf_runtime.c Fri Apr 10 07:55:55 2009 +0200
@@ -20,7 +20,7 @@
{
/* Put the master in operational mode */
setState(d, Operational);
-
+
/* Ask slave node to go in operational mode */
masterSendNMTstateChange (d, 0, NMT_Start_Node);
}
@@ -30,7 +30,7 @@
%(slavebootups)s
/* One slave node post_sync callback.
- * Used to align PLC tick-time on CANopen SYNC
+ * Used to align PLC tick-time on CANopen SYNC
*/
%(post_sync)s
@@ -48,42 +48,47 @@
setState(&nodename##_Data, Initialisation);
#define NODE_MASTER_INIT(nodename, nodeid) \
- NODE_FORCE_SYNC(nodename) \
- NODE_INIT(nodename, nodeid)
+ NODE_FORCE_SYNC(nodename) \
+ NODE_INIT(nodename, nodeid)
#define NODE_SLAVE_INIT(nodename, nodeid) \
- NODE_INIT(nodename, nodeid)
+ NODE_INIT(nodename, nodeid)
void InitNodes(CO_Data* d, UNS32 id)
{
- %(slavebootup_register)s
- %(post_sync_register)s
+ %(slavebootup_register)s
+ %(post_sync_register)s
%(nodes_init)s
}
+#define NODE_STOP(nodename) \
+ if(init_level-- > 0)\
+ {\
+ masterSendNMTstateChange(&nodename##_Data, 0, NMT_Reset_Node);\
+ setState(&nodename##_Data, Stopped);\
+ }
+
void Exit(CO_Data* d, UNS32 id)
{
+ %(nodes_stop)s
}
#define NODE_CLOSE(nodename) \
- if(init_level-- > 0)\
+ if(init_level_c-- > 0)\
{\
- EnterMutex();\
- masterSendNMTstateChange(&nodename##_Data, 0, NMT_Reset_Node);\
- setState(&nodename##_Data, Stopped);\
- LeaveMutex();\
- canClose(&nodename##_Data);\
+ canClose(&nodename##_Data);\
}
void __cleanup_%(locstr)s()
{
// Stop timer thread
if(init_level-- > 0){
+ int init_level_c = init_level;
StopTimerLoop(&Exit);
%(nodes_close)s
- }
+ }
#if !defined(WIN32) || defined(__CYGWIN__)
- TimerCleanup();
+ TimerCleanup();
#endif
}
@@ -104,11 +109,11 @@
fflush(stderr);
return -1;
}
-#endif
- #if !defined(WIN32) || defined(__CYGWIN__)
- TimerInit();
- #endif
-
+#endif
+ #if !defined(WIN32) || defined(__CYGWIN__)
+ TimerInit();
+ #endif
+
%(nodes_open)s
// Start timer thread
@@ -123,7 +128,7 @@
void __retrieve_%(locstr)s()
{
/* Locks the stack, so that no changes occurs while PLC access variables
- * TODO : implement buffers to avoid such a big lock
+ * TODO : implement buffers to avoid such a big lock
* */
EnterMutex();
/* Send Sync */
--- a/runtime/PLCObject.py Fri Apr 10 07:53:42 2009 +0200
+++ b/runtime/PLCObject.py Fri Apr 10 07:55:55 2009 +0200
@@ -226,7 +226,9 @@
runtime_begin()
def FinishRuntimePy(self):
- runtime_cleanup = self.python_threads_vars.get("_runtime_cleanup",None)
+ runtime_cleanup = None
+ if self.python_threads_vars is not None:
+ runtime_cleanup = self.python_threads_vars.get("_runtime_cleanup",None)
if runtime_cleanup is not None:
runtime_cleanup()
if self.hmi_frame is not None:
--- a/targets/Xenomai/plc_Xenomai_main.c Fri Apr 10 07:53:42 2009 +0200
+++ b/targets/Xenomai/plc_Xenomai_main.c Fri Apr 10 07:55:55 2009 +0200
@@ -1,6 +1,6 @@
/**
* Linux specific code
- **/
+ **/
#include <stdio.h>
#include <string.h>
@@ -52,7 +52,7 @@
void PLC_task_proc(void *arg)
{
PLC_SetTimer(Ttick, Ttick);
-
+
while (1) {
PLC_GetTime(&__CURRENT_TIME);
__run();
@@ -84,7 +84,7 @@
rt_mutex_delete(&python_mutex);
PLC_state &= ~ PLC_STATE_PYTHON_MUTEX_CREATED;
}
-
+
if (PLC_state & PLC_STATE_DEBUG_WAIT_SEM_CREATED) {
rt_sem_delete(&debug_wait_sem);
PLC_state &= ~ PLC_STATE_DEBUG_WAIT_SEM_CREATED;
@@ -122,40 +122,40 @@
int startPLC(int argc,char **argv)
{
int ret = 0;
-
+
signal(SIGINT, catch_signal);
-
+
/* ne-memory-swapping for this program */
mlockall(MCL_CURRENT | MCL_FUTURE);
-
+
/* Translate PLC's microseconds to Ttick nanoseconds */
Ttick = 1000000 * max_val(common_ticktime__,1);
-
+
/* 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;
-
+
/* create debug_wait_sem */
ret = rt_sem_create(&debug_wait_sem, "debug_wait_sem", 0, S_FIFO);
if (ret) goto error;
PLC_state |= PLC_STATE_DEBUG_WAIT_SEM_CREATED;
-
+
/* 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_TASK_CREATED;
-
+
ret = __init(argc,argv);
if (ret) goto error;
@@ -189,7 +189,7 @@
rt_sem_p(&debug_wait_sem, TM_INFINITE);
return __debug_tick;
}
-
+
/* Called by PLC thread when debug_publish finished
* This is supposed to unlock debugger thread in WaitDebugData*/
void InitiateDebugTransfer()
@@ -221,7 +221,7 @@
/* Wait signal from PLC thread */
rt_sem_p(&python_wait_sem, TM_INFINITE);
}
-
+
/* Called by PLC thread on each new python command*/
void UnBlockPythonCommands(void)
{