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 <http://www.gnu.org/licenses/>.
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 <stdio.h>
etisserant@57: #include <sys/timeb.h>
etisserant@57: #include <time.h>
etisserant@57: #include <windows.h>
etisserant@57: #else
etisserant@57: #include <stdio.h>
etisserant@57: #include <string.h>
etisserant@41: #include <time.h>
etisserant@41: #include <signal.h>
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