100ms 마다 send를 보낼때 이상한 데이터 출력


#1

	if(TX_flog==1)
	{    

		Check_TXcntB++;

		ret=send(0, TCP_buf, 10);  //Modbus frame	 Rx
        //wiz_send_data(0, TCP_buf, 10);
		Check_ReturnVal = ret;

		if(ret < 0)
		{
			    Check_TXcntC++;
				//socket(sn, Sn_MR_TCP, port, 0x00);
				return ret;
		}


		for(Count=0; Count<DATA_MAP_SIZE; Count++)
		{
			TCP_buf[Count]=0;
		}

		//TX_flog=0;
	}

100ms 마다 데이터를 보낼때 비정상 데이터가 간혹 발생
50ms 마다 데이터를 보낼때 비정상 데이터가 산발적으로 발생
10ms 마다 데이터를 보낼떄 비정상 데이이터가 산발적으로 발생

위 같은 증상이 계속 됩니다.
답변 부탁드립니다.


#2

안녕하세요 문의감사드립니다.

일단 첨부해주신 내용으로는 어떠한 상황인지 확실히는 알기 어렵습니다만 판단하기로는 실제 전송하려는 데이터보다 더 많이 나가는 문제가 있는것 같은데 맞는지요?

코드상에서는 10byte 만 전송하도록 되어 있는데 만약 원하는 데이터보다 더 많은 데이터가 나가는 경우라면 SEND 커맨드하시기전에 Buffer WR/RD 포인터값을 한번 확인해야 할 것 같구요

또는 Interface 통신에 크리티컬 섹션을 지정하셨나요? 만약 그렇지 않다면 MCU와 W5500사이에서 데이터 송수신중 MCU가 인터럽트 동작을 수행할 경우 원하지 않는 동작을 할 수 도 있습니다.

그리고 몇가지 요청사항이 있는데

첫번째로 네트워크 환경이 어떻게 되시나요?

W5500과 PC사이의 데이터 전송인가요? 아니면 W5500과 장비사이의 데이터 전송인가요?

그리고 또 한가지 요청드릴 사항이 있는데 네트워크 환경이 W5500과 PC사이의 데이터 송수신이라면 wireshark라는 open 툴이 있습니다.

그걸 PC쪽에 설치하신다음에 실행시키시면 W5500과 통신하는 TCP 패킷을 확인하실 수 있습니다. (상단에서 IP로 필터링하시면 빠르게 확인가능합니다.)

혹시 위의 내용이 가능하시다면 확인해보시고 패킷을 .pcap으로 저장하셔서 첨부해주실 수 있으신가요?

시리얼로 확인하는 부분도 좋지만

패킷을 직접보고 실제 네트워크상에 전송된 데이터와 비교해보는 작업도 필요해보여서 부탁드립니다.

감사합니다.


#3

1.W5500과 PC사이의 데이터 전송인가요? 아니면 W5500과 장비사이의 데이터 전송인가요?

그리고 또 한가지 요청드릴 사항이 있는데 네트워크 환경이 W5500과 PC사이의 데이터 송수신이라면 wireshark라는 open 툴이 있습니다.

  • W5500과 PC 사의 데이터 전송입니다.

2.코드상에서는 10byte 만 전송하도록 되어 있는데 만약 원하는 데이터보다 더 많은 데이터가 나가는 경우라면 SEND 커맨드하시기전에 Buffer WR/RD 포인터값을 한번 확인해야 할 것 같구요

또는 Interface 통신에 크리티컬 섹션을 지정하셨나요? 만약 그렇지 않다면 MCU와 W5500사이에서 데이터 송수신중 MCU가 인터럽트 동작을 수행할 경우 원하지 않는 동작을 할 수 도 있습니다.

  • Buffer WR/RD 포인터값은 #define DATA_MAP_SIZE 10 / unsigned int TCP_buf[DATA_MAP_SIZE];
    으로 했습니다. 궁굼한게 버퍼값이 늘린다고 하지만 len 을 10으로 하면 10byte 만 보내는거 아닌가요?

wireshark 툴은 일반 허브로 안됀다고 했는데… 특수한 허브가 없습니다.


#4

W5500과 PC사이에서의 데이터전송 패킷은 더미허브없이 PC에 wireshark를 설치하고 확인가능합니다.

네 말씀하신대로 len=10을 하면 10byte를 보내지만 send()내에서 포인터값을 지정할때 그값이 제대로 들어가는지가 궁금해서 여쭤봤습니다.

만약 코드상에 의심가는부분이 없으시다면 wireshark를 통해서 패킷내용을 알 수 있을까요?

그리고 SPI통신간에 크리티컬 섹션이 지정되었는지도 확인부탁드립니다.

감사합니다.


#5

이메일 보냈습니다, 확인 부탁드립니다.


#6

#define DATA_MAP_SIZE 5
unsigned int TX_BUF[DATA_MAP_SIZE]={0,1,2,3,4}; // TX Buffer for applications
unsigned int *data_buf = TX_BUF;
void main(void){



while(1){
if(TimeTask.bit.Task_10ms==TRUE)
{
Task_10ms(); // 10ms 체크
TCP_MODBUS(0, data_buf, 5000,DATA_MAP_SIZE ); //W5500이더넷 송수신 함수

	}
}

}
unsigned int TCP_MODBUS(unsigned int sn, unsigned int* buf, unsigned int port, unsigned int _MAP_SIZE)
{
int ret;
int i=0;
//int txsize[WIZCHIP_SOCK_NUM]=0;
//Link_Flag = wizphy_getphylink();

Sock_State = getSn_SR(sn);
//if(!Link_Flag) Sock_State = SOCK_CLOSED;

switch(Sock_State)
{
case SOCK_ESTABLISHED : //3 //3
if(TX_flog==1)
{

		Check_TXcntB++;
       	//for(Count=0; Count<DATA_MAP_SIZE; Count++)
		//{
		//	TCP_buf[Count]=Count;
		//}
		send(sn, buf, _MAP_SIZE);  //Modbus frame	 Rx
        //wiz_send_data(0, TCP_buf, 10);
		//Check_ReturnVal = ret;

		if(ret < 0)
		{
			    Check_TXcntC++;
				closeA(sn);
				//socket(sn, Sn_MR_TCP, port, 0x00); 
				return ret;
		}


	       //for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
            //setSn_TXBUF_SIZE(i, txsize[i]);


		//TX_flog=0;
	}

     break;

     case SOCK_CLOSE_WAIT :
    	  disconnect(sn); // disconnect 0x1c -> 0x14  4
    	  //if((ret=disconnect(sn)) != SOCK_OK) return ret;
     break;

     case SOCK_INIT :

    	 listen(sn); // 2
    	// if( (ret = listen(sn)) != SOCK_OK) return ret;
     break;

     case SOCK_CLOSED:

	     socket(sn, Sn_MR_TCP, port, 0x00); // 1
    	// if((ret=socket(sn,Sn_MR_TCP,port,0x00)) != sn)
    	// return ret;

     break;

     default:

     break;

}
return 1;
}

00 01 02 03 04
00 01 02 03 04
00 01 02 03 04
00 01 02 03 04
이게 정상으로 가야 하는데
00 01 02 03 04
00 01 02 03 04 00 01 02 03 04
00 01 02 03 04
00 01 02 03 04 00 01 02 03 04

이런식으로 비정상으로 데이터가 들어옵니다.
그리고 크리티컬섹션이 무슨 듯인가요?
패킷정보도 같이 드리겠습니다. 패킷.zip (46.2 KB)


#7

안녕하세요 위즈네트 입니다.

https://hercules-setup.soft32.com/

전화상으로 말씀드린 프로그램 링크입니다.

아래그림은 제가 짧게 테스트해봤습니다.

왼쪽은 Server로 동작시킬때인데요 TCP Server 탭에서 포트만 입력시키고 OPEN버튼 누르시면됩니다

오른쪽은 Client로 동작시킬때인데요 TCP Client탭에서 server의 아이피, 포트 입력시키고 CONNECT버튼 누르시면됩니다.

그림은 오른쪽에서 close라는 메시지를 계속 보낸건데 보시다시피 왼쪽에서 줄바꿈없이 계속 이어서 시리얼창에 뜨더라구요… 그래서 데이터는 01020304 + 0d0a 를 보내주시면 됩니다, '0d0a’는 window에서 줄바꿈으로 인식되니까 hercules 툴에서 원하시는 포멧대로 데이터가 뜰껍니다.

안되시거나 어려운부분있으시면 다시 연락주세요 감사합니다


#8

안녕하세요 어제 오늘 디버깅을 하다가 발견한게 있는데
send 함수안에 freesize = getSn_TX_FSR(sn); 있는데 freesize 데이터값이 2048,2043,2023, … 이렇게 되다가 어느 순간에 29773, 또는 -9272 , 값은 변화 합니다. 혹시 이거떄문에 대량의 데이터가 나오는건 아닌지요?