답변 감사합니다.
말씀해주신 부분에 대한 답변 드리면
1. 현장에서 사용 중 발생한 문제라 와이어샤크로 분석하진 못했고, 현장에서 문제를 해결해야 했기에 소켓을 close/open하는 방식을 사용했습니다.
2,3 위즈네트에서 재공하는 공식 Library를 사용했고, 일부 수정하여 사용했습니다. 그래서 코드 공유드립니다.
uint32 sendto(SOCKET s, uint8 * buf, uint32 len, uint8 * addr, uint16 port)
{
uint8 status=0;
uint8 isr=0;
uint32 ret=0;
udp_delay(10000000);__HAL_IWDG_RELOAD_COUNTER(&hiwdg);
udp_delay(10000000);__HAL_IWDG_RELOAD_COUNTER(&hiwdg);
udp_delay(10000000);__HAL_IWDG_RELOAD_COUNTER(&hiwdg);
udp_delay(10000000);__HAL_IWDG_RELOAD_COUNTER(&hiwdg);
udp_delay(10000000);__HAL_IWDG_RELOAD_COUNTER(&hiwdg);
// #ifdef DEF_IINCHIP_DBG
//printff(“%d : sendto():%d.%d.%d.%d(%d), len=%d\r\n”);
// #endif
if
(
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
((port == 0x00)) ||(len == 0)
)
{
// #ifdef DEF_IINCHIP_DBG
//printff(“%d : Fail[%d.%d.%d.%d, %.d, %d]\r\n”);
// #endif
return 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_DIPR0(s),addr[0]);
IINCHIP_WRITE(Sn_DIPR1(s),addr[1]);
IINCHIP_WRITE(Sn_DIPR2(s),addr[2]);
IINCHIP_WRITE(Sn_DIPR3(s),addr[3]);
// set destination port number
IINCHIP_WRITE(Sn_DPORTR0(s),((uint8)(port >> 8)));
IINCHIP_WRITE(Sn_DPORTR1(s),((uint8)(port & 0xff)));
wiz_write_buf(s, buf, ret+(ret & 0x01)); // copy data
// send
setSn_TX_WRSR(s,ret);
ApplySubnet();
if(s == 3) setSn_CR(s, Sn_CR_SEND);
else if(MAC_fg){
MAC_fg = 0;
setSn_DHAR(s,SMAC);
setSn_CR(s, Sn_CR_SEND_MAC);
}
else setSn_CR(s, Sn_CR_SEND);
//ClearSubnet();
while (!((isr = getSn_IR(s)) & Sn_IR_SENDOK)) // wait SEND command completion
{
status = getSn_SSR(s); // warning ---------------------------------------
if ((status == SOCK_CLOSED) || (isr & Sn_IR_TIMEOUT)) // Sn_IR_TIMEOUT causes the decrement of Sn_TX_FSR
{ // -----------------------------------------------
//#ifdef __DEF_IINCHIP_DBG__
//printff("%d: send fail.status=0x%02x,isr=%02x\r\n");
//#endif
setSn_IR(s,Sn_IR_TIMEOUT);
return 0;
}
}
setSn_IR(s, Sn_IR_SENDOK); // Clear Sn_IR_SENDOK
ClearSubnet();
#ifdef __DEF_IINCHIP_DBG__
//printff("%d : send()end\r\n");
#endif
return ret;
}
그리고 추가질문있습니다.
while (!((isr = getSn_IR(s)) & Sn_IR_SENDOK)) // wait SEND command completion
{
status = getSn_SSR(s); // warning ---------------------------------------
if ((status == SOCK_CLOSED) || (isr & Sn_IR_TIMEOUT)) // Sn_IR_TIMEOUT causes the decrement of Sn_TX_FSR
{ // -----------------------------------------------
//#ifdef __DEF_IINCHIP_DBG__
//printff("%d: send fail.status=0x%02x,isr=%02x\r\n");
//#endif
setSn_IR(s,Sn_IR_TIMEOUT);
return 0;
}
}
이 부분에서 sendok가 안뜨고 while 문 안으로 들어갔을 때
socket이 close된다면 버퍼포인트가 초기화돼서 문제가 없겠지만 만약 timeout이 발생한다면 버퍼가 어떻게 처리되는지 궁금합니다. 이 부분에서 문제가 발생하는게 아닐까 짐작돼 질문드립니다.