Introduction
Warnings for the proper use of UDP communication from R3 applications:
•UDP communication over Ethernet performed by R3 application works exclusively using the Ethernet interface present on the CPU board. It cannot be used to communicate via an Ethernet interface present on other boards (e.g., Netint board).
•Due to its inherent characteristics, UDP communication does not guarantee delivery of data packets. The application must take responsibility, if requested, for verification and retransmission of lost packets.
•UDP communication does not guarantee transmission timing
•UDP communication does not guarantee the timing of receiving packets. Packet P2, transmitted after packet P1, may be received before P1. The application must take charge, if requested, of data reordering.
•The handle associated with a UDP communication (value returned by the udp_open_ functions) makes sense only within the R3 task in which the open was performed. You cannot use the handle in a different task to make calls to other UDP functions
•Up to a maximum of 65535 bytes can be transmitted with a single udp_ function call. In the O.S. (IP layer) transmission is done by breaking the buffer into blocks of maximum size equal to MAX_UDP_DATA = 508. If one of these packets fails transmission, the entire buffer, as a result, is lost
•The functions udp_send_notify() and udp_recv_notify() must in all cases have a buffer limited to MAX_UDP_DATA bytes
•The user making from task R3 a UDP server application can use as many ports as they wish for the connection. However, it is recommended to avoid the 8000 to 8999 range, to avoid conflicts with current and future Robox implementations
Istruzioni
udp_close() |
Closing a UDP communication |
udp_open_client() |
Opening a client-type UDP communication |
udp_open_server() |
Opening a UDP communication of server type |
udp_recv() |
Receiving a UDP message from a previously specified station |
udp_recv_from() |
Receiving a UDP message from a specified station |
udp_recv_notify() |
Receiving a UDP message (notification) from a previously specified station |
udp_send() |
Sending a UDP message to a previously specified station |
udp_send_notify() |
Sending a UDP message with notification to a previously specified station |
udp_send_to() |
Sending a UDP message to a previously specified station |
ipaddr_to_str() |
Support |
str_to_ipaddr() |
Support |
NOTE: A client/server example can be found in RDE3-->workspace-->default examples.
Example
$task 1 ;==================================================================== ; Example of UDP client for message exchange with notification. ; Requests the server for the value of 50 rr, starting at rr(30). ; Copies the response data into the registers starting at rr(150). ;==================================================================== ; Structure for sending command lit size_buffer 16 STRUCT_P buff_send U32 msgId I32 comando I32 reg_start I32 reg_num end_struct_p buff_send buffer ; structure for receiving data lit size_bufrec 812 STRUCT_P buff_recv I32 msgId I32 comando I32 reg_num REAL regs[100] end_struct_p buff_recv bufrec U32 ip_srvaddr = 0x0a001011; ; server address = 10.0.16.17 U32 udp_srvport = 18000 ; server on port 18000 I32 codOpen, codSend, codRecv I32 i ; Start task ; opening connection codOpen = udp_open_client(udp_srvport, ip_srvaddr ) if (codOpen < 0) alarm s, "err. udp_open (client)" while (1) dwell(1) end_while endif loop: ; command transmission buffer.comando = 2 ; display rr() buffer.reg_start = 50 ; from rr(50) buffer.reg_num = 30 ; 30 rr() codSend = udp_send_notify(codOpen, buffer, size_buffer) if (codSend < 0) alarm s, "1002 error send_notify (client)" dwell(1) goto loop endif ; receiving while (1) codRecv = udp_recv_notify(codOpen, bufrec, size_bufrec, 0.2, 2) if (codRecv = 0) ; the response has not yet arrived dwell (0.01) continue endif if (codRecv < 0) ; receiving with error alarm s, "1003 error recv_notify (client)" dwell (1) goto loop endif ; message received OK... for (i=0, i<buffer.reg_num, i=i+1) ; data copying rr(100+buffer.reg_start+i) = bufrec.regs[i] end_for break end_while dwell (0.05) goto loop $task 2 ;==================================================================== ; Example of UDP server for message exchange with notification. ; Receives a command from the client (request for real registers). ; Executes the command by sending the client the value of 30 RR ; starting with RR(50). ;==================================================================== ; structure for receiving command lit size_buf_from 16 STRUCT_P buff_send U32 msgId I32 comando I32 reg_start I32 reg_num end_struct_p buff_send buf_from ; structure for sending response lit size_buf_to 812 STRUCT_P buff_recv U32 msgId I32 comando I32 reg_num REAL regs[100] end_struct_p buff_recv buf_to I32 udp_remport = 18000 ; port of server I32 ip_remaddr I32 codOpenS, codSendS, codRecvS I32 i ; Start Task ; opening from all local eth. interfaces (no address specified) codOpenS = udp_open_server(udp_remport) if (codOpenS < 0) alarm s, "err. udp_open (server)" endif loop: ; receiving messages codRecvS = udp_recv_from(codOpenS, buf_from, size_buf_from, udp_remport, ip_remaddr ) if (codRecvS = 0) goto loop endif if (codRecvS < 0) ; receiving with error alarm s, "err. udp_recv_from (server)" dwell(1) goto loop endif ; preparation response buf_to.msgId = buf_from.msgId buf_to.comando = buf_from.comando buf_to.reg_num = buf_from.reg_num for (i=0, i<buf_from.reg_num, i=i+1) buf_to.regs[i] = rr(buf_from.reg_start+i) end_for
; sending response codSendS = udp_send_to(codOpenS, buf_to, size_buf_to, udp_remport, ip_remaddr) if (codSendS < 0) ; sending with error alarm s, "1001 error send_to (server)" dwell (1) goto loop endif goto loop |