WIZnet Developer Forum

[WIZ750SR-RS232] setSn_DHAR 질문.

안녕하세요!
setSN_DHAR이 잘 되지 않아서 질문드립니다.

1:N UDP 를 사용중이고요,
2개의 서버에서 데이터를 보냅니다.
초기에 MAC을 모를때는 setSn_CR(sn,Sn_CR_SEND) 를 보내고
2개의 MAC을 확인후 setSn_CR(sn,Sn_CR_SEND_MAC)을 하는데요.
Debug 화면을 보면,
처음 두번 ARP 를 진행할때
getSn_DHAR(sock, mac_1)
getSn_DHAR(sock, mac_2) 모두 맞게 읽혀서 Debug화면에 표시됩니다.

Debug 화면**
< SERVER1 에서 ARP >

UDP Peer IP/Port1: 192.168.1.199 : 8194
RECV ARP packet1 from 80:fa:5b:3b:61:f7
RECV ARP packet2 from 0: 0: 0: 0: 0: 0

< SERVER2 에서 ARP >

UDP Peer IP/Port2: 192.168.1.198 : 8194
RECV ARP packet1 from 80:fa:5b:3b:61:f7
RECV ARP packet2 from 18:67:b0:ca:7f: a

< SERVER1 에서 SEND_MAC >

RECV ARP packet1 from 80:fa:5b:3b: 0: 0
RECV ARP packet2 from 18:67:b0:ca:7f: a

< SERVER2 에서 SEND_MAC >

RECV ARP packet1 from 80:fa:5b:3b: 0: 0
RECV ARP packet2 from 18:67:b0:ca: 0: 0

위 처럼 처음 자동으로 ARP 할때는, sendto() 이후 getSn_DHAR() 하여 MAC이 잘 읽히는데요
SEND_MAC 하고나면, 뒤에 5,6 번이 0으로 채워져서 보냅니다.
실제로 Wireshark로 확인해도 마찬가지 입니다.

Frame 2: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface 0
Ethernet II, Src: Wiznet_56:76:f2 (00:08:dc:56:76:f2), Dst: SamsungE_ca:00:00 (18:67:b0:ca:00:00)
Internet Protocol Version 4, Src: 192.168.1.101, Dst: 192.168.1.198
User Datagram Protocol, Src Port: 8194, Dst Port: 8194
Data (15 bytes)

왜그럴까요? 코드 첨부합니다.
도움 부탁드립니다.
감사합니다.

void uart_to_ether(uint8_t sock)
{
	struct __network_info *netinfo = (struct __network_info *)&(get_DevConfig_pointer()->network_info);
	struct __serial_info *serial = (struct __serial_info *)get_DevConfig_pointer()->serial_info;
	uint16_t len;
	int16_t sent_len;
	uint16_t i; // ## for debugging
	
#if ((DEVICE_BOARD_NAME == WIZ750SR) || (DEVICE_BOARD_NAME == WIZ750SR_1xx))
	if(get_phylink_in_pin() != 0) return; // PHY link down
#endif
	
	// UART ring buffer -> user's buffer
	len = get_serial_data();
	
	if(len > 0)
	{
		add_data_transfer_bytecount(SEG_UART_RX, len);
		if((serial->serial_debug_en == SEG_DEBUG_S2E) || (serial->serial_debug_en == SEG_DEBUG_ALL))
		{
			debugSerial_dataTransfer(g_send_buf, len, SEG_DEBUG_S2E);
		}
		
		switch(getSn_SR(sock))
		{
			case SOCK_UDP: // UDP_MODE
				if((netinfo->remote_ip[0] == 0x00) && (netinfo->remote_ip[1] == 0x00) && (netinfo->remote_ip[2] == 0x00) && (netinfo->remote_ip[3] == 0x00))
				{
					if((peerip[0] == 0x00) && (peerip[1] == 0x00) && (peerip[2] == 0x00) && (peerip[3] == 0x00))
					{
						if(serial->serial_debug_en) printf(" > SEG:UDP_MODE:DATA SEND FAILED - UDP Peer IP/Port required (0.0.0.0)\r\n");
					}
					else
					{
						// UDP 1:N mode
						//peerip[3] = g_send_buf[05]; // yhlee
						if(g_send_buf[05] == peerip_1[3]){
							setSn_DHAR(sock, mac_1);
							memcpy(peerip, peerip_1, 4);
						}
						else if(g_send_buf[05] == peerip_2[3]) {
							setSn_DHAR(sock, mac_2);
							memcpy(peerip, peerip_2, 4);
						}						
						sent_len = (int16_t)sendto(sock, g_send_buf, len, peerip, peerport);

						if(g_send_buf[05] == peerip_1[3]){
							getSn_DHAR(sock, mac_1);
							mac_flag1 = 1;
						}
						else if(g_send_buf[05] == peerip_2[3]) {
							getSn_DHAR(sock, mac_2);
							mac_flag2 = 1;							
						}
						if(serial->serial_debug_en) {
							printf("RECV ARP packet1 from %2x:%2x:%2x:%2x:%2x:%2x\r\n",mac_1[0],mac_1[1],mac_1[2],mac_1[3],mac_1[4],mac_1[5]);
							printf("RECV ARP packet2 from %2x:%2x:%2x:%2x:%2x:%2x\r\n",mac_2[0],mac_2[1],mac_2[2],mac_2[3],mac_2[4],mac_2[5]);
						}
					}
				}
				else
				{
					// UDP 1:1 mode
					sent_len = (int16_t)sendto(sock, g_send_buf, len, netinfo->remote_ip, netinfo->remote_port);
				}
				
				if(sent_len > 0) u2e_size-=sent_len;
				
				break;
			
			case SOCK_ESTABLISHED: // TCP_SERVER_MODE, TCP_CLIENT_MODE, TCP_MIXED_MODE
			case SOCK_CLOSE_WAIT:
				// Connection password is only checked in the TCP SERVER MODE / TCP MIXED MODE (MIXED_SERVER)
				if(flag_connect_pw_auth == SEG_ENABLE)
				{
					sent_len = (int16_t)send(sock, g_send_buf, len);
					if(sent_len > 0) u2e_size-=sent_len;
					
					add_data_transfer_bytecount(SEG_UART_TX, len);
					
					if(netinfo->keepalive_en == ENABLE)
					{
						if(flag_sent_first_keepalive == DISABLE)
						{
							enable_keepalive_timer = SEG_ENABLE;
						}
						else
						{
							flag_sent_first_keepalive = SEG_DISABLE;
						}
						keepalive_time = 0;
					}
				}
				break;
			
			case SOCK_LISTEN:
				u2e_size = 0;
				return;
			
			default:
				break;
		}
	}
	
	inactivity_time = 0;
	//flag_serial_input_time_elapse = SEG_DISABLE; // this flag is cleared in the 'Data packing delimiter:time' checker routine
}

자사 펌웨어 문제로 v1.2.5 버전 부터 업데이트된 부분과 관련있어보입니다.
Libraries/W7500x_stdPeriph_Driver/inc/W7500x_wztoe.h
에서 아래 내용을 확인해보시길 바랍니다.

WIZCHIP_WRITE((WZTOE_Sn_DHAR(sn)+3), dhar[0]); \
WIZCHIP_WRITE((WZTOE_Sn_DHAR(sn)+2), dhar[1]); \
WIZCHIP_WRITE((WZTOE_Sn_DHAR(sn)+1), dhar[2]); \
WIZCHIP_WRITE((WZTOE_Sn_DHAR(sn)+0), dhar[3]); \
WIZCHIP_WRITE((WZTOE_Sn_DHAR(sn)+7), dhar[4]); \
WIZCHIP_WRITE((WZTOE_Sn_DHAR(sn)+6), dhar[5]); 

해당 라이브러리에는 위와 같이 되어 있습니다. (V1.2.4 입니다.)
5, 4가 맞는건가요?

getSn_DHAR은 3 2 1 0 7 6
setSn_DHAR은 3 2 1 0 5 4
입니다.
read 할때 address와 write할때 address가 다릅니다.

1 Like

감사합니다.
해결되었습니다!

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