From 1824d4a95e1c91a944423b773e93ab48574fd935 Mon Sep 17 00:00:00 2001 From: skarg Date: Fri, 29 Jun 2007 22:46:19 +0000 Subject: [PATCH] Testing the MS/TP datalink layer on Linux. --- bacnet-stack/ports/linux/dlmstp.c | 156 ++++++++++++---------------- bacnet-stack/ports/linux/dlmstp.mak | 33 ++++++ bacnet-stack/ports/linux/rs485.c | 2 + bacnet-stack/ports/linux/rx_fsm.c | 7 +- bacnet-stack/ports/win32/dlmstp.c | 2 +- 5 files changed, 105 insertions(+), 95 deletions(-) create mode 100644 bacnet-stack/ports/linux/dlmstp.mak diff --git a/bacnet-stack/ports/linux/dlmstp.c b/bacnet-stack/ports/linux/dlmstp.c index e9725e45..f0aa8b26 100644 --- a/bacnet-stack/ports/linux/dlmstp.c +++ b/bacnet-stack/ports/linux/dlmstp.c @@ -29,16 +29,19 @@ #if PRINT_ENABLED #include #endif +/* Linux Includes */ +#include +#include +#include +#include +#include +/* project includes */ #include "bacdef.h" #include "mstp.h" #include "dlmstp.h" #include "rs485.h" #include "npdu.h" -#define WIN32_LEAN_AND_MEAN -#define STRICT 1 -#include - /* Number of MS/TP Packets Rx/Tx */ uint16_t MSTP_Packets = 0; @@ -72,29 +75,37 @@ void dlmstp_init(void) Receive_Buffer.pdu_len = 0; /* initialize hardware */ RS485_Initialize(); - MSTP_Port.InputBuffer = &Receive_Buffer.pdu[0]; MSTP_Init(&MSTP_Port); /* FIXME: implement your data storage */ - data = 64; /* I2C_Read_Byte( - EEPROM_DEVICE_ADDRESS, - EEPROM_MSTP_MAC_ADDR); */ + data = 64; +#if 0 + /* I2C_Read_Byte( + EEPROM_DEVICE_ADDRESS, + EEPROM_MSTP_MAC_ADDR); */ +#endif if (data <= 127) MSTP_Port.This_Station = data; else dlmstp_set_my_address(DEFAULT_MAC_ADDRESS); + /* FIXME: implement your data storage */ - data = 127; /* I2C_Read_Byte( - EEPROM_DEVICE_ADDRESS, - EEPROM_MSTP_MAX_MASTER_ADDR); */ + data = 127; +#if 0 + /* I2C_Read_Byte( + EEPROM_DEVICE_ADDRESS, + EEPROM_MSTP_MAX_MASTER_ADDR); */ +#endif if ((data <= 127) && (data >= MSTP_Port.This_Station)) MSTP_Port.Nmax_master = data; else dlmstp_set_max_master(DEFAULT_MAX_MASTER); /* FIXME: implement your data storage */ data = 1; +#if 0 /* I2C_Read_Byte( EEPROM_DEVICE_ADDRESS, EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */ +#endif if (data >= 1) MSTP_Port.Nmax_info_frames = data; else @@ -146,13 +157,12 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */ return bytes_sent; } -static void dlmstp_receive_fsm_task(void *pArg) +static void *dlmstp_receive_fsm_task(void *pArg) { uint8_t bytes_remaining; bool received_frame; - //(void)SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - while (TRUE) { + for (;;) { /* only do receive state machine while we don't have a frame */ if ((MSTP_Port.ReceivedValidFrame == false) && (MSTP_Port.ReceivedInvalidFrame == false)) { @@ -168,14 +178,13 @@ static void dlmstp_receive_fsm_task(void *pArg) } } -static void dlmstp_master_fsm_task(void *pArg) +static void *dlmstp_master_fsm_task(void *pArg) { - //(void)SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - while (TRUE) { + for (;;) { /* only do master state machine while rx is idle */ if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE) { while (MSTP_Master_Node_FSM(&MSTP_Port)) { - Sleep(1); + sched_yield(); }; } /* see if there is a packet available, and a place @@ -335,6 +344,7 @@ void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest) #ifdef TEST_DLMSTP #include + void npdu_handler( BACNET_ADDRESS * src, /* source address */ uint8_t * pdu, /* PDU data */ @@ -346,86 +356,50 @@ void npdu_handler( fprintf(stderr, "NPDU: received PDU!\n"); } -static void test_transmit_task(void *pArg) +void *test_milliseconds_task(void *pArg) { - while (TRUE) { - Sleep(1000); + struct timespec timeOut,remains; + + timeOut.tv_sec = 0; + timeOut.tv_nsec = 1000000; /* 1 millisecond */ + + for (;;) { + nanosleep(&timeOut, &remains); + dlmstp_millisecond_timer(); + } + + return NULL; +} + +int main(void) +{ + int rc = 0; + pthread_t hThread; + struct timespec timeOut,remains; + + timeOut.tv_sec = 1; + timeOut.tv_nsec = 0; /* 1 millisecond */ + + /* initialize our interface */ + RS485_Set_Interface("/dev/ttyS0"); + RS485_Set_Baud_Rate(38400); + dlmstp_init(); + dlmstp_set_my_address(0x05); + /* start our MilliSec task */ + rc = pthread_create(&hThread, NULL, test_milliseconds_task, NULL); + rc = pthread_create(&hThread, NULL, dlmstp_receive_fsm_task, NULL); + rc = pthread_create(&hThread, NULL, dlmstp_master_fsm_task, NULL); + /* forever task */ + for (;;) { +#if 0 MSTP_Create_And_Send_Frame( &MSTP_Port, FRAME_TYPE_TEST_REQUEST, MSTP_Port.SourceAddress, MSTP_Port.This_Station, NULL, 0); - } -} - -/* returns a delta timestamp */ -uint32_t timestamp_ms(void) -{ - DWORD ticks = 0, delta_ticks = 0; - static DWORD last_ticks = 0; - - ticks = GetTickCount(); - delta_ticks = - (ticks >= last_ticks ? - ticks - last_ticks : - MAXDWORD - last_ticks); - last_ticks = ticks; - - return delta_ticks; -} - -static void test_millisecond_task(void *pArg) -{ - DWORD ticks = 0; - DWORD last_ticks = GetTickCount(); - DWORD total_ticks = 0; - - (void)SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - while (TRUE) { - ticks = GetTickCount(); - if (ticks > last_ticks) { - total_ticks = ticks - last_ticks; - } else if (ticks == last_ticks) { - Sleep(1); - continue; - } else { - /* integer rollover */ - total_ticks = (MAXDWORD - last_ticks) + ticks; - } - while (total_ticks) { - dlmstp_millisecond_timer(); - total_ticks--; - } - last_ticks = ticks; - Sleep(1); - } -} - -int main(void) -{ - unsigned long hThread = 0; - uint32_t arg_value = 0; - - RS485_Set_Interface("COM4"); - RS485_Set_Baud_Rate(38400); - dlmstp_set_my_address(0x05); - dlmstp_init(); - hThread = _beginthread(test_millisecond_task,4096,&arg_value); - if (hThread == 0) { - fprintf(stderr, "Failed to start timer task\n"); - } - hThread = _beginthread(dlmstp_receive_fsm_task,4096,&arg_value); - if (hThread == 0) { - fprintf(stderr, "Failed to start recive FSM task\n"); - } - hThread = _beginthread(dlmstp_master_fsm_task,4096,&arg_value); - if (hThread == 0) { - fprintf(stderr, "Failed to start Master Node FSM task\n"); - } - /* forever task */ - for (;;) { - Sleep(10000); +#endif + nanosleep(&timeOut, &remains); } return 0; diff --git a/bacnet-stack/ports/linux/dlmstp.mak b/bacnet-stack/ports/linux/dlmstp.mak new file mode 100644 index 00000000..bce20b9f --- /dev/null +++ b/bacnet-stack/ports/linux/dlmstp.mak @@ -0,0 +1,33 @@ +#Makefile to build test case +CC = gcc +BASEDIR = . +# -g for debugging with gdb +DEFINES = -DBIG_ENDIAN=0 -DBACDL_MSTP=1 -DTEST_DLMSTP +INCLUDES = -I. -I../../ +CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g + +SRCS = rs485.c \ + dlmstp.c \ + mstp.c \ + ../../crc.c + +OBJS = ${SRCS:.c=.o} + +TARGET = dlmstp + +all: ${TARGET} + +${TARGET}: ${OBJS} + ${CC} -pthread -o $@ ${OBJS} + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +clean: + rm -rf core ${TARGET} $(OBJS) *.bak *.1 *.ini + +include: .depend diff --git a/bacnet-stack/ports/linux/rs485.c b/bacnet-stack/ports/linux/rs485.c index e09ade48..f26aab13 100644 --- a/bacnet-stack/ports/linux/rs485.c +++ b/bacnet-stack/ports/linux/rs485.c @@ -49,6 +49,7 @@ #include #include #include +#include /* Local includes */ #include "mstp.h" @@ -201,6 +202,7 @@ void RS485_Send_Frame( turnaround_time = 1; while (mstp_port->SilenceTimer < turnaround_time) { /* do nothing - wait for timer to increment */ + sched_yield(); }; } /* diff --git a/bacnet-stack/ports/linux/rx_fsm.c b/bacnet-stack/ports/linux/rx_fsm.c index 9af75259..9c9c0284 100644 --- a/bacnet-stack/ports/linux/rx_fsm.c +++ b/bacnet-stack/ports/linux/rx_fsm.c @@ -86,6 +86,7 @@ uint16_t dlmstp_put_receive( return 0; } +#if 1 static const uint8_t CRC_Table[256] = { 0000, 0xfe, 0xff, 0x01, 0xfd, 0x03, 0x02, 0xfc, @@ -122,7 +123,7 @@ static const uint8_t CRC_Table[256] = 0xa9, 0x57, 0x56, 0xa8, 0x54, 0xaa, 0xab, 0x55 }; -static uint8_t calculate_header_CRC_table( +static uint8_t calculate_header_CRC( volatile struct mstp_port_struct_t *mstp_port) { uint8_t crc8 = 0xFF; /* used to calculate the crc value */ @@ -136,6 +137,7 @@ static uint8_t calculate_header_CRC_table( return (~crc8); } +#else static uint8_t calculate_header_CRC( volatile struct mstp_port_struct_t *mstp_port) { @@ -149,6 +151,7 @@ static uint8_t calculate_header_CRC( return (~crc8); } +#endif static void print_received_packet( volatile struct mstp_port_struct_t *mstp_port, @@ -178,8 +181,6 @@ static void print_received_packet( if (print_crc_flag) { crc8 = calculate_header_CRC(mstp_port); fprintf(stderr, "[%02X] ", crc8); - crc8 = calculate_header_CRC_table(mstp_port); - fprintf(stderr, "[%02X] ", crc8); } if (mstp_port->DataLength) { for (i = 0; i < mstp_port->DataLength; i++) { diff --git a/bacnet-stack/ports/win32/dlmstp.c b/bacnet-stack/ports/win32/dlmstp.c index e9725e45..cab25b4f 100644 --- a/bacnet-stack/ports/win32/dlmstp.c +++ b/bacnet-stack/ports/win32/dlmstp.c @@ -409,8 +409,8 @@ int main(void) RS485_Set_Interface("COM4"); RS485_Set_Baud_Rate(38400); - dlmstp_set_my_address(0x05); dlmstp_init(); + dlmstp_set_my_address(0x05); hThread = _beginthread(test_millisecond_task,4096,&arg_value); if (hThread == 0) { fprintf(stderr, "Failed to start timer task\n");