Added extra sub-state for MS/TP from Addendum 135-2008v. Tested with ports/bdk-atxx4-mstp/ code on the BACnet Development Kit. Clean compile on src/mstp.c, ports/at91sam7s and ports/atmega168, but untested. All other changes were not compiled or tested.

This commit is contained in:
skarg
2010-10-07 15:52:45 +00:00
parent 23eecbc100
commit b54218939e
7 changed files with 99 additions and 23 deletions
+13 -3
View File
@@ -866,9 +866,19 @@ static bool MSTP_Master_Node_FSM(
/* before passing the token. */ /* before passing the token. */
Master_State = MSTP_MASTER_STATE_USE_TOKEN; Master_State = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true; transition_now = true;
} } else if ((MSTP_Flag.SoleMaster == false) &&
/* Npoll changed in Errata SSPC-135-2004 */ (Next_Station == This_Station)) {
else if (TokenCount < (Npoll - 1)) { /* NextStationUnknown - added in Addendum 135-2008v-1 */
/* then the next station to which the token
should be sent is unknown - so PollForMaster */
Poll_Station = next_this_station;
MSTP_Send_Frame(
FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
This_Station, NULL, 0);
RetryCount = 0;
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} else if (TokenCount < (Npoll - 1)) {
/* Npoll changed in Errata SSPC-135-2004 */
if ((MSTP_Flag.SoleMaster == true) && if ((MSTP_Flag.SoleMaster == true) &&
(Next_Station != next_this_station)) { (Next_Station != next_this_station)) {
/* SoleMaster */ /* SoleMaster */
+11
View File
@@ -783,6 +783,17 @@ static bool MSTP_Master_Node_FSM(
/* before passing the token. */ /* before passing the token. */
Master_State = MSTP_MASTER_STATE_USE_TOKEN; Master_State = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true; transition_now = true;
} else if ((MSTP_Flag.SoleMaster == false) &&
(Next_Station == This_Station)) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
/* then the next station to which the token
should be sent is unknown - so PollForMaster */
Poll_Station = next_this_station;
MSTP_Send_Frame(
FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
This_Station, NULL, 0);
RetryCount = 0;
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
/* Npoll changed in Errata SSPC-135-2004 */ /* Npoll changed in Errata SSPC-135-2004 */
else if (TokenCount < (Npoll - 1)) { else if (TokenCount < (Npoll - 1)) {
@@ -888,6 +888,17 @@ static bool MSTP_Master_Node_FSM(
/* before passing the token. */ /* before passing the token. */
Master_State = MSTP_MASTER_STATE_USE_TOKEN; Master_State = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true; transition_now = true;
} else if ((MSTP_Flag.SoleMaster == false) &&
(Next_Station == This_Station)) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
/* then the next station to which the token
should be sent is unknown - so PollForMaster */
Poll_Station = next_this_station;
MSTP_Send_Frame(
FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
This_Station, NULL, 0);
RetryCount = 0;
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
/* Npoll changed in Errata SSPC-135-2004 */ /* Npoll changed in Errata SSPC-135-2004 */
else if (TokenCount < (Npoll - 1)) { else if (TokenCount < (Npoll - 1)) {
+29 -18
View File
@@ -46,7 +46,7 @@
#include "bacaddr.h" #include "bacaddr.h"
/* This file has been customized for use with small microprocessors */ /* This file has been customized for use with small microprocessors */
/* Assumptions: /* Assumptions:
Only one MS/TP datalink layer Only one MS/TP datalink layer
*/ */
#include "timer.h" #include "timer.h"
@@ -121,7 +121,7 @@ static struct mstp_flag_t {
/* A Boolean flag set TRUE by the datalink transmit if a /* A Boolean flag set TRUE by the datalink transmit if a
pending packet is DataExpectingReply */ pending packet is DataExpectingReply */
unsigned TransmitPacketDER:1; unsigned TransmitPacketDER:1;
/* A Boolean flag set TRUE by the datalink if a /* A Boolean flag set TRUE by the datalink if a
packet has been received, but not processed. */ packet has been received, but not processed. */
unsigned ReceivePacketPending:1; unsigned ReceivePacketPending:1;
} MSTP_Flag; } MSTP_Flag;
@@ -287,8 +287,8 @@ static bool dlmstp_compare_data_expecting_reply(
uint8_t dest_address) uint8_t dest_address)
{ {
uint16_t offset; uint16_t offset;
/* One way to check the message is to compare NPDU /* One way to check the message is to compare NPDU
src, dest, along with the APDU type, invoke id. src, dest, along with the APDU type, invoke id.
Seems a bit overkill */ Seems a bit overkill */
struct DER_compare_t { struct DER_compare_t {
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
@@ -327,7 +327,7 @@ static bool dlmstp_compare_data_expecting_reply(
if (reply.npdu_data.network_layer_message) { if (reply.npdu_data.network_layer_message) {
return false; return false;
} }
/* reply could be a lot of things: /* reply could be a lot of things:
confirmed, simple ack, abort, reject, error */ confirmed, simple ack, abort, reject, error */
reply.pdu_type = reply_pdu[offset] & 0xF0; reply.pdu_type = reply_pdu[offset] & 0xF0;
switch (reply.pdu_type) { switch (reply.pdu_type) {
@@ -451,7 +451,7 @@ static void MSTP_Receive_Frame_FSM(
static uint16_t DataCRC = 0; static uint16_t DataCRC = 0;
/* Used to accumulate the CRC on the header of a frame. */ /* Used to accumulate the CRC on the header of a frame. */
static uint8_t HeaderCRC = 0; static uint8_t HeaderCRC = 0;
/* Used as an index by the Receive State Machine, /* Used as an index by the Receive State Machine,
up to a maximum value of the MPDU */ up to a maximum value of the MPDU */
static uint8_t Index = 0; static uint8_t Index = 0;
@@ -473,7 +473,7 @@ static void MSTP_Receive_Frame_FSM(
} }
break; break;
case MSTP_RECEIVE_STATE_PREAMBLE: case MSTP_RECEIVE_STATE_PREAMBLE:
/* In the PREAMBLE state, the node waits for the /* In the PREAMBLE state, the node waits for the
second octet of the preamble. */ second octet of the preamble. */
if (Timer_Silence() > Tframe_abort) { if (Timer_Silence() > Tframe_abort) {
/* Timeout */ /* Timeout */
@@ -553,7 +553,7 @@ static void MSTP_Receive_Frame_FSM(
} else if (Index == 5) { } else if (Index == 5) {
/* HeaderCRC */ /* HeaderCRC */
HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC);
/* In the HEADER_CRC state, the node validates the CRC /* In the HEADER_CRC state, the node validates the CRC
on the fixed message header. */ on the fixed message header. */
if (HeaderCRC != 0x55) { if (HeaderCRC != 0x55) {
/* BadCRC */ /* BadCRC */
@@ -565,7 +565,7 @@ static void MSTP_Receive_Frame_FSM(
} else { } else {
/* Note: proposed change to BACnet MSTP state machine! /* Note: proposed change to BACnet MSTP state machine!
If we don't decode data that is not for us, we could If we don't decode data that is not for us, we could
get confused about the start if the Preamble 55 FF get confused about the start if the Preamble 55 FF
is part of the data. */ is part of the data. */
if ((DataLength) && (DataLength <= InputBufferSize)) { if ((DataLength) && (DataLength <= InputBufferSize)) {
/* Data */ /* Data */
@@ -580,7 +580,7 @@ static void MSTP_Receive_Frame_FSM(
(DestinationAddress == (DestinationAddress ==
MSTP_BROADCAST_ADDRESS)) { MSTP_BROADCAST_ADDRESS)) {
/* ForUs */ /* ForUs */
/* indicate that a frame with /* indicate that a frame with
no data has been received */ no data has been received */
MSTP_Flag.ReceivedValidFrame = true; MSTP_Flag.ReceivedValidFrame = true;
} else { } else {
@@ -617,7 +617,7 @@ static void MSTP_Receive_Frame_FSM(
/* Error */ /* Error */
Timer_Silence_Reset(); Timer_Silence_Reset();
INCREMENT_AND_LIMIT_UINT8(EventCount); INCREMENT_AND_LIMIT_UINT8(EventCount);
/* indicate that an error has occurred during /* indicate that an error has occurred during
the reception of a frame */ the reception of a frame */
MSTP_Flag.ReceivedInvalidFrame = true; MSTP_Flag.ReceivedInvalidFrame = true;
/* wait for the start of the next frame. */ /* wait for the start of the next frame. */
@@ -643,7 +643,7 @@ static void MSTP_Receive_Frame_FSM(
if ((DestinationAddress == This_Station) || if ((DestinationAddress == This_Station) ||
(DestinationAddress == MSTP_BROADCAST_ADDRESS)) { (DestinationAddress == MSTP_BROADCAST_ADDRESS)) {
/* ForUs */ /* ForUs */
/* indicate that a frame with no data /* indicate that a frame with no data
has been received */ has been received */
MSTP_Flag.ReceivedValidFrame = true; MSTP_Flag.ReceivedValidFrame = true;
} }
@@ -766,7 +766,7 @@ static bool MSTP_Master_Node_FSM(
default: default:
break; break;
} }
/* For DATA_EXPECTING_REPLY, we will keep the Rx Frame for /* For DATA_EXPECTING_REPLY, we will keep the Rx Frame for
reference, and the flag will be cleared in the next state */ reference, and the flag will be cleared in the next state */
if (Master_State != MSTP_MASTER_STATE_ANSWER_DATA_REQUEST) { if (Master_State != MSTP_MASTER_STATE_ANSWER_DATA_REQUEST) {
MSTP_Flag.ReceivedValidFrame = false; MSTP_Flag.ReceivedValidFrame = false;
@@ -884,6 +884,17 @@ static bool MSTP_Master_Node_FSM(
/* before passing the token. */ /* before passing the token. */
Master_State = MSTP_MASTER_STATE_USE_TOKEN; Master_State = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true; transition_now = true;
} else if ((MSTP_Flag.SoleMaster == false) &&
(Next_Station == This_Station)) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
/* then the next station to which the token
should be sent is unknown - so PollForMaster */
Poll_Station = next_this_station;
MSTP_Send_Frame(
FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
This_Station, NULL, 0);
RetryCount = 0;
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
/* Npoll changed in Errata SSPC-135-2004 */ /* Npoll changed in Errata SSPC-135-2004 */
else if (TokenCount < (Npoll - 1)) { else if (TokenCount < (Npoll - 1)) {
@@ -1182,7 +1193,7 @@ uint16_t dlmstp_receive(
MSTP_Receive_Frame_FSM(); MSTP_Receive_Frame_FSM();
if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame) if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame)
break; break;
/* if we are not idle, then we are /* if we are not idle, then we are
receiving a frame or timing out */ receiving a frame or timing out */
if (Receive_State == MSTP_RECEIVE_STATE_IDLE) if (Receive_State == MSTP_RECEIVE_STATE_IDLE)
break; break;
@@ -1214,7 +1225,7 @@ void dlmstp_set_mac_address(
This_Station = mac_address; This_Station = mac_address;
/* FIXME: implement your data storage */ /* FIXME: implement your data storage */
/* I2C_Write_Byte( /* I2C_Write_Byte(
EEPROM_DEVICE_ADDRESS, EEPROM_DEVICE_ADDRESS,
mac_address, mac_address,
EEPROM_MSTP_MAC_ADDR); */ EEPROM_MSTP_MAC_ADDR); */
if (mac_address > Nmax_master) if (mac_address > Nmax_master)
@@ -1243,8 +1254,8 @@ void dlmstp_set_max_info_frames(
if (max_info_frames >= 1) { if (max_info_frames >= 1) {
Nmax_info_frames = max_info_frames; Nmax_info_frames = max_info_frames;
/* FIXME: implement your data storage */ /* FIXME: implement your data storage */
/* I2C_Write_Byte( /* I2C_Write_Byte(
EEPROM_DEVICE_ADDRESS, EEPROM_DEVICE_ADDRESS,
(uint8_t)max_info_frames, (uint8_t)max_info_frames,
EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */ EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */
} }
@@ -1271,7 +1282,7 @@ void dlmstp_set_max_master(
Nmax_master = max_master; Nmax_master = max_master;
/* FIXME: implement your data storage */ /* FIXME: implement your data storage */
/* I2C_Write_Byte( /* I2C_Write_Byte(
EEPROM_DEVICE_ADDRESS, EEPROM_DEVICE_ADDRESS,
max_master, max_master,
EEPROM_MSTP_MAX_MASTER_ADDR); */ EEPROM_MSTP_MAX_MASTER_ADDR); */
} }
+11
View File
@@ -799,6 +799,17 @@ bool MSTP_Master_Node_FSM(
/* before passing the token. */ /* before passing the token. */
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true; transition_now = true;
} else if ((MSTP_Flag.SoleMaster == false) &&
(Next_Station == This_Station)) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
/* then the next station to which the token
should be sent is unknown - so PollForMaster */
Poll_Station = next_this_station;
MSTP_Send_Frame(
FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
This_Station, NULL, 0);
RetryCount = 0;
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
/* Npoll changed in Errata SSPC-135-2004 */ /* Npoll changed in Errata SSPC-135-2004 */
else if (mstp_port->TokenCount < (Npoll - 1)) { else if (mstp_port->TokenCount < (Npoll - 1)) {
+13 -2
View File
@@ -474,7 +474,7 @@ void MSTP_Receive_Frame_FSM(
} }
/* NoData */ /* NoData */
else if (mstp_port->DataLength == 0) { else if (mstp_port->DataLength == 0) {
/* CHEAT: it is very difficult to respond to /* CHEAT: it is very difficult to respond to
poll for master in the Master Node state machine poll for master in the Master Node state machine
before Tusage_timeout, so we will do it here. */ before Tusage_timeout, so we will do it here. */
if ((mstp_port->FrameType == if ((mstp_port->FrameType ==
@@ -784,7 +784,7 @@ bool MSTP_Master_Node_FSM(
case FRAME_TYPE_POLL_FOR_MASTER: case FRAME_TYPE_POLL_FOR_MASTER:
/* CHEAT: we cheat a little and this is really handled in the /* CHEAT: we cheat a little and this is really handled in the
receive state machine since it is difficult to respond receive state machine since it is difficult to respond
quick enough (i.e. faster than Tusage_timeout of the quick enough (i.e. faster than Tusage_timeout of the
other node which could be 20ms). */ other node which could be 20ms). */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER,
@@ -938,6 +938,17 @@ bool MSTP_Master_Node_FSM(
/* then this node may send another information frame */ /* then this node may send another information frame */
/* before passing the token. */ /* before passing the token. */
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
} else if ((mstp_port->SoleMaster == false) &&
(mstp_port->Next_Station == mstp_port->This_Station)) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
/* then the next station to which the token
should be sent is unknown - so PollForMaster */
mstp_port->Poll_Station = next_this_station;
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station,
mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
/* Npoll changed in Errata SSPC-135-2004 */ /* Npoll changed in Errata SSPC-135-2004 */
else if (mstp_port->TokenCount < (Npoll - 1)) { else if (mstp_port->TokenCount < (Npoll - 1)) {
+11
View File
@@ -795,6 +795,17 @@ bool MSTP_Master_Node_FSM(
/* before passing the token. */ /* before passing the token. */
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true; transition_now = true;
} else if ((mstp_port->SoleMaster == false) &&
(mstp_port->Next_Station == mstp_port->This_Station)) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
/* then the next station to which the token
should be sent is unknown - so PollForMaster */
mstp_port->Poll_Station = next_this_station;
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station,
mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} else if (mstp_port->TokenCount < (Npoll - 1)) { } else if (mstp_port->TokenCount < (Npoll - 1)) {
/* Npoll changed in Errata SSPC-135-2004 */ /* Npoll changed in Errata SSPC-135-2004 */
if ((mstp_port->SoleMaster == true) && if ((mstp_port->SoleMaster == true) &&