WIZnet Developer Forum

소켓이 0번잘되나 1~7번소켓은 수신시 2byte에러

안녕하세요.

W5300 IC를 오랫동안 사용한 유저입니다.

대부분 소켓 0번만으로 UDP,TCP로 통신문제없이 잘쓰고 있었는데
이번 프로젝트에서는 소켓 1~7을 이용하여 사용해야 되서 구현중입니다.
전부터 0번소켓은 아무문제없으나 그외 소켓에서 수신시 데이터중 처음 2byte만 안들어오는 문제가
있습니다.그 뒤에 오는 데이터는 정상적입니다. 전에도 알고있었지만 패킷처음 2bytes를 무시하고 사용하였습니다. 지금은 1byte수신데이터도 인식해야하기 때문에 중요합니다.(uart통신처럼 사용할 예정)
그리고 TCP/UDP 둘다 그렇습니다. 그거 이외에는 지극히 정상적입니다.

2byte인 이유가 16bit모드를 사용하고 있어서 그런거 같습니다.
데이터를 확인해 보니 rxdata[0]=192, rxdata[1]=168 이값이 들어올때가 많으며, 몇번안되지만 정상적으로 들어온 경우도 있습니다. 한마디로 쓰레기 데이터가 들어옵니다.

포럼을 확인하니 동일증상이 있어 질문을 한 유저도 있는것을 확인하였습니다.

그래서 W5300_Drv_V1.2.4 버젼으로 다시 해봤는데도 동일합니다.

사용 MCU는 STM32F407 + W5300입니다.(16bit모드만 사용해야합니다.)

참고로
switch (IINCHIP_READ(Sn_MR(s)) & 0x07) // check the mode of s-th SOCKET
{ // -----------------------------
case Sn_MR_UDP : // UDP mode
wiz_read_buf(s, (uint8*)head, 8); // extract the PACKET-INFO
// read peer’s IP address, port number.
if(((vuint16)MR) & MR_FS) // check FIFO swap bit
{
head[0] = ((((head[0] << 8 ) & 0xFF00)) | ((head[0] >> 8)& 0x00FF));
head[1] = ((((head[1] << 8 ) & 0xFF00)) | ((head[1] >> 8)& 0x00FF));
head[2] = ((((head[2] << 8 ) & 0xFF00)) | ((head[2] >> 8)& 0x00FF));
head[3] = ((((head[3] << 8 ) & 0xFF00)) | ((head[3] >> 8)& 0x00FF));
}
addr[0] = (uint8)(head[0] >> 8); // destination IP address
addr[1] = (uint8)head[0];
addr[2] = (uint8)(head[1]>>8);
addr[3] = (uint8)head[1];
*port = head[2]; // destination port number
data_len = (uint32)head[3]; // DATA packet length

    #ifdef __DEF_IINCHIP_DBG__
       printf("UDP msg arrived:%d(0x%04x)\r\n",data_len,data_len);
       printf("source Port : %d\r\n", *port);
       printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
    #endif

    wiz_read_buf(s, buf, data_len);        // data copy.
    break;

UDP코드인데 여기서 sockettest프로그램으로 이용해 테스트도 해봤습니다.
강제적으로 4byte만 보내고 이함수를 수정하여 그냥 wiz_read_buf(s, buf, 12); 만 읽어보았는데
이렇게 읽으면 수신데이터 모두 정상입니다.
그런데 ip와 port,data_len를 확인하고 4byte만 읽으면
rxdata[0]~[1]은 쓰레기고 rxdata[2]~[3]은 정상입니다.

피곤한 상태여서 생각나는데로 적으니 문맥상 이상하셔도 양해부탁드립니다.
빠른답변 부탁드릴께요

010-삼112-오3칠2 박동진 으로 전화주셔도 됩니다.

방금 테스트해봤는데 송신데이터는 정상입니다.

안녕하세요
W5300을 잘 사용해주셔서 감사합니다.

첨부해주셨던 구문중에, MR &MR_FS를 비교하는 구문이 있는데,
MR을 getMR()을 이용해서 사용하셔야 할것 같습니다.
즉, 함수를 시작할때, 미리 아래와 같이 작성하고,
uint16 mr = getMR();

이후
if( *((vuint16* )MR) & MR_FS) 대신 if(mr & MR_RS)

를 사용하시길 바랍니다.
변경하신 후에도 또다시 문제가 발생하게 된다면, 다시 답글을 남겨주시면 빠르게 대응해드리겠습니다.

감사합니다.
irina

그다음날 iolibrary를 이용하여 해결하였습니다.
나중에 시간내서 말씀하신대로 해보고 답변드리겠습니다.

그리고 iolibrary에서 빅엔디언과 리틀엔디언 설정은 이전 라이브러리랑 동일하게 초기에 설정하면 되는건가요?

mr = getMR();
setMR(mr | MR_FS);

위 코드를 추가해서 해보니 안되고 MR_FS을 설정안하니 리틀엔디언 처리되어서 됩니다.

차후 타업체간의 연동시 빅엔디언을 사용하는데 iolibrary에서 빅엔디언 설정방법은 어떻게 하는지 부탁드리겠습니다.

네 ~ 초기에 설정해주시는게 맞습니다.
기본적으로 Big- endian 으로 사용되며, MR레지스터의 FS bit를 세팅하시면 Little-endian으로 동작하게 됩니다.

추후 문의 사항은 언제든 남겨주시면 답변해드리겠습니다.

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.