|
1 /** |
|
2 * Linux specific code |
|
3 **/ |
|
4 |
1 #include <stdio.h> |
5 #include <stdio.h> |
2 #include <string.h> |
6 #include <string.h> |
3 #include <time.h> |
7 #include <time.h> |
4 #include <signal.h> |
8 #include <signal.h> |
5 #include <stdlib.h> |
9 #include <stdlib.h> |
6 #include <pthread.h> |
10 #include <pthread.h> |
7 |
11 |
|
12 /* provided by POUS.C */ |
|
13 extern int common_ticktime__; |
|
14 |
8 long AtomicCompareExchange(long* atomicvar,long compared, long exchange) |
15 long AtomicCompareExchange(long* atomicvar,long compared, long exchange) |
9 { |
16 { |
10 return __sync_val_compare_and_swap(atomicvar, compared, exchange); |
17 return __sync_val_compare_and_swap(atomicvar, compared, exchange); |
11 } |
18 } |
12 |
|
13 //long AtomicExchange(long* atomicvar,long exchange) |
|
14 //{ |
|
15 // return __sync_lock_test_and_set(atomicvar, exchange); |
|
16 //} |
|
17 |
19 |
18 void PLC_GetTime(IEC_TIME *CURRENT_TIME) |
20 void PLC_GetTime(IEC_TIME *CURRENT_TIME) |
19 { |
21 { |
20 clock_gettime(CLOCK_REALTIME, CURRENT_TIME); |
22 clock_gettime(CLOCK_REALTIME, CURRENT_TIME); |
21 } |
23 } |
62 } |
64 } |
63 |
65 |
64 |
66 |
65 static int __debug_tick; |
67 static int __debug_tick; |
66 |
68 |
67 static pthread_mutex_t wait_mutex = PTHREAD_MUTEX_INITIALIZER; |
69 static pthread_mutex_t python_wait_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
70 static pthread_mutex_t python_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
71 static pthread_mutex_t debug_wait_mutex = PTHREAD_MUTEX_INITIALIZER; |
68 static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER; |
72 static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER; |
69 |
73 |
|
74 #define maxval(a,b) ((a>b)?a:b) |
70 int startPLC(int argc,char **argv) |
75 int startPLC(int argc,char **argv) |
71 { |
76 { |
72 struct sigevent sigev; |
77 struct sigevent sigev; |
73 /* Translate PLC's microseconds to Ttick nanoseconds */ |
78 /* Translate PLC's microseconds to Ttick nanoseconds */ |
74 Ttick = 1000000 * maxval(common_ticktime__,1); |
79 Ttick = 1000000 * maxval(common_ticktime__,1); |
77 sigev.sigev_value.sival_int = 0; |
82 sigev.sigev_value.sival_int = 0; |
78 sigev.sigev_notify = SIGEV_THREAD; |
83 sigev.sigev_notify = SIGEV_THREAD; |
79 sigev.sigev_notify_attributes = NULL; |
84 sigev.sigev_notify_attributes = NULL; |
80 sigev.sigev_notify_function = PLC_timer_notify; |
85 sigev.sigev_notify_function = PLC_timer_notify; |
81 |
86 |
82 pthread_mutex_lock(&wait_mutex); |
87 pthread_mutex_lock(&debug_wait_mutex); |
|
88 pthread_mutex_lock(&python_wait_mutex); |
83 |
89 |
84 timer_create (CLOCK_REALTIME, &sigev, &PLC_timer); |
90 timer_create (CLOCK_REALTIME, &sigev, &PLC_timer); |
85 if( __init(argc,argv) == 0 ){ |
91 if( __init(argc,argv) == 0 ){ |
86 PLC_SetTimer(Ttick,Ttick); |
92 PLC_SetTimer(Ttick,Ttick); |
87 |
93 |
109 /* Stop the PLC */ |
115 /* Stop the PLC */ |
110 PLC_SetTimer(0,0); |
116 PLC_SetTimer(0,0); |
111 timer_delete (PLC_timer); |
117 timer_delete (PLC_timer); |
112 __cleanup(); |
118 __cleanup(); |
113 __debug_tick = -1; |
119 __debug_tick = -1; |
114 pthread_mutex_unlock(&wait_mutex); |
120 pthread_mutex_unlock(&debug_wait_mutex); |
115 } |
121 } |
116 |
122 |
117 extern int __tick; |
123 extern int __tick; |
118 /* from plc_debugger.c */ |
124 /* from plc_debugger.c */ |
119 int WaitDebugData() |
125 int WaitDebugData() |
120 { |
126 { |
121 /* Wait signal from PLC thread */ |
127 /* Wait signal from PLC thread */ |
122 pthread_mutex_lock(&wait_mutex); |
128 pthread_mutex_lock(&debug_wait_mutex); |
123 return __debug_tick; |
129 return __debug_tick; |
124 } |
130 } |
125 |
131 |
126 /* Called by PLC thread when debug_publish finished |
132 /* Called by PLC thread when debug_publish finished |
127 * This is supposed to unlock debugger thread in WaitDebugData*/ |
133 * This is supposed to unlock debugger thread in WaitDebugData*/ |
128 void InitiateDebugTransfer() |
134 void InitiateDebugTransfer() |
129 { |
135 { |
130 /* Leave debugger section */ |
|
131 pthread_mutex_unlock(&debug_mutex); |
|
132 /* remember tick */ |
136 /* remember tick */ |
133 __debug_tick = __tick; |
137 __debug_tick = __tick; |
134 /* signal debugger thread it can read data */ |
138 /* signal debugger thread it can read data */ |
135 pthread_mutex_unlock(&wait_mutex); |
139 pthread_mutex_unlock(&debug_wait_mutex); |
136 } |
140 } |
137 |
141 |
138 void suspendDebug() |
142 void suspendDebug(void) |
139 { |
143 { |
140 __DEBUG = 0; |
|
141 /* Prevent PLC to enter debug code */ |
144 /* Prevent PLC to enter debug code */ |
142 pthread_mutex_lock(&debug_mutex); |
145 pthread_mutex_lock(&debug_mutex); |
143 } |
146 } |
144 |
147 |
145 void resumeDebug() |
148 void resumeDebug(void) |
146 { |
149 { |
147 __DEBUG = 1; |
|
148 /* Let PLC enter debug code */ |
150 /* Let PLC enter debug code */ |
149 pthread_mutex_unlock(&debug_mutex); |
151 pthread_mutex_unlock(&debug_mutex); |
150 } |
152 } |
151 |
153 |
|
154 /* from plc_python.c */ |
|
155 int WaitPythonCommands(void) |
|
156 { |
|
157 /* Wait signal from PLC thread */ |
|
158 pthread_mutex_lock(&python_wait_mutex); |
|
159 } |
|
160 |
|
161 /* Called by PLC thread on each new python command*/ |
|
162 void UnBlockPythonCommands(void) |
|
163 { |
|
164 /* signal debugger thread it can read data */ |
|
165 pthread_mutex_unlock(&python_wait_mutex); |
|
166 } |
|
167 |
|
168 int TryLockPython(void) |
|
169 { |
|
170 return pthread_mutex_trylock(&python_mutex) == 0; |
|
171 } |
|
172 |
|
173 void UnLockPython(void) |
|
174 { |
|
175 pthread_mutex_unlock(&python_mutex); |
|
176 } |
|
177 |
|
178 void LockPython(void) |
|
179 { |
|
180 pthread_mutex_lock(&python_mutex); |
|
181 } |