Edouard@279: /* Edouard@279: * matiec - a compiler for the programming languages defined in IEC 61131-3 Edouard@279: * Edouard@279: * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) Edouard@279: * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant Edouard@279: * Edouard@279: * This program is free software: you can redistribute it and/or modify Edouard@279: * it under the terms of the GNU General Public License as published by Edouard@279: * the Free Software Foundation, either version 3 of the License, or Edouard@279: * (at your option) any later version. Edouard@279: * Edouard@279: * This program is distributed in the hope that it will be useful, Edouard@279: * but WITHOUT ANY WARRANTY; without even the implied warranty of Edouard@279: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Edouard@279: * GNU General Public License for more details. Edouard@279: * Edouard@279: * You should have received a copy of the GNU General Public License Edouard@279: * along with this program. If not, see . Edouard@279: * Edouard@279: * Edouard@279: * This code is made available on the understanding that it will not be Edouard@279: * used in safety-critical situations without a full and competent review. Edouard@279: * Edouard@279: * Edouard@279: * Minimal standaloen C runtime, for test purpose. Edouard@279: * TODO : UPDATE Edouard@279: * Edouard@279: */ Edouard@279: etisserant@57: #ifdef __WIN32__ etisserant@57: #include etisserant@57: #include etisserant@57: #include etisserant@57: #include etisserant@57: #else etisserant@57: #include etisserant@57: #include etisserant@41: #include etisserant@41: #include etisserant@57: #endif etisserant@41: lbessard@150: #include "iec_types.h" lbessard@150: etisserant@41: /* etisserant@41: * Functions and variables provied by generated C softPLC etisserant@41: **/ etisserant@41: extern int common_ticktime__; etisserant@41: lbessard@150: IEC_BOOL __DEBUG; lbessard@150: etisserant@41: /* etisserant@57: * Functions and variables provied by plc.c etisserant@57: **/ etisserant@57: void run(long int tv_sec, long int tv_nsec); etisserant@41: etisserant@57: #define maxval(a,b) ((a>b)?a:b) etisserant@41: etisserant@57: #ifdef __WIN32__ etisserant@57: void timer_notify() etisserant@57: { etisserant@57: struct _timeb timebuffer; etisserant@57: etisserant@57: _ftime( &timebuffer ); etisserant@57: run(timebuffer.time, timebuffer.millitm * 1000000); etisserant@57: } etisserant@57: etisserant@57: int main(int argc,char **argv) etisserant@57: { etisserant@57: HANDLE hTimer = NULL; etisserant@57: LARGE_INTEGER liDueTime; etisserant@57: etisserant@57: liDueTime.QuadPart = -10000 * maxval(common_ticktime__,1);; etisserant@57: etisserant@57: // Create a waitable timer. etisserant@57: hTimer = CreateWaitableTimer(NULL, TRUE, "WaitableTimer"); etisserant@57: if (NULL == hTimer) etisserant@57: { etisserant@57: printf("CreateWaitableTimer failed (%d)\n", GetLastError()); etisserant@57: return 1; etisserant@57: } etisserant@57: etisserant@57: config_init__(); etisserant@57: etisserant@57: // Set a timer to wait for 10 seconds. etisserant@57: if (!SetWaitableTimer(hTimer, &liDueTime, common_ticktime__, NULL, NULL, 0)) etisserant@57: { etisserant@57: printf("SetWaitableTimer failed (%d)\n", GetLastError()); etisserant@57: return 2; etisserant@57: } etisserant@57: etisserant@57: while(1){ etisserant@57: // Wait for the timer. etisserant@57: if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0) etisserant@57: { etisserant@57: printf("WaitForSingleObject failed (%d)\n", GetLastError()); etisserant@57: break; etisserant@57: } etisserant@57: timer_notify(); etisserant@57: } etisserant@57: return 0; etisserant@57: } etisserant@57: #else etisserant@41: void timer_notify(sigval_t val) etisserant@41: { etisserant@57: struct timespec CURRENT_TIME; etisserant@57: clock_gettime(CLOCK_REALTIME, &CURRENT_TIME); etisserant@57: run(CURRENT_TIME.tv_sec, CURRENT_TIME.tv_nsec); etisserant@41: } etisserant@41: etisserant@41: void catch_signal(int sig) etisserant@41: { etisserant@41: signal(SIGTERM, catch_signal); etisserant@41: signal(SIGINT, catch_signal); etisserant@41: printf("Got Signal %d\n",sig); etisserant@41: } etisserant@41: etisserant@41: int main(int argc,char **argv) etisserant@41: { etisserant@41: timer_t timer; etisserant@41: struct sigevent sigev; etisserant@41: long tv_nsec = 1000000 * (maxval(common_ticktime__,1)%1000); etisserant@41: time_t tv_sec = common_ticktime__/1000; etisserant@41: struct itimerspec timerValues; etisserant@41: etisserant@41: memset (&sigev, 0, sizeof (struct sigevent)); etisserant@41: memset (&timerValues, 0, sizeof (struct itimerspec)); etisserant@41: sigev.sigev_value.sival_int = 0; etisserant@41: sigev.sigev_notify = SIGEV_THREAD; etisserant@41: sigev.sigev_notify_attributes = NULL; etisserant@41: sigev.sigev_notify_function = timer_notify; etisserant@41: timerValues.it_value.tv_sec = tv_sec; etisserant@41: timerValues.it_value.tv_nsec = tv_nsec; etisserant@41: timerValues.it_interval.tv_sec = tv_sec; etisserant@41: timerValues.it_interval.tv_nsec = tv_nsec; etisserant@41: etisserant@41: config_init__(); etisserant@41: etisserant@41: timer_create (CLOCK_REALTIME, &sigev, &timer); etisserant@41: timer_settime (timer, 0, &timerValues, NULL); etisserant@41: etisserant@41: /* install signal handler for manual break */ etisserant@41: signal(SIGTERM, catch_signal); etisserant@41: signal(SIGINT, catch_signal); etisserant@41: etisserant@41: pause(); etisserant@41: etisserant@41: timer_delete (timer); etisserant@41: etisserant@41: return 0; etisserant@41: } etisserant@57: #endif