Corrected race condition where the MS/TP Master Node FSM may miss the first packet since it may not run until after the first packet has arrived if the ReceivedValidFrame flag is set to false during MSTP_MASTER_STATE_INITIALIZE. Thank you to anand!
This commit is contained in:
@@ -704,8 +704,6 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
/* receives the token */
|
||||
TokenCount = Npoll;
|
||||
MSTP_Flag.SoleMaster = false;
|
||||
MSTP_Flag.ReceivedValidFrame = false;
|
||||
MSTP_Flag.ReceivedInvalidFrame = false;
|
||||
Master_State = MSTP_MASTER_STATE_IDLE;
|
||||
transition_now = true;
|
||||
break;
|
||||
|
||||
@@ -622,8 +622,6 @@ static bool MSTP_Master_Node_FSM(void)
|
||||
/* receives the token */
|
||||
TokenCount = Npoll;
|
||||
MSTP_Flag.SoleMaster = false;
|
||||
MSTP_Flag.ReceivedValidFrame = false;
|
||||
MSTP_Flag.ReceivedInvalidFrame = false;
|
||||
Master_State = MSTP_MASTER_STATE_IDLE;
|
||||
transition_now = true;
|
||||
break;
|
||||
|
||||
@@ -600,8 +600,6 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
/* receives the token */
|
||||
mstp_port->TokenCount = Npoll;
|
||||
mstp_port->SoleMaster = false;
|
||||
mstp_port->ReceivedValidFrame = false;
|
||||
mstp_port->ReceivedInvalidFrame = false;
|
||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
||||
transition_now = true;
|
||||
break;
|
||||
@@ -1134,469 +1132,3 @@ void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "ctest.h"
|
||||
|
||||
/* test stub functions */
|
||||
void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port specific data */
|
||||
uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
|
||||
uint16_t nbytes)
|
||||
{ /* number of bytes of data (up to 501) */
|
||||
(void) mstp_port;
|
||||
(void) buffer;
|
||||
(void) nbytes;
|
||||
}
|
||||
|
||||
#define RING_BUFFER_DATA_SIZE 1
|
||||
#define RING_BUFFER_SIZE MAX_MPDU
|
||||
static RING_BUFFER Test_Buffer;
|
||||
static uint8_t Test_Buffer_Data[RING_BUFFER_DATA_SIZE * RING_BUFFER_SIZE];
|
||||
static void Load_Input_Buffer(uint8_t * buffer, size_t len)
|
||||
{
|
||||
static bool initialized = false; /* tracks our init */
|
||||
|
||||
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
Ringbuf_Init(&Test_Buffer,
|
||||
(char *) Test_Buffer_Data,
|
||||
RING_BUFFER_DATA_SIZE, RING_BUFFER_SIZE);
|
||||
}
|
||||
/* empty any the existing data */
|
||||
while (!Ringbuf_Empty(&Test_Buffer)) {
|
||||
(void) Ringbuf_Pop_Front(&Test_Buffer);
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
while (len) {
|
||||
(void) Ringbuf_Put(&Test_Buffer, (char *) buffer);
|
||||
len--;
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
|
||||
{ /* port specific data */
|
||||
char *data;
|
||||
if (!Ringbuf_Empty(&Test_Buffer) && mstp_port &&
|
||||
(mstp_port->DataAvailable == false)) {
|
||||
data = Ringbuf_Pop_Front(&Test_Buffer);
|
||||
if (data) {
|
||||
mstp_port->DataRegister = *data;
|
||||
mstp_port->DataAvailable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testReceiveNodeFSM(Test * pTest)
|
||||
{
|
||||
volatile struct mstp_port_struct_t mstp_port; /* port data */
|
||||
unsigned EventCount = 0; /* local counter */
|
||||
uint8_t my_mac = 0x05; /* local MAC address */
|
||||
uint8_t HeaderCRC = 0; /* for local CRC calculation */
|
||||
uint8_t FrameType = 0; /* type of packet that was sent */
|
||||
unsigned len; /* used for the size of the message packet */
|
||||
size_t i; /* used to loop through the message bytes */
|
||||
uint8_t buffer[MAX_MPDU] = { 0 };
|
||||
uint8_t data[MAX_MPDU - 8 /*header */ - 2 /*CRC*/] = { 0 };
|
||||
|
||||
MSTP_Init(&mstp_port, my_mac);
|
||||
|
||||
/* check the receive error during idle */
|
||||
mstp_port.receive_state = MSTP_RECEIVE_STATE_IDLE;
|
||||
mstp_port.ReceiveError = true;
|
||||
mstp_port.SilenceTimer = 255;
|
||||
mstp_port.EventCount = 0;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.ReceiveError == false);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for bad packet header */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x11;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for good packet header, but timeout */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
/* force the timeout */
|
||||
mstp_port.SilenceTimer = Tframe_abort + 1;
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for good packet header preamble, but receive error */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
/* force the error */
|
||||
mstp_port.ReceiveError = true;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceiveError == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for good packet header preamble1, but bad preamble2 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
/* no change of state if no data yet */
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
/* repeated preamble1 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
/* repeated preamble1 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
/* bad data */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x11;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceiveError == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for good packet header preamble, but timeout in packet */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
/* preamble2 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0xFF;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 0);
|
||||
ct_test(pTest, mstp_port.HeaderCRC == 0xFF);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
/* force the timeout */
|
||||
mstp_port.SilenceTimer = Tframe_abort + 1;
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
ct_test(pTest, mstp_port.ReceivedInvalidFrame == true);
|
||||
|
||||
/* check for good packet header preamble, but error in packet */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
/* preamble2 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0xFF;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 0);
|
||||
ct_test(pTest, mstp_port.HeaderCRC == 0xFF);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
/* force the error */
|
||||
mstp_port.ReceiveError = true;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceiveError == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for good packet header preamble */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
/* preamble2 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0xFF;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 0);
|
||||
ct_test(pTest, mstp_port.HeaderCRC == 0xFF);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
/* no change of state if no data yet */
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
/* Data is received - index is incremented */
|
||||
/* FrameType */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = FRAME_TYPE_TOKEN;
|
||||
HeaderCRC = 0xFF;
|
||||
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 1);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
ct_test(pTest, FrameType == FRAME_TYPE_TOKEN);
|
||||
/* Destination */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x10;
|
||||
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 2);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
ct_test(pTest, mstp_port.DestinationAddress == 0x10);
|
||||
/* Source */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = my_mac;
|
||||
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 3);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
ct_test(pTest, mstp_port.SourceAddress == my_mac);
|
||||
/* Length1 = length*256 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0;
|
||||
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 4);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
ct_test(pTest, mstp_port.DataLength == 0);
|
||||
/* Length2 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0;
|
||||
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 5);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
ct_test(pTest, mstp_port.DataLength == 0);
|
||||
/* HeaderCRC */
|
||||
mstp_port.DataAvailable = true;
|
||||
ct_test(pTest, HeaderCRC == 0x73); /* per Annex G example */
|
||||
mstp_port.DataRegister = ~HeaderCRC; /* one's compliment of CRC is sent */
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 5);
|
||||
ct_test(pTest,
|
||||
mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC);
|
||||
ct_test(pTest, mstp_port.HeaderCRC == 0x55);
|
||||
/* NotForUs */
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* BadCRC in header check */
|
||||
mstp_port.ReceivedInvalidFrame = false;
|
||||
mstp_port.ReceivedValidFrame = false;
|
||||
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, 0x10, /* destination */
|
||||
my_mac, /* source */
|
||||
NULL, /* data */
|
||||
0); /* data size */
|
||||
ct_test(pTest, len > 0);
|
||||
/* make the header CRC bad */
|
||||
buffer[7] = 0x00;
|
||||
Load_Input_Buffer(buffer, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
RS485_Check_UART_Data(&mstp_port);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
}
|
||||
ct_test(pTest,
|
||||
mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceivedInvalidFrame == true);
|
||||
ct_test(pTest, mstp_port.ReceivedValidFrame == false);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* NoData for us */
|
||||
mstp_port.ReceivedInvalidFrame = false;
|
||||
mstp_port.ReceivedValidFrame = false;
|
||||
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, my_mac, /* destination */
|
||||
my_mac, /* source */
|
||||
NULL, /* data */
|
||||
0); /* data size */
|
||||
ct_test(pTest, len > 0);
|
||||
Load_Input_Buffer(buffer, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
RS485_Check_UART_Data(&mstp_port);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
}
|
||||
ct_test(pTest,
|
||||
mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceivedInvalidFrame == false);
|
||||
ct_test(pTest, mstp_port.ReceivedValidFrame == true);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* FrameTooLong */
|
||||
mstp_port.ReceivedInvalidFrame = false;
|
||||
mstp_port.ReceivedValidFrame = false;
|
||||
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, my_mac, /* destination */
|
||||
my_mac, /* source */
|
||||
NULL, /* data */
|
||||
0); /* data size */
|
||||
ct_test(pTest, len > 0);
|
||||
/* make the header data length bad */
|
||||
buffer[5] = 0x02;
|
||||
Load_Input_Buffer(buffer, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
RS485_Check_UART_Data(&mstp_port);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
}
|
||||
ct_test(pTest,
|
||||
mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceivedInvalidFrame == true);
|
||||
ct_test(pTest, mstp_port.ReceivedValidFrame == false);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* Data */
|
||||
mstp_port.ReceivedInvalidFrame = false;
|
||||
mstp_port.ReceivedValidFrame = false;
|
||||
memset(data, 0, sizeof(data));
|
||||
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_PROPRIETARY_MIN, my_mac, /* destination */
|
||||
my_mac, /* source */
|
||||
data, /* data */
|
||||
sizeof(data)); /* data size */
|
||||
ct_test(pTest, len > 0);
|
||||
Load_Input_Buffer(buffer, len);
|
||||
RS485_Check_UART_Data(&mstp_port);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
while (mstp_port.receive_state != MSTP_RECEIVE_STATE_IDLE) {
|
||||
RS485_Check_UART_Data(&mstp_port);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
}
|
||||
ct_test(pTest, mstp_port.DataLength == sizeof(data));
|
||||
ct_test(pTest, mstp_port.ReceivedInvalidFrame == false);
|
||||
ct_test(pTest, mstp_port.ReceivedValidFrame == true);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void testMasterNodeFSM(Test * pTest)
|
||||
{
|
||||
volatile struct mstp_port_struct_t mstp_port; /* port data */
|
||||
uint8_t my_mac = 0x05; /* local MAC address */
|
||||
|
||||
MSTP_Init(&mstp_port, my_mac);
|
||||
ct_test(pTest, mstp_port.master_state == MSTP_MASTER_STATE_INITIALIZE);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST_MSTP
|
||||
int main(void)
|
||||
{
|
||||
Test *pTest;
|
||||
bool rc;
|
||||
|
||||
pTest = ct_create("mstp", NULL);
|
||||
|
||||
/* individual tests */
|
||||
rc = ct_addTestFunction(pTest, testReceiveNodeFSM);
|
||||
assert(rc);
|
||||
rc = ct_addTestFunction(pTest, testMasterNodeFSM);
|
||||
assert(rc);
|
||||
|
||||
ct_setStream(pTest, stdout);
|
||||
ct_run(pTest);
|
||||
(void) ct_report(pTest);
|
||||
|
||||
ct_destroy(pTest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -734,8 +734,6 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
/* receives the token */
|
||||
mstp_port->TokenCount = Npoll;
|
||||
mstp_port->SoleMaster = false;
|
||||
mstp_port->ReceivedValidFrame = false;
|
||||
mstp_port->ReceivedInvalidFrame = false;
|
||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
||||
transition_now = true;
|
||||
break;
|
||||
@@ -1268,468 +1266,3 @@ void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "ctest.h"
|
||||
|
||||
/* test stub functions */
|
||||
void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port specific data */
|
||||
uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
|
||||
uint16_t nbytes)
|
||||
{ /* number of bytes of data (up to 501) */
|
||||
(void) mstp_port;
|
||||
(void) buffer;
|
||||
(void) nbytes;
|
||||
}
|
||||
|
||||
#define RING_BUFFER_DATA_SIZE 1
|
||||
#define RING_BUFFER_SIZE MAX_MPDU
|
||||
static RING_BUFFER Test_Buffer;
|
||||
static uint8_t Test_Buffer_Data[RING_BUFFER_DATA_SIZE * RING_BUFFER_SIZE];
|
||||
static void Load_Input_Buffer(uint8_t * buffer, size_t len)
|
||||
{
|
||||
static bool initialized = false; /* tracks our init */
|
||||
|
||||
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
Ringbuf_Init(&Test_Buffer,
|
||||
(char *) Test_Buffer_Data,
|
||||
RING_BUFFER_DATA_SIZE, RING_BUFFER_SIZE);
|
||||
}
|
||||
/* empty any the existing data */
|
||||
while (!Ringbuf_Empty(&Test_Buffer)) {
|
||||
(void) Ringbuf_Pop_Front(&Test_Buffer);
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
while (len) {
|
||||
(void) Ringbuf_Put(&Test_Buffer, (char *) buffer);
|
||||
len--;
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
|
||||
{ /* port specific data */
|
||||
char *data;
|
||||
if (!Ringbuf_Empty(&Test_Buffer) && mstp_port &&
|
||||
(mstp_port->DataAvailable == false)) {
|
||||
data = Ringbuf_Pop_Front(&Test_Buffer);
|
||||
if (data) {
|
||||
mstp_port->DataRegister = *data;
|
||||
mstp_port->DataAvailable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testReceiveNodeFSM(Test * pTest)
|
||||
{
|
||||
volatile struct mstp_port_struct_t mstp_port; /* port data */
|
||||
unsigned EventCount = 0; /* local counter */
|
||||
uint8_t my_mac = 0x05; /* local MAC address */
|
||||
uint8_t HeaderCRC = 0; /* for local CRC calculation */
|
||||
uint8_t FrameType = 0; /* type of packet that was sent */
|
||||
unsigned len; /* used for the size of the message packet */
|
||||
size_t i; /* used to loop through the message bytes */
|
||||
uint8_t buffer[MAX_MPDU] = { 0 };
|
||||
uint8_t data[MAX_MPDU - 8 /*header */ - 2 /*CRC*/] = { 0 };
|
||||
|
||||
MSTP_Init(&mstp_port, my_mac);
|
||||
|
||||
/* check the receive error during idle */
|
||||
mstp_port.receive_state = MSTP_RECEIVE_STATE_IDLE;
|
||||
mstp_port.ReceiveError = true;
|
||||
mstp_port.SilenceTimer = 255;
|
||||
mstp_port.EventCount = 0;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.ReceiveError == false);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for bad packet header */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x11;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for good packet header, but timeout */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
/* force the timeout */
|
||||
mstp_port.SilenceTimer = Tframe_abort + 1;
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for good packet header preamble, but receive error */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
/* force the error */
|
||||
mstp_port.ReceiveError = true;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceiveError == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for good packet header preamble1, but bad preamble2 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
/* no change of state if no data yet */
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
/* repeated preamble1 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
/* repeated preamble1 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
/* bad data */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x11;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceiveError == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for good packet header preamble, but timeout in packet */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
/* preamble2 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0xFF;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 0);
|
||||
ct_test(pTest, mstp_port.HeaderCRC == 0xFF);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
/* force the timeout */
|
||||
mstp_port.SilenceTimer = Tframe_abort + 1;
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
ct_test(pTest, mstp_port.ReceivedInvalidFrame == true);
|
||||
|
||||
/* check for good packet header preamble, but error in packet */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
/* preamble2 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0xFF;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 0);
|
||||
ct_test(pTest, mstp_port.HeaderCRC == 0xFF);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
/* force the error */
|
||||
mstp_port.ReceiveError = true;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceiveError == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* check for good packet header preamble */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x55;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
/* preamble2 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0xFF;
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 0);
|
||||
ct_test(pTest, mstp_port.HeaderCRC == 0xFF);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
/* no change of state if no data yet */
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
/* Data is received - index is incremented */
|
||||
/* FrameType */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = FRAME_TYPE_TOKEN;
|
||||
HeaderCRC = 0xFF;
|
||||
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 1);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
ct_test(pTest, FrameType == FRAME_TYPE_TOKEN);
|
||||
/* Destination */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0x10;
|
||||
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 2);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
ct_test(pTest, mstp_port.DestinationAddress == 0x10);
|
||||
/* Source */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = my_mac;
|
||||
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 3);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
ct_test(pTest, mstp_port.SourceAddress == my_mac);
|
||||
/* Length1 = length*256 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0;
|
||||
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 4);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
ct_test(pTest, mstp_port.DataLength == 0);
|
||||
/* Length2 */
|
||||
mstp_port.DataAvailable = true;
|
||||
mstp_port.DataRegister = 0;
|
||||
HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister, HeaderCRC);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 5);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER);
|
||||
ct_test(pTest, mstp_port.DataLength == 0);
|
||||
/* HeaderCRC */
|
||||
mstp_port.DataAvailable = true;
|
||||
ct_test(pTest, HeaderCRC == 0x73); /* per Annex G example */
|
||||
mstp_port.DataRegister = ~HeaderCRC; /* one's compliment of CRC is sent */
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
ct_test(pTest, mstp_port.Index == 5);
|
||||
ct_test(pTest,
|
||||
mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC);
|
||||
ct_test(pTest, mstp_port.HeaderCRC == 0x55);
|
||||
/* NotForUs */
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* BadCRC in header check */
|
||||
mstp_port.ReceivedInvalidFrame = false;
|
||||
mstp_port.ReceivedValidFrame = false;
|
||||
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, 0x10, /* destination */
|
||||
my_mac, /* source */
|
||||
NULL, /* data */
|
||||
0); /* data size */
|
||||
ct_test(pTest, len > 0);
|
||||
/* make the header CRC bad */
|
||||
buffer[7] = 0x00;
|
||||
Load_Input_Buffer(buffer, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
RS485_Check_UART_Data(&mstp_port);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
}
|
||||
ct_test(pTest,
|
||||
mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceivedInvalidFrame == true);
|
||||
ct_test(pTest, mstp_port.ReceivedValidFrame == false);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* NoData for us */
|
||||
mstp_port.ReceivedInvalidFrame = false;
|
||||
mstp_port.ReceivedValidFrame = false;
|
||||
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, my_mac, /* destination */
|
||||
my_mac, /* source */
|
||||
NULL, /* data */
|
||||
0); /* data size */
|
||||
ct_test(pTest, len > 0);
|
||||
Load_Input_Buffer(buffer, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
RS485_Check_UART_Data(&mstp_port);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
}
|
||||
ct_test(pTest,
|
||||
mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceivedInvalidFrame == false);
|
||||
ct_test(pTest, mstp_port.ReceivedValidFrame == true);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* FrameTooLong */
|
||||
mstp_port.ReceivedInvalidFrame = false;
|
||||
mstp_port.ReceivedValidFrame = false;
|
||||
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_TOKEN, my_mac, /* destination */
|
||||
my_mac, /* source */
|
||||
NULL, /* data */
|
||||
0); /* data size */
|
||||
ct_test(pTest, len > 0);
|
||||
/* make the header data length bad */
|
||||
buffer[5] = 0x02;
|
||||
Load_Input_Buffer(buffer, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
RS485_Check_UART_Data(&mstp_port);
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.DataAvailable == false);
|
||||
ct_test(pTest, mstp_port.SilenceTimer == 0);
|
||||
ct_test(pTest, mstp_port.EventCount == EventCount);
|
||||
}
|
||||
ct_test(pTest,
|
||||
mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
ct_test(pTest, mstp_port.ReceivedInvalidFrame == true);
|
||||
ct_test(pTest, mstp_port.ReceivedValidFrame == false);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
/* Data */
|
||||
mstp_port.ReceivedInvalidFrame = false;
|
||||
mstp_port.ReceivedValidFrame = false;
|
||||
memset(data, 0, sizeof(data));
|
||||
len = MSTP_Create_Frame(buffer, sizeof(buffer), FRAME_TYPE_PROPRIETARY_MIN, my_mac, /* destination */
|
||||
my_mac, /* source */
|
||||
data, /* data */
|
||||
sizeof(data)); /* data size */
|
||||
ct_test(pTest, len > 0);
|
||||
Load_Input_Buffer(buffer, len);
|
||||
RS485_Check_UART_Data(&mstp_port);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
while (mstp_port.receive_state != MSTP_RECEIVE_STATE_IDLE) {
|
||||
RS485_Check_UART_Data(&mstp_port);
|
||||
MSTP_Receive_Frame_FSM(&mstp_port);
|
||||
}
|
||||
ct_test(pTest, mstp_port.DataLength == sizeof(data));
|
||||
ct_test(pTest, mstp_port.ReceivedInvalidFrame == false);
|
||||
ct_test(pTest, mstp_port.ReceivedValidFrame == true);
|
||||
ct_test(pTest, mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void testMasterNodeFSM(Test * pTest)
|
||||
{
|
||||
volatile struct mstp_port_struct_t mstp_port; /* port data */
|
||||
uint8_t my_mac = 0x05; /* local MAC address */
|
||||
|
||||
MSTP_Init(&mstp_port, my_mac);
|
||||
ct_test(pTest, mstp_port.master_state == MSTP_MASTER_STATE_INITIALIZE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST_MSTP
|
||||
int main(void)
|
||||
{
|
||||
Test *pTest;
|
||||
bool rc;
|
||||
|
||||
pTest = ct_create("mstp", NULL);
|
||||
|
||||
/* individual tests */
|
||||
rc = ct_addTestFunction(pTest, testReceiveNodeFSM);
|
||||
assert(rc);
|
||||
rc = ct_addTestFunction(pTest, testMasterNodeFSM);
|
||||
assert(rc);
|
||||
|
||||
ct_setStream(pTest, stdout);
|
||||
ct_run(pTest);
|
||||
(void) ct_report(pTest);
|
||||
|
||||
ct_destroy(pTest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -616,8 +616,6 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||
/* receives the token */
|
||||
mstp_port->TokenCount = Npoll;
|
||||
mstp_port->SoleMaster = false;
|
||||
mstp_port->ReceivedValidFrame = false;
|
||||
mstp_port->ReceivedInvalidFrame = false;
|
||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
||||
transition_now = true;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user