diff --git a/bacnet-stack/demo/mstpcap/Makefile b/bacnet-stack/demo/mstpcap/Makefile index 27039d2d..65e64629 100644 --- a/bacnet-stack/demo/mstpcap/Makefile +++ b/bacnet-stack/demo/mstpcap/Makefile @@ -25,7 +25,7 @@ LIBRARIES=-lc,-lgcc,-lrt,-lm endif ifeq (${BACNET_PORT},win32) TARGET_BIN = ${TARGET}.exe -LIBRARIES=-lws2_32,-lgcc,-lm,-liphlpapi +LIBRARIES=-lws2_32,-lgcc,-lm,-liphlpapi,-lwinmm endif #build for release (default) or debug DEBUGGING = @@ -40,6 +40,7 @@ LFLAGS = -Wl,-Map=$(TARGET).map,$(LIBRARIES),--gc-sections SRCS = main.c \ ${BACNET_PORT_DIR}/rs485.c \ + ${BACNET_PORT_DIR}/timer.c \ ${BACNET_SOURCE_DIR}/mstp.c \ ${BACNET_SOURCE_DIR}/mstptext.c \ ${BACNET_SOURCE_DIR}/debug.c \ diff --git a/bacnet-stack/demo/mstpcap/main.c b/bacnet-stack/demo/mstpcap/main.c index b6548985..9fef27ea 100644 --- a/bacnet-stack/demo/mstpcap/main.c +++ b/bacnet-stack/demo/mstpcap/main.c @@ -41,6 +41,7 @@ #include /* OS specific include*/ #include "net.h" +#include "timer.h" /* local includes */ #include "bytes.h" #include "rs485.h" @@ -48,12 +49,6 @@ #include "mstptext.h" #include "dlmstp.h" -#if defined(__BORLANDC__) -#include -#define _timeb timeb -#define _ftime(param) ftime(param) -#endif - #ifndef max #define max(a,b) (((a) (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) @@ -64,86 +59,26 @@ static volatile struct mstp_port_struct_t MSTP_Port; /* buffers needed by mstp port struct */ static uint8_t RxBuffer[MAX_MPDU]; static uint8_t TxBuffer[MAX_MPDU]; -static uint16_t SilenceTime; -#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;} - -#if defined (_WIN32) -struct timespec { - time_t tv_sec; /* Seconds */ - long tv_nsec; /* Nanoseconds [0 .. 999999999] */ -}; - -static int gettimeofday( - struct timeval *tp, - void *tzp) -{ - struct _timeb timebuffer; - - (void) tzp; - - _ftime(&timebuffer); - tp->tv_sec = timebuffer.time; - tp->tv_usec = timebuffer.millitm * 1000; - - return 0; -} -#endif static uint16_t Timer_Silence( void) { - return SilenceTime; + uint32_t delta_time = 0; + + delta_time = timer_milliseconds(TIMER_SILENCE); + if (delta_time > 0xFFFF) { + delta_time = 0xFFFF; + } + + return (uint16_t)delta_time; } + static void Timer_Silence_Reset( void) { - SilenceTime = 0; + timer_reset(TIMER_SILENCE); } -static void dlmstp_millisecond_timer( - void) -{ - INCREMENT_AND_LIMIT_UINT16(SilenceTime); -} - -#if !defined (_WIN32) -void Sleep( - unsigned long milliseconds) -{ - struct timespec timeOut, remains; - - timeOut.tv_sec = milliseconds / 1000; - timeOut.tv_nsec = (milliseconds - (timeOut.tv_sec * 1000)) * 10000000; - nanosleep(&timeOut, &remains); -} -#endif - -void *milliseconds_task( - void *pArg) -{ - (void) pArg; - - for (;;) { - Sleep(1); - dlmstp_millisecond_timer(); - } - - return NULL; -} - -#if defined(_WIN32) -/************************************************************************* -* Description: Timer task -* Returns: none -* Notes: none -*************************************************************************/ -static void milliseconds_task_win32( - void *pArg) -{ - milliseconds_task(pArg); -} -#endif - /* functions used by the MS/TP state machine to put or get data */ uint16_t MSTP_Put_Receive( volatile struct mstp_port_struct_t *mstp_port) @@ -313,13 +248,6 @@ int main( volatile struct mstp_port_struct_t *mstp_port; long my_baud = 38400; uint32_t packet_count = 0; -#if defined(_WIN32) - unsigned long hThread = 0; - uint32_t arg_value = 0; -#else - int rc = 0; - pthread_t hThread; -#endif /* mimic our pointer in the state machine */ mstp_port = &MSTP_Port; @@ -357,18 +285,6 @@ int main( mstp_port->Lurking = true; fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n", RS485_Interface(), (long) RS485_Get_Baud_Rate()); -#if defined(_WIN32) - hThread = _beginthread(milliseconds_task_win32, 4096, &arg_value); - if (hThread == 0) { - fprintf(stderr, "Failed to start timer task\n"); - } - (void) SetThreadPriority(GetCurrentThread(), - THREAD_PRIORITY_TIME_CRITICAL); -#else - /* start our MilliSec task */ - rc = pthread_create(&hThread, NULL, milliseconds_task, NULL); - signal_init(); -#endif atexit(cleanup); filename_create_new(); /* run forever */ diff --git a/bacnet-stack/demo/mstpcap/makefile.b32 b/bacnet-stack/demo/mstpcap/makefile.b32 index fc62aec6..28141471 100644 --- a/bacnet-stack/demo/mstpcap/makefile.b32 +++ b/bacnet-stack/demo/mstpcap/makefile.b32 @@ -38,7 +38,7 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1 DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) -SRCS = main.c +SRCS = main.c \ OBJS = $(SRCS:.c=.obj) diff --git a/bacnet-stack/ports/linux/timer.c b/bacnet-stack/ports/linux/timer.c new file mode 100644 index 00000000..f3b75e76 --- /dev/null +++ b/bacnet-stack/ports/linux/timer.c @@ -0,0 +1,134 @@ +/************************************************************************** +* +* Copyright (C) 2009 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include "timer.h" + +/* counter for the various timers */ +static volatile uint32_t Millisecond_Counter[MAX_MILLISECOND_TIMERS]; + +/* start time for the clock */ +static struct timespec start; +uint32_t timeGetTime(void) +{ + struct timespec now; + uint32_t ticks; + + clock_gettime(CLOCK_MONOTONIC,&now); + + ticks = (now.tv_sec-start.tv_sec)*1000+ + (now.tv_nsec-start.tv_nsec)/1000000; + + return ticks; +} + +/************************************************************************* +* Description: returns the current millisecond count +* Returns: none +* Notes: none +*************************************************************************/ +uint32_t timer_milliseconds( + unsigned index) +{ + uint32_t now = timeGetTime(); + uint32_t delta_time = 0; + + if (index < MAX_MILLISECOND_TIMERS) { + if (Millisecond_Counter[index] <= now) { + delta_time = now - Millisecond_Counter[index]; + } else { + delta_time = (UINT32_MAX - Millisecond_Counter[index]) + now + 1; + } + } + + return delta_time; +} + +/************************************************************************* +* Description: compares the current time count with a value +* Returns: true if the time has elapsed +* Notes: none +*************************************************************************/ +bool timer_elapsed_milliseconds( + unsigned index, + uint32_t value) +{ + return (timer_milliseconds(index) >= value); +} + +/************************************************************************* +* Description: compares the current time count with a value +* Returns: true if the time has elapsed +* Notes: none +*************************************************************************/ +bool timer_elapsed_seconds( + unsigned index, + uint32_t seconds) +{ + return ((timer_milliseconds(index)/1000) >= seconds); +} + +/************************************************************************* +* Description: compares the current time count with a value +* Returns: true if the time has elapsed +* Notes: none +*************************************************************************/ +bool timer_elapsed_minutes( + unsigned index, + uint32_t minutes) +{ + return ((timer_milliseconds(index)/(1000*60)) >= minutes); +} + +/************************************************************************* +* Description: Sets the timer counter to zero. +* Returns: none +* Notes: none +*************************************************************************/ +uint32_t timer_reset( + unsigned index) +{ + uint32_t timer_value = 0; + + if (index < MAX_MILLISECOND_TIMERS) { + timer_value = timer_milliseconds(index); + Millisecond_Counter[index] = timeGetTime(); + } + + return timer_value; +} + +/************************************************************************* +* Description: Initialization for timer +* Returns: none +* Notes: none +*************************************************************************/ +void timer_init( + void) +{ + clock_gettime(CLOCK_MONOTONIC,&start); +} diff --git a/bacnet-stack/ports/linux/timer.h b/bacnet-stack/ports/linux/timer.h new file mode 100644 index 00000000..2d821cc7 --- /dev/null +++ b/bacnet-stack/ports/linux/timer.h @@ -0,0 +1,63 @@ +/************************************************************************** +* +* Copyright (C) 2009 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*********************************************************************/ +#ifndef TIMER_H +#define TIMER_H + +#include +#include + +/* Timer Module */ +#ifndef MAX_MILLISECOND_TIMERS + #define TIMER_SILENCE 0 + #define MAX_MILLISECOND_TIMERS 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + uint32_t timeGetTime(void); + + void timer_init( + void); + uint32_t timer_milliseconds( + unsigned index); + bool timer_elapsed_milliseconds( + unsigned index, + uint32_t value); + bool timer_elapsed_seconds( + unsigned index, + uint32_t value); + bool timer_elapsed_minutes( + unsigned index, + uint32_t seconds); + uint32_t timer_milliseconds_set( + unsigned index, + uint32_t value); + uint32_t timer_reset( + unsigned index); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/bacnet-stack/ports/win32/timer.c b/bacnet-stack/ports/win32/timer.c new file mode 100644 index 00000000..edd29eb4 --- /dev/null +++ b/bacnet-stack/ports/win32/timer.c @@ -0,0 +1,155 @@ +/************************************************************************** +* +* Copyright (C) 2009 Steve Karg +* Multimedia Timer contribution by Cameron Crothers, 2008 +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#define WIN32_LEAN_AND_MEAN +#define STRICT 1 +#include +#include +#include +#include +#include "timer.h" + +#if defined(__BORLANDC__) +#define _timeb timeb +#define _ftime(param) ftime(param) +#endif + +/* counter for the various timers */ +static volatile uint32_t Millisecond_Counter[MAX_MILLISECOND_TIMERS]; + +/************************************************************************* +* Description: simulate the gettimeofday Linux function +* Returns: none +* Notes: none +*************************************************************************/ +int gettimeofday( + struct timeval *tp, + void *tzp) +{ + struct _timeb timebuffer; + + _ftime(&timebuffer); + tp->tv_sec = timebuffer.time; + tp->tv_usec = timebuffer.millitm * 1000; + + return 0; +} + +/************************************************************************* +* Description: returns the current millisecond count +* Returns: none +* Notes: none +*************************************************************************/ +uint32_t timer_milliseconds( + unsigned index) +{ + uint32_t now = timeGetTime(); + uint32_t delta_time = 0; + + + if (index < MAX_MILLISECOND_TIMERS) { + if (Millisecond_Counter[index] <= now) { + delta_time = now - Millisecond_Counter[index]; + } else { + delta_time = (UINT32_MAX - Millisecond_Counter[index]) + now + 1; + } + } + + return delta_time; +} + +/************************************************************************* +* Description: compares the current time count with a value +* Returns: true if the time has elapsed +* Notes: none +*************************************************************************/ +bool timer_elapsed_milliseconds( + unsigned index, + uint32_t value) +{ + return (timer_milliseconds(index) >= value); +} + +/************************************************************************* +* Description: compares the current time count with a value +* Returns: true if the time has elapsed +* Notes: none +*************************************************************************/ +bool timer_elapsed_seconds( + unsigned index, + uint32_t seconds) +{ + return ((timer_milliseconds(index)/1000) >= seconds); +} + +/************************************************************************* +* Description: compares the current time count with a value +* Returns: true if the time has elapsed +* Notes: none +*************************************************************************/ +bool timer_elapsed_minutes( + unsigned index, + uint32_t minutes) +{ + return ((timer_milliseconds(index)/(1000*60)) >= minutes); +} + +/************************************************************************* +* Description: Sets the timer counter to zero. +* Returns: none +* Notes: none +*************************************************************************/ +uint32_t timer_reset( + unsigned index) +{ + uint32_t timer_value = timer_milliseconds(index); + if (index < MAX_MILLISECOND_TIMERS) { + Millisecond_Counter[index] = timeGetTime(); + } + return timer_value; +} + +/************************************************************************* +* Description: Initialization for timer +* Returns: none +* Notes: none +*************************************************************************/ +void timer_init( + void) +{ + TIMECAPS tc; + uint32_t period; + + /* set timer resolution */ + if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) { + fprintf(stderr, "Failed to get timer resolution parameters\n"); + } + /* configure for 1ms resolution - if possible */ + period = min(max(tc.wPeriodMin, 1), tc.wPeriodMax); + timeBeginPeriod(period); +} diff --git a/bacnet-stack/ports/win32/timer.h b/bacnet-stack/ports/win32/timer.h new file mode 100644 index 00000000..89bbc4a6 --- /dev/null +++ b/bacnet-stack/ports/win32/timer.h @@ -0,0 +1,72 @@ +/************************************************************************** +* +* Copyright (C) 2009 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*********************************************************************/ +#ifndef TIMER_H +#define TIMER_H + +#include +#include + +#define WIN32_LEAN_AND_MEAN +#define STRICT 1 +#include +#include +#include + +/* Timer Module */ +#ifndef MAX_MILLISECOND_TIMERS + #define TIMER_SILENCE 0 + #define MAX_MILLISECOND_TIMERS 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + int gettimeofday( + struct timeval *tp, + void *tzp); + + void timer_init( + void); + uint32_t timer_milliseconds( + unsigned index); + bool timer_elapsed_milliseconds( + unsigned index, + uint32_t value); + bool timer_elapsed_seconds( + unsigned index, + uint32_t value); + bool timer_elapsed_minutes( + unsigned index, + uint32_t seconds); + uint32_t timer_milliseconds_set( + unsigned index, + uint32_t value); + uint32_t timer_reset( + unsigned index); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif