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