From ade401f44b3fb01f773631bb2109385c70b58930 Mon Sep 17 00:00:00 2001 From: skarg Date: Sat, 30 Jun 2007 22:47:23 +0000 Subject: [PATCH] Modified the MS/TP datalink on Linux to be able to run correctly as a datalink layer when built with the demos. --- bacnet-stack/ports/linux/dlmstp.c | 123 +++++++++++++----------------- bacnet-stack/ports/linux/mstp.c | 6 +- bacnet-stack/ports/linux/rs485.c | 91 +++++++++++----------- bacnet-stack/ports/linux/rs485.h | 1 + 4 files changed, 105 insertions(+), 116 deletions(-) diff --git a/bacnet-stack/ports/linux/dlmstp.c b/bacnet-stack/ports/linux/dlmstp.c index 7ef7f20e..61f9061d 100644 --- a/bacnet-stack/ports/linux/dlmstp.c +++ b/bacnet-stack/ports/linux/dlmstp.c @@ -26,6 +26,7 @@ #include #include #include +#include #if PRINT_ENABLED #include #endif @@ -58,6 +59,21 @@ void dlmstp_millisecond_timer(void) INCREMENT_AND_LIMIT_UINT16(MSTP_Port.SilenceTimer); } +static void *dlmstp_milliseconds_task(void *pArg) +{ + struct timespec timeOut,remains; + + timeOut.tv_sec = 0; + timeOut.tv_nsec = 1000000; /* 1 millisecond */ + + for (;;) { + nanosleep(&timeOut, &remains); + dlmstp_millisecond_timer(); + } + + return NULL; +} + void dlmstp_reinit(void) { //RS485_Reinit(); @@ -66,54 +82,9 @@ void dlmstp_reinit(void) dlmstp_set_max_master(DEFAULT_MAX_MASTER); } -void dlmstp_init(void) -{ - uint8_t data; - - /* initialize buffer */ - Receive_Buffer.ready = false; - Receive_Buffer.pdu_len = 0; - /* initialize hardware */ - RS485_Initialize(); - MSTP_Init(&MSTP_Port); - /* FIXME: implement your data storage */ - 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; -#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 - dlmstp_set_max_info_frames(DEFAULT_MAX_INFO_FRAMES); -} - void dlmstp_cleanup(void) { + RS485_Cleanup(); /* nothing to do for static buffers */ } @@ -342,6 +313,41 @@ void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest) return; } +void dlmstp_init(void) +{ + int rc = 0; + pthread_t hThread; + + /* initialize buffer */ + Receive_Buffer.ready = false; + Receive_Buffer.pdu_len = 0; + /* initialize hardware */ + RS485_Initialize(); + MSTP_Init(&MSTP_Port); +#if 0 + /* FIXME: implement your data storage */ + if (data <= 127) + MSTP_Port.This_Station = data; + else + dlmstp_set_my_address(DEFAULT_MAC_ADDRESS); + if ((data <= 127) && (data >= MSTP_Port.This_Station)) + MSTP_Port.Nmax_master = data; + else + dlmstp_set_max_master(DEFAULT_MAX_MASTER); + if (data >= 1) + MSTP_Port.Nmax_info_frames = data; + else + dlmstp_set_max_info_frames(DEFAULT_MAX_INFO_FRAMES); +#endif + + /* start our MilliSec task */ + rc = pthread_create(&hThread, NULL, dlmstp_milliseconds_task, NULL); + rc = pthread_create(&hThread, NULL, dlmstp_receive_fsm_task, NULL); + rc = pthread_create(&hThread, NULL, dlmstp_master_fsm_task, NULL); + + atexit(dlmstp_cleanup); +} + #ifdef TEST_DLMSTP #include @@ -356,25 +362,8 @@ void npdu_handler( fprintf(stderr, "NPDU: received PDU!\n"); } -void *test_milliseconds_task(void *pArg) -{ - 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(int argc, char *argv[]) { - int rc = 0; - pthread_t hThread; struct timespec timeOut,remains; timeOut.tv_sec = 1; @@ -385,12 +374,10 @@ int main(int argc, char *argv[]) RS485_Set_Interface(argv[1]); } 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); + dlmstp_set_max_info_frames(DEFAULT_MAX_INFO_FRAMES); + dlmstp_set_max_master(DEFAULT_MAX_MASTER); + dlmstp_init(); /* forever task */ for (;;) { #if 0 diff --git a/bacnet-stack/ports/linux/mstp.c b/bacnet-stack/ports/linux/mstp.c index 959c48cc..352fedc9 100644 --- a/bacnet-stack/ports/linux/mstp.c +++ b/bacnet-stack/ports/linux/mstp.c @@ -1203,9 +1203,9 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port) return transition_now; } -/* note: This_Station should be set with the MAC address */ -/* note: Nmax_info_frames should be set */ -/* note: Nmax_master should be set */ +/* note: This_Station assumed to be set with the MAC address */ +/* note: Nmax_info_frames assumed to be set (default=1) */ +/* note: Nmax_master assumed to be set (default=127) */ void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port) { int i; /*loop counter */ diff --git a/bacnet-stack/ports/linux/rs485.c b/bacnet-stack/ports/linux/rs485.c index 7962f63c..51826ead 100644 --- a/bacnet-stack/ports/linux/rs485.c +++ b/bacnet-stack/ports/linux/rs485.c @@ -137,50 +137,6 @@ bool RS485_Set_Baud_Rate(uint32_t baud) return valid; } - -void RS485_Initialize(void) -{ - struct termios newtio; - - /* - Open device for reading and writing. - */ - RS485_Handle = open(RS485_Port_Name, - O_RDWR | O_NOCTTY | O_NDELAY ); - if (RS485_Handle < 0) { - perror(RS485_Port_Name); - exit(-1); - } -#if 0 - /* non blocking for the read */ - fcntl(RS485_Handle, F_SETFL, FNDELAY); -#else - /* effecient blocking for the read */ - fcntl(RS485_Handle, F_SETFL, 0); -#endif - /* save current serial port settings */ - tcgetattr(RS485_Handle,&RS485_oldtio); - /* clear struct for new port settings */ - bzero(&newtio, sizeof(newtio)); - /* - BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed. - CRTSCTS : output hardware flow control (only used if the cable has - all necessary lines. See sect. 7 of Serial-HOWTO) - CS8 : 8n1 (8bit,no parity,1 stopbit) - CLOCAL : local connection, no modem contol - CREAD : enable receiving characters - */ - newtio.c_cflag = RS485_Baud | CS8 | CLOCAL | CREAD; - /* Raw input */ - newtio.c_iflag = 0; - /* Raw output */ - newtio.c_oflag = 0; - /* no processing */ - newtio.c_lflag = 0; - /* activate the settings for the port after flushing I/O */ - tcsetattr(RS485_Handle,TCSAFLUSH,&newtio); -} - /* Transmits a Frame on the wire */ void RS485_Send_Frame( struct mstp_port_struct_t *mstp_port, /* port specific data */ @@ -253,6 +209,52 @@ void RS485_Cleanup(void) close(RS485_Handle); } + +void RS485_Initialize(void) +{ + struct termios newtio; + + /* + Open device for reading and writing. + */ + RS485_Handle = open(RS485_Port_Name, + O_RDWR | O_NOCTTY | O_NDELAY ); + if (RS485_Handle < 0) { + perror(RS485_Port_Name); + exit(-1); + } +#if 0 + /* non blocking for the read */ + fcntl(RS485_Handle, F_SETFL, FNDELAY); +#else + /* effecient blocking for the read */ + fcntl(RS485_Handle, F_SETFL, 0); +#endif + /* save current serial port settings */ + tcgetattr(RS485_Handle,&RS485_oldtio); + /* clear struct for new port settings */ + bzero(&newtio, sizeof(newtio)); + /* + BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed. + CRTSCTS : output hardware flow control (only used if the cable has + all necessary lines. See sect. 7 of Serial-HOWTO) + CS8 : 8n1 (8bit,no parity,1 stopbit) + CLOCAL : local connection, no modem contol + CREAD : enable receiving characters + */ + newtio.c_cflag = RS485_Baud | CS8 | CLOCAL | CREAD; + /* Raw input */ + newtio.c_iflag = 0; + /* Raw output */ + newtio.c_oflag = 0; + /* no processing */ + newtio.c_lflag = 0; + /* activate the settings for the port after flushing I/O */ + tcsetattr(RS485_Handle,TCSAFLUSH,&newtio); + /* destructor */ + atexit(RS485_Cleanup); +} + #ifdef TEST_RS485 #include int main(int argc, char *argv[]) @@ -270,7 +272,6 @@ int main(int argc, char *argv[]) } RS485_Set_Baud_Rate(38400); RS485_Initialize(); - atexit(RS485_Cleanup); for (;;) { written = write(RS485_Handle, wbuf, wlen); diff --git a/bacnet-stack/ports/linux/rs485.h b/bacnet-stack/ports/linux/rs485.h index 2ca3f498..6435fcd3 100644 --- a/bacnet-stack/ports/linux/rs485.h +++ b/bacnet-stack/ports/linux/rs485.h @@ -55,6 +55,7 @@ extern "C" { volatile struct mstp_port_struct_t *mstp_port); /* port specific data */ uint32_t RS485_Get_Baud_Rate(void); bool RS485_Set_Baud_Rate(uint32_t baud); + void RS485_Cleanup(void); #ifdef __cplusplus }