greg@205: #include greg@205: #include greg@205: #include greg@205: #include greg@205: greg@244: long AtomicCompareExchange(long* atomicvar, long compared, long exchange) 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 PLC_thread; greg@244: HANDLE debug_sem; greg@244: HANDLE wait_sem; greg@244: #define MAX_SEM_COUNT 10 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@244: debug_sem = CreateSemaphore( greg@244: NULL, // default security attributes greg@244: 1, // initial count greg@244: MAX_SEM_COUNT, // maximum count greg@244: NULL); // unnamed semaphore greg@244: if (debug_sem == NULL) greg@244: { greg@244: printf("CreateMutex error: %d\n", GetLastError()); greg@244: return; greg@244: } greg@244: greg@244: wait_sem = CreateSemaphore( greg@244: NULL, // default security attributes greg@244: 0, // initial count greg@244: MAX_SEM_COUNT, // maximum count greg@244: NULL); // unnamed semaphore greg@229: greg@244: if (wait_sem == 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@244: static int __debug_tick; greg@244: greg@244: int TryEnterDebugSection(void) greg@244: { greg@244: //printf("TryEnterDebugSection\n"); greg@244: return WaitForSingleObject(debug_sem, 0) == WAIT_OBJECT_0; greg@244: } greg@244: greg@244: void LeaveDebugSection(void) greg@244: { greg@244: ReleaseSemaphore(debug_sem, 1, NULL); greg@244: //printf("LeaveDebugSection\n"); greg@244: } greg@229: greg@229: int stopPLC() greg@229: { greg@229: runplcloop = 0; greg@229: WaitForSingleObject(PLC_thread, INFINITE); greg@244: __cleanup(); greg@244: __debug_tick = -1; greg@244: ReleaseSemaphore(wait_sem, 1, NULL); greg@244: CloseHandle(debug_sem); greg@244: CloseHandle(wait_sem); greg@244: CloseHandle(PLC_timer); greg@229: CloseHandle(PLC_thread); greg@229: } greg@229: greg@229: /* from plc_debugger.c */ greg@244: int WaitDebugData() greg@229: { greg@244: WaitForSingleObject(wait_sem, INFINITE); greg@244: return __debug_tick; 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@244: /* Leave debugger section */ greg@244: ReleaseSemaphore(debug_sem, 1, NULL); greg@244: /* remember tick */ greg@244: __debug_tick = __tick; greg@244: /* signal debugger thread it can read data */ greg@244: ReleaseSemaphore(wait_sem, 1, NULL); greg@229: } greg@244: greg@244: void suspendDebug() greg@244: { greg@247: __DEBUG = 0; greg@244: /* Prevent PLC to enter debug code */ greg@244: WaitForSingleObject(debug_sem, INFINITE); greg@244: } greg@244: greg@244: void resumeDebug() greg@244: { greg@247: __DEBUG = 1; greg@244: /* Let PLC enter debug code */ greg@244: ReleaseSemaphore(debug_sem, 1, NULL); greg@244: }