1 #include <stdio.h> |
|
2 #include <string.h> |
|
3 #include <time.h> |
|
4 #include <signal.h> |
|
5 #include <stdlib.h> |
|
6 #include <pthread.h> |
|
7 |
|
8 long AtomicCompareExchange(long* atomicvar,long exchange, long compared) |
|
9 { |
|
10 return __sync_val_compare_and_swap(atomicvar, compared, exchange); |
|
11 } |
|
12 |
|
13 //long AtomicExchange(long* atomicvar,long exchange) |
|
14 //{ |
|
15 // return __sync_lock_test_and_set(atomicvar, exchange); |
|
16 //} |
|
17 |
|
18 void PLC_GetTime(IEC_TIME *CURRENT_TIME) |
|
19 { |
|
20 clock_gettime(CLOCK_REALTIME, CURRENT_TIME); |
|
21 } |
|
22 |
|
23 void PLC_timer_notify(sigval_t val) |
|
24 { |
|
25 PLC_GetTime(&__CURRENT_TIME); |
|
26 __run(); |
|
27 } |
|
28 |
|
29 timer_t PLC_timer; |
|
30 |
|
31 void PLC_SetTimer(long long next, long long period) |
|
32 { |
|
33 struct itimerspec timerValues; |
|
34 /* |
|
35 printf("SetTimer(%lld,%lld)\n",next, period); |
|
36 */ |
|
37 memset (&timerValues, 0, sizeof (struct itimerspec)); |
|
38 { |
|
39 #ifdef __lldiv_t_defined |
|
40 lldiv_t nxt_div = lldiv(next, 1000000000); |
|
41 lldiv_t period_div = lldiv(period, 1000000000); |
|
42 timerValues.it_value.tv_sec = nxt_div.quot; |
|
43 timerValues.it_value.tv_nsec = nxt_div.rem; |
|
44 timerValues.it_interval.tv_sec = period_div.quot; |
|
45 timerValues.it_interval.tv_nsec = period_div.rem; |
|
46 #else |
|
47 timerValues.it_value.tv_sec = next / 1000000000; |
|
48 timerValues.it_value.tv_nsec = next % 1000000000; |
|
49 timerValues.it_interval.tv_sec = period / 1000000000; |
|
50 timerValues.it_interval.tv_nsec = period % 1000000000; |
|
51 #endif |
|
52 } |
|
53 timer_settime (PLC_timer, 0, &timerValues, NULL); |
|
54 } |
|
55 // |
|
56 void catch_signal(int sig) |
|
57 { |
|
58 // signal(SIGTERM, catch_signal); |
|
59 signal(SIGINT, catch_signal); |
|
60 printf("Got Signal %d\n",sig); |
|
61 exit(0); |
|
62 } |
|
63 |
|
64 int startPLC(int argc,char **argv) |
|
65 { |
|
66 struct sigevent sigev; |
|
67 /* Translate PLC's microseconds to Ttick nanoseconds */ |
|
68 Ttick = 1000000 * maxval(common_ticktime__,1); |
|
69 |
|
70 memset (&sigev, 0, sizeof (struct sigevent)); |
|
71 sigev.sigev_value.sival_int = 0; |
|
72 sigev.sigev_notify = SIGEV_THREAD; |
|
73 sigev.sigev_notify_attributes = NULL; |
|
74 sigev.sigev_notify_function = PLC_timer_notify; |
|
75 |
|
76 timer_create (CLOCK_REALTIME, &sigev, &PLC_timer); |
|
77 if( __init(argc,argv) == 0 ){ |
|
78 PLC_SetTimer(Ttick,Ttick); |
|
79 |
|
80 /* install signal handler for manual break */ |
|
81 // signal(SIGTERM, catch_signal); |
|
82 signal(SIGINT, catch_signal); |
|
83 }else{ |
|
84 return 1; |
|
85 } |
|
86 return 0; |
|
87 } |
|
88 |
|
89 int stopPLC() |
|
90 { |
|
91 /* Stop the PLC */ |
|
92 PLC_SetTimer(0,0); |
|
93 timer_delete (PLC_timer); |
|
94 __cleanup(); |
|
95 } |
|
96 |
|
97 pthread_mutex_t DebugLock = PTHREAD_MUTEX_INITIALIZER; |
|
98 |
|
99 /* from plc_debugger.c */ |
|
100 void WaitDebugData() |
|
101 { |
|
102 /* Wait signal from PLC thread */ |
|
103 pthread_mutex_lock(&DebugLock); |
|
104 } |
|
105 |
|
106 /* Called by PLC thread when debug_publish finished |
|
107 * This is supposed to unlock debugger thread in WaitDebugData*/ |
|
108 void InitiateDebugTransfer() |
|
109 { |
|
110 /* signal debugger thread to continue*/ |
|
111 pthread_mutex_unlock(&DebugLock); |
|
112 } |
|