안녕하세요.
UDP통신에서 1:N을 진행 하려고 합니다.
네트워크를 모르다 보니 프로젝트 진행도중
UDP는 데이터 전송시 상대방 IP주소가 바뀌면 "ARP"를 전송하여 맥을 확인하는 작업이 있는줄 몰랐습니다.
STM103 MCU를 사용중이고 SendTo를 하는 시간을 체크해보니 28us 소모되었습니다.
SendTo 함수에서 “while (!((isr = getSn_IR(s)) & Sn_IR_SENDOK))” 부분이 있어서 상관 없는줄 알았으나 수백 수천번을 연속적으로 진행하다보니
데이터가 밀리는 현상이 발생되었습니다.
예를 들어 A가
B한테는 11 22 33 44을 전송하고
C한테는 55 66 77 88을 전송하는데 일정 시간 후에 보면
B한테는 22 33 44 11이 전송되고
C한테는 77 88 55 66이 전송 되는 데이터 밀림 현상이 발생됩니다.
추가적으로는 위 증상이 발생될때 11 22 33 44를 보내고 있다가
55 66 77 88를 전송하면 소켓 메모리에 11 22 33 44가 저장된 상태였는지
55 66 77 88 데이터가 아닌 11 22 33 44 데이터가 전송되었습니다.
아래는 사용하고 있는 함수입니다. “ARP” 전송 후 응답시간을 sendto 후에 얼마나 줘야 할지 몰라서 delay를 170us를 주었는도 계속 발생되네요…
그래서 1분마다 해당 소켓을 열고 닫고를 하는
setSn_CR(s, Sn_CR_CLOSE);
setSn_CR(s, Sn_CR_OPEN);
위 코드를 사용하니 해당 증상이 나오지는 않지만 어쩔 수 없이 닫고 여는 순간의 데이터가 빠지다보니 이걸로는 해결이 안되겠더라구요…
별도로 더 참고해야하는 부분이 있거나 놓친부분이 있을까요…?
uint32 SendTo_UDP(SOCKET s, uint8 * buf, uint32 len, uint8 * addr, uint16 port)
{
uint8 status=0;
uint8 isr=0;
uint32 ret=0;
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;
// set destination IP address
IINCHIP_WRITE(Sn_DIPR(s),(((uint16)addr[0])<<8) + (uint16) addr[1]);
IINCHIP_WRITE(Sn_DIPR2(s),(((uint16)addr[2])<<8) + (uint16) addr[3]);
// set destination port number
IINCHIP_WRITE(Sn_DPORTR(s),port);
wiz_write_buf(s, buf, ret); // copy data
// send
setSn_TX_WRSR(s,ret);
setSn_CR(s, Sn_CR_SEND);
g_mgrDevice.nTemp = 0;
while (!((isr = getSn_IR(s)) & Sn_IR_SENDOK)) // wait SEND command completion
{
g_mgrDevice.nTemp++;
if( g_mgrDevice.nTemp >= 50 )
{
setSn_IR(s,Sn_IR_TIMEOUT);
return 0;
}
status = getSn_SSR(s); // warning ---------------------------------------
if ((status == SOCK_CLOSED) || (isr & Sn_IR_TIMEOUT)) // Sn_IR_TIMEOUT causes the decrement of Sn_TX_FSR
{ // -----------------------------------------------
setSn_IR(s,Sn_IR_TIMEOUT);
return 0;
}
}
setSn_IR(s, Sn_IR_SENDOK); // Clear Sn_IR_SENDOK
Delay(1000); // 약 170us
return ret;
}