|
1 /** |
|
2 * Win32 specific code |
|
3 **/ |
|
4 |
1 #include <stdio.h> |
5 #include <stdio.h> |
2 #include <sys/timeb.h> |
6 #include <sys/timeb.h> |
3 #include <time.h> |
7 #include <time.h> |
4 #include <windows.h> |
8 #include <windows.h> |
5 |
9 |
|
10 /* provided by POUS.C */ |
|
11 extern int common_ticktime__; |
|
12 |
6 long AtomicCompareExchange(long* atomicvar, long compared, long exchange) |
13 long AtomicCompareExchange(long* atomicvar, long compared, long exchange) |
7 { |
14 { |
8 return InterlockedCompareExchange(atomicvar, exchange, compared); |
15 return InterlockedCompareExchange(atomicvar, exchange, compared); |
9 } |
16 } |
10 |
|
11 //long AtomicExchange(long* atomicvar,long exchange) |
|
12 //{ |
|
13 // return InterlockedExchange(atomicvar, exchange); |
|
14 //} |
|
15 |
17 |
16 struct _timeb timetmp; |
18 struct _timeb timetmp; |
17 void PLC_GetTime(IEC_TIME *CURRENT_TIME) |
19 void PLC_GetTime(IEC_TIME *CURRENT_TIME) |
18 { |
20 { |
19 _ftime(&timetmp); |
21 _ftime(&timetmp); |
62 } |
64 } |
63 } |
65 } |
64 |
66 |
65 HANDLE PLC_thread; |
67 HANDLE PLC_thread; |
66 HANDLE debug_sem; |
68 HANDLE debug_sem; |
67 HANDLE wait_sem; |
69 HANDLE debug_wait_sem; |
68 #define MAX_SEM_COUNT 1 |
70 HANDLE python_sem; |
69 |
71 HANDLE python_wait_sem; |
|
72 |
|
73 #define maxval(a,b) ((a>b)?a:b) |
70 int startPLC(int argc,char **argv) |
74 int startPLC(int argc,char **argv) |
71 { |
75 { |
72 unsigned long thread_id = 0; |
76 unsigned long thread_id = 0; |
73 /* Translate PLC's microseconds to Ttick nanoseconds */ |
77 /* Translate PLC's microseconds to Ttick nanoseconds */ |
74 Ttick = 1000000 * maxval(common_ticktime__,1); |
78 Ttick = 1000000 * maxval(common_ticktime__,1); |
75 |
79 |
76 debug_sem = CreateSemaphore( |
80 debug_sem = CreateSemaphore( |
77 NULL, // default security attributes |
81 NULL, // default security attributes |
78 1, // initial count |
82 1, // initial count |
79 MAX_SEM_COUNT, // maximum count |
83 1, // maximum count |
80 NULL); // unnamed semaphore |
84 NULL); // unnamed semaphore |
81 if (debug_sem == NULL) |
85 if (debug_sem == NULL) |
82 { |
86 { |
83 printf("CreateMutex error: %d\n", GetLastError()); |
87 printf("startPLC CreateSemaphore debug_sem error: %d\n", GetLastError()); |
84 return; |
88 return; |
85 } |
89 } |
86 |
90 |
87 wait_sem = CreateSemaphore( |
91 debug_wait_sem = CreateSemaphore( |
88 NULL, // default security attributes |
92 NULL, // default security attributes |
89 0, // initial count |
93 0, // initial count |
90 MAX_SEM_COUNT, // maximum count |
94 1, // maximum count |
91 NULL); // unnamed semaphore |
95 NULL); // unnamed semaphore |
92 |
96 |
93 if (wait_sem == NULL) |
97 if (debug_wait_sem == NULL) |
94 { |
98 { |
95 printf("CreateMutex error: %d\n", GetLastError()); |
99 printf("startPLC CreateSemaphore debug_wait_sem error: %d\n", GetLastError()); |
96 return; |
100 return; |
97 } |
101 } |
|
102 |
|
103 python_sem = CreateSemaphore( |
|
104 NULL, // default security attributes |
|
105 1, // initial count |
|
106 1, // maximum count |
|
107 NULL); // unnamed semaphore |
|
108 |
|
109 if (python_sem == NULL) |
|
110 { |
|
111 printf("startPLC CreateSemaphore python_sem error: %d\n", GetLastError()); |
|
112 return; |
|
113 } |
|
114 python_wait_sem = CreateSemaphore( |
|
115 NULL, // default security attributes |
|
116 0, // initial count |
|
117 1, // maximum count |
|
118 NULL); // unnamed semaphore |
|
119 |
|
120 |
|
121 if (python_wait_sem == NULL) |
|
122 { |
|
123 printf("startPLC CreateSemaphore python_wait_sem error: %d\n", GetLastError()); |
|
124 return; |
|
125 } |
|
126 |
98 |
127 |
99 /* Create a waitable timer */ |
128 /* Create a waitable timer */ |
100 PLC_timer = CreateWaitableTimer(NULL, FALSE, "WaitableTimer"); |
129 PLC_timer = CreateWaitableTimer(NULL, FALSE, "WaitableTimer"); |
101 if(NULL == PLC_timer) |
130 if(NULL == PLC_timer) |
102 { |
131 { |
131 { |
160 { |
132 runplcloop = 0; |
161 runplcloop = 0; |
133 WaitForSingleObject(PLC_thread, INFINITE); |
162 WaitForSingleObject(PLC_thread, INFINITE); |
134 __cleanup(); |
163 __cleanup(); |
135 __debug_tick = -1; |
164 __debug_tick = -1; |
136 ReleaseSemaphore(wait_sem, 1, NULL); |
165 ReleaseSemaphore(debug_wait_sem, 1, NULL); |
137 CloseHandle(debug_sem); |
166 CloseHandle(debug_sem); |
138 CloseHandle(wait_sem); |
167 CloseHandle(debug_wait_sem); |
139 CloseHandle(PLC_timer); |
168 CloseHandle(PLC_timer); |
140 CloseHandle(PLC_thread); |
169 CloseHandle(PLC_thread); |
141 } |
170 } |
142 |
171 |
143 /* from plc_debugger.c */ |
172 /* from plc_debugger.c */ |
144 int WaitDebugData() |
173 int WaitDebugData() |
145 { |
174 { |
146 WaitForSingleObject(wait_sem, INFINITE); |
175 WaitForSingleObject(debug_wait_sem, INFINITE); |
147 return __debug_tick; |
176 return __debug_tick; |
148 } |
177 } |
149 |
178 |
150 /* Called by PLC thread when debug_pu//blish finished |
179 /* Called by PLC thread when debug_publish finished |
151 * This is supposed to unlock debugger thread in WaitDebugData*/ |
180 * This is supposed to unlock debugger thread in WaitDebugData*/ |
152 void InitiateDebugTransfer() |
181 void InitiateDebugTransfer() |
153 { |
182 { |
154 /* remember tick */ |
183 /* remember tick */ |
155 __debug_tick = __tick; |
184 __debug_tick = __tick; |
156 /* signal debugger thread it can read data */ |
185 /* signal debugger thread it can read data */ |
157 ReleaseSemaphore(wait_sem, 1, NULL); |
186 ReleaseSemaphore(debug_wait_sem, 1, NULL); |
158 } |
187 } |
159 |
188 |
160 void suspendDebug() |
189 void suspendDebug() |
161 { |
190 { |
162 __DEBUG = 0; |
|
163 /* Prevent PLC to enter debug code */ |
191 /* Prevent PLC to enter debug code */ |
164 WaitForSingleObject(debug_sem, INFINITE); |
192 WaitForSingleObject(debug_sem, INFINITE); |
165 } |
193 } |
166 |
194 |
167 void resumeDebug() |
195 void resumeDebug() |
168 { |
196 { |
169 __DEBUG = 1; |
|
170 /* Let PLC enter debug code */ |
197 /* Let PLC enter debug code */ |
171 ReleaseSemaphore(debug_sem, 1, NULL); |
198 ReleaseSemaphore(debug_sem, 1, NULL); |
172 } |
199 } |
|
200 |
|
201 /* from plc_python.c */ |
|
202 int WaitPythonCommands(void) |
|
203 { |
|
204 /* Wait signal from PLC thread */ |
|
205 WaitForSingleObject(python_wait_sem, INFINITE); |
|
206 } |
|
207 |
|
208 /* Called by PLC thread on each new python command*/ |
|
209 void UnBlockPythonCommands(void) |
|
210 { |
|
211 /* signal debugger thread it can read data */ |
|
212 ReleaseSemaphore(python_wait_sem, 1, NULL); |
|
213 } |
|
214 |
|
215 int TryLockPython(void) |
|
216 { |
|
217 return WaitForSingleObject(python_sem, 0) == WAIT_OBJECT_0; |
|
218 } |
|
219 |
|
220 void UnLockPython(void) |
|
221 { |
|
222 ReleaseSemaphore(python_sem, 1, NULL); |
|
223 } |
|
224 |
|
225 void LockPython(void) |
|
226 { |
|
227 WaitForSingleObject(python_sem, INFINITE); |
|
228 } |
|
229 |