greg@205: #include greg@205: #include greg@205: #include greg@205: #include greg@205: greg@205: long AtomicCompareExchange(long* atomicvar,long exchange, long compared) greg@205: { greg@205: return InterlockedCompareExchange(atomicvar, exchange, compared); greg@205: } greg@205: greg@205: //long AtomicExchange(long* atomicvar,long exchange) greg@205: //{ greg@205: // return InterlockedExchange(atomicvar, exchange); greg@205: //} greg@205: greg@205: struct _timeb timetmp; greg@205: void PLC_GetTime(IEC_TIME *CURRENT_TIME) greg@205: { greg@205: _ftime(&timetmp); greg@205: greg@205: (*CURRENT_TIME).tv_sec = timetmp.time; greg@205: (*CURRENT_TIME).tv_nsec = timetmp.millitm * 1000000; greg@205: } greg@205: greg@205: void PLC_timer_notify() greg@205: { greg@205: PLC_GetTime(&__CURRENT_TIME); greg@205: __run(); greg@205: } greg@205: greg@205: HANDLE PLC_timer = NULL; greg@205: void PLC_SetTimer(long long next, long long period) greg@205: { greg@229: LARGE_INTEGER liDueTime; greg@205: /* arg 2 of SetWaitableTimer take 100 ns interval*/ greg@205: liDueTime.QuadPart = next / (-100); greg@205: greg@205: /* greg@205: printf("SetTimer(%lld,%lld)\n",next, period); greg@205: */ greg@205: greg@205: if (!SetWaitableTimer(PLC_timer, &liDueTime, common_ticktime__, NULL, NULL, 0)) greg@205: { greg@205: printf("SetWaitableTimer failed (%d)\n", GetLastError()); greg@205: } greg@229: } greg@229: greg@229: /* Variable used to stop plcloop thread */ greg@229: int runplcloop; greg@229: void PlcLoop() greg@229: { greg@229: runplcloop = 1; greg@229: while(runplcloop) greg@229: { greg@229: // Set a timer greg@229: PLC_SetTimer(Ttick,Ttick); greg@205: if (WaitForSingleObject(PLC_timer, INFINITE) != WAIT_OBJECT_0) greg@205: { greg@205: printf("WaitForSingleObject failed (%d)\n", GetLastError()); greg@205: } greg@205: PLC_timer_notify(); greg@229: } greg@205: } greg@205: greg@229: HANDLE DebugLock; greg@229: HANDLE PLC_thread; greg@229: greg@229: int startPLC(int argc,char **argv) greg@205: { greg@229: unsigned long thread_id = 0; greg@205: /* Translate PLC's microseconds to Ttick nanoseconds */ greg@205: Ttick = 1000000 * maxval(common_ticktime__,1); greg@205: greg@229: DebugLock = CreateMutex( greg@229: NULL, // default security attributes greg@229: FALSE, // initially not owned greg@229: NULL); // unnamed mutex greg@229: greg@229: if (DebugLock == NULL) greg@229: { greg@229: printf("CreateMutex error: %d\n", GetLastError()); greg@229: return; greg@229: } greg@229: greg@205: /* Create a waitable timer */ greg@205: PLC_timer = CreateWaitableTimer(NULL, FALSE, "WaitableTimer"); greg@205: if(NULL == PLC_timer) greg@205: { greg@205: printf("CreateWaitableTimer failed (%d)\n", GetLastError()); greg@205: return 1; greg@205: } greg@205: if( __init(argc,argv) == 0 ) greg@205: { greg@205: printf("Tick Time : %d ms\n", common_ticktime__); greg@229: PLC_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlcLoop, NULL, 0, &thread_id); greg@205: } greg@229: else{ greg@229: return 1; greg@229: } greg@205: return 0; greg@205: } greg@229: greg@229: int stopPLC() greg@229: { greg@229: runplcloop = 0; greg@229: WaitForSingleObject(PLC_thread, INFINITE); greg@229: CloseHandle(PLC_thread); greg@229: CloseHandle(DebugLock); greg@229: CloseHandle(PLC_timer); greg@229: __cleanup(); greg@229: } greg@229: greg@229: /* from plc_debugger.c */ greg@229: void WaitDebugData() greg@229: { greg@229: DWORD dwWaitResult; greg@229: dwWaitResult = WaitForSingleObject( greg@229: DebugLock, // handle to mutex greg@229: INFINITE); // no time-out interval greg@229: } greg@229: greg@229: /* Called by PLC thread when debug_publish finished greg@229: * This is supposed to unlock debugger thread in WaitDebugData*/ greg@229: void InitiateDebugTransfer() greg@229: { greg@229: /* signal debugger thread to continue*/ greg@229: ReleaseMutex(DebugLock); greg@229: }