forked from delhatch/Zynq_UDP
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f58a239
Showing
6 changed files
with
380 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Zedboard_UDP | ||
|
||
Author | ||
|
||
Del Hatch | ||
|
||
** Communicating over UDP | ||
|
||
The purpose of this project is to demostrate data transfers over UDP using the Zedboard. This can be used on the MicroZed and other Zynq-based boards with minor modifications. | ||
|
||
** Build a Zynq system using Vivado | ||
|
||
Using the figure below as a guide, build a Zynq system. The AXI Interconnect, Processor Reset, and GPIO modules are optional, but I like to put them in for command.control/debugging later. | ||
|
||
 | ||
|
||
You can use all of the system defaults, peripheral auto-address assignments, and system configuration defaults -- no need to customize anything. | ||
|
||
After you build the system and export the hardware (including the bit file) launch the SDK. | ||
|
||
** SDK and software | ||
|
||
After the SDK opens, click File -> New -> Application Project. | ||
|
||
Give the project a name, then click Next. | ||
|
||
Select "lwIP Echo Server" from the list of Available Templates, and Finish. | ||
|
||
At this point you can compile, load and run the Echo Server on the Zedboard. I use PuTTY to see it working. | ||
|
||
Launch PuTTY, type in the IP address of the Zedboard defined in the main.c file, set the Port value to 7, and select "Telnet" as the connection type. In the window that opens, you can type letters and see them echoed back to PuTTY. | ||
|
||
** Changing the Echo Server to use UDP | ||
|
||
The default lwIP Echo Server uses TCP. To convert it to use UDP instead, replace the supplied main.c with the main.c in this Github repository. Also, replace the echo.c file. | ||
|
||
Also, download the includes.h file and add them to your project. | ||
|
||
Copy the files into the <project>.sdk/<project>/src directory. Then in the SDK, highlight the <SDK project> line in the "Project Explorer" frame, and hit F5 to refresh. | ||
|
||
** Compile and run | ||
|
||
Now compile and run the code. As the code runs, in the connected terminal program, you will see this: | ||
|
||
 | ||
|
||
The dots along the bottom indicate that the Zedboard is sending a UDP packet. This happens once every 500 mSeconds. The packet consists of a single integer with a value of 0x45. | ||
|
||
To see the packets being sent, use Wireshark. | ||
|
||
There are many ways to transmit data to the Zedboard of UDP. I used the VLC media player and set it to stream a .mpg file over UDP. Here's how to do that: | ||
|
||
Launch VLC and click Media -> Stream... | ||
|
||
On the File tab, click "+Add" and select a media file. I use a .mpg video file. Click the Stream button. | ||
|
||
Click Next. For the Destination Setup, pull-down the New destination box. Select UDP (legacy). Click Add. Type in the IP address of the Zedboard and set the Port to 7. | ||
|
||
Click Next. I un-select "Activate Transcoding" but it does not matter for this purpose. | ||
|
||
Click Next, and then Stream. | ||
|
||
In ther terminal program you will see a lot of messages showing you the length of the UDP datagrams received by the Zedboard. | ||
|
||
** Improvements | ||
|
||
This project is mainly a demonstration of how to use UDP to send and receive data using a Zedboard or other Zynq board. | ||
|
||
I will be using it to stream media from the Zedboard to a PC, and using VLC to view the media stream. | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#include "lwip/err.h" | ||
#include "lwip/udp.h" | ||
#if defined (__arm__) || defined (__aarch64__) | ||
#include "xil_printf.h" | ||
#endif | ||
|
||
// Include our own definitions | ||
#include "includes.h" | ||
|
||
// Global variables for data flow | ||
extern volatile u8 IndArrDone; | ||
extern volatile u32 EthBytesReceived; | ||
int* IndArrPtr; | ||
extern volatile u8 SendResults; | ||
extern volatile u8 DMA_TX_Busy; | ||
extern volatile u8 Error; | ||
|
||
// Global Variables for Ethernet handling | ||
extern u16_t RemotePort; | ||
extern struct ip_addr RemoteAddr; | ||
extern struct udp_pcb send_pcb; | ||
|
||
int transfer_data() { | ||
return 0; | ||
} | ||
|
||
/* | ||
void print_app_header() | ||
{ | ||
xil_printf("\n\r\n\r-----lwIP TCP echo server ------\n\r"); | ||
xil_printf("TCP packets sent to port 6001 will be echoed back\n\r"); | ||
} | ||
*/ | ||
|
||
/* recv_callback: function that handles responding to UDP packets */ | ||
void recv_callback(void *arg, struct udp_pcb *upcb, | ||
struct pbuf *p, struct ip_addr *addr, u16_t port) | ||
{ | ||
|
||
// Set up a timeout counter and a status variable | ||
//int TimeOutCntr = 0; | ||
//int status = 0; | ||
|
||
/* Do not read the packet if we are not in ESTABLISHED state */ | ||
if (!p) { | ||
udp_disconnect(upcb); | ||
return; | ||
} | ||
|
||
/* Assign the Remote IP:port from the callback on each first pulse */ | ||
RemotePort = port; | ||
RemoteAddr = *addr; | ||
|
||
/* Keep track of the control block so we can send data back in the main while loop */ | ||
send_pcb = *upcb; | ||
|
||
/********************** WAVE ARRAY ********************************/ | ||
// Determine the number of bytes received and copy this segment to the temp array | ||
EthBytesReceived = p->len; | ||
xil_printf("Data len = %d \r\n", p->len ); | ||
//memcpy(&WaveformArr[0], (u32*)p->payload, EthBytesReceived); | ||
|
||
/* free the received pbuf */ | ||
pbuf_free(p); | ||
return; | ||
|
||
} | ||
|
||
/* start_application: function to set up UDP listener */ | ||
int start_application() | ||
{ | ||
struct udp_pcb *pcb; | ||
err_t err; | ||
unsigned port = FF_UDP_PORT; | ||
|
||
/* create new UDP PCB structure */ | ||
pcb = udp_new(); | ||
if (!pcb) { | ||
xil_printf("Error creating PCB. Out of Memory\n\r"); | ||
return -1; | ||
} | ||
|
||
/* bind to specified @port */ | ||
err = udp_bind(pcb, IP_ADDR_ANY, port); | ||
if (err != ERR_OK) { | ||
xil_printf("Unable to bind to port %d: err = %d\n\r", port, err); | ||
return -2; | ||
} | ||
|
||
/* specify callback to use for incoming connections */ | ||
udp_recv(pcb, recv_callback, NULL); | ||
|
||
xil_printf("UDP echo server started @ port %d\n\r", port); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Global include file for MicroZedAXIStreamEthernetUDP project | ||
|
||
// Debug defines | ||
#define READ_BACK_INDEX_ARRAY | ||
|
||
// Define port to listen on | ||
#define FF_UDP_PORT 7 | ||
|
||
// TIMEOUT FOR DMA AND GMM WAIT | ||
#define RESET_TIMEOUT_COUNTER 10000 | ||
|
||
// DEFINES | ||
#define WAVE_SIZE_BYTES 512 // Number of samples in waveform | ||
#define INDARR_SIZE_BYTES 1024 // Number of bytes required to hold 512 fixed point floats | ||
|
||
//HARDWARE DEFINES | ||
#define NUMCHANNELS 2 // Number of parallel operations done on input stream (1 OR 2) | ||
#define BW 32 // Total number of bits in fixed point data type | ||
#define IW 24 // Number of bits left of decimal point in fixed point data type | ||
#define BITDIV 256.0 // Divisor to shift fixed point to int and back to float |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
//DEFINE STATEMENTS TO INCREASE SPEED | ||
#undef LWIP_TCP | ||
#undef LWIP_DHCP | ||
//#undef CHECKSUM_CHECK_UDP | ||
//#undef LWIP_CHECKSUM_ON_COPY | ||
//#undef CHECKSUM_GEN_UDP | ||
|
||
#include <stdio.h> | ||
|
||
#include "xparameters.h" | ||
|
||
#include "netif/xadapter.h" | ||
|
||
#include "platform.h" | ||
#include "platform_config.h" | ||
#if defined (__arm__) || defined(__aarch64__) | ||
#include "xil_printf.h" | ||
#endif | ||
|
||
#include "lwip/udp.h" | ||
#include "xil_cache.h" | ||
|
||
// Include our own definitions | ||
#include "includes.h" | ||
|
||
/* defined by each RAW mode application */ | ||
void print_app_header(); | ||
int start_application(); | ||
//int transfer_data(); | ||
void tcp_fasttmr(void); | ||
void tcp_slowtmr(void); | ||
|
||
/* missing declaration in lwIP */ | ||
void lwip_init(); | ||
|
||
extern volatile int TcpFastTmrFlag; | ||
extern volatile int TcpSlowTmrFlag; | ||
/* set up netif stuctures */ | ||
static struct netif server_netif; | ||
struct netif *echo_netif; | ||
|
||
// Global Variables to store results and handle data flow | ||
int Centroid; | ||
|
||
// Global variables for data flow | ||
volatile u8 IndArrDone; | ||
volatile u32 EthBytesReceived; | ||
volatile u8 SendResults; | ||
volatile u8 DMA_TX_Busy; | ||
volatile u8 Error; | ||
|
||
// Global Variables for Ethernet handling | ||
u16_t RemotePort = 8; | ||
struct ip_addr RemoteAddr; | ||
struct udp_pcb send_pcb; | ||
|
||
void | ||
print_ip(char *msg, struct ip_addr *ip) | ||
{ | ||
print(msg); | ||
xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip), | ||
ip4_addr3(ip), ip4_addr4(ip)); | ||
} | ||
|
||
void | ||
print_ip_settings(struct ip_addr *ip, struct ip_addr *mask, struct ip_addr *gw) | ||
{ | ||
|
||
print_ip("Board IP: ", ip); | ||
print_ip("Netmask : ", mask); | ||
print_ip("Gateway : ", gw); | ||
} | ||
|
||
/* print_app_header: function to print a header at start time */ | ||
void print_app_header() | ||
{ | ||
xil_printf("\n\r\n\r------lwIP UDP GetCentroid Application------\n\r"); | ||
xil_printf("UDP packets sent to port 7 will be processed\n\r"); | ||
} | ||
|
||
int main() | ||
{ | ||
struct ip_addr ipaddr, netmask, gw /*, Remotenetmask, Remotegw*/; | ||
struct pbuf * psnd; | ||
err_t udpsenderr; | ||
int status = 0; | ||
|
||
/* the mac address of the board. this should be unique per board */ | ||
unsigned char mac_ethernet_address[] = | ||
{ 0x00, 0x0a, 0x35, 0x00, 0x01, 0x10 }; | ||
|
||
/* Use the same structure for the server and the echo server */ | ||
echo_netif = &server_netif; | ||
init_platform(); | ||
|
||
/* initialize IP addresses to be used */ | ||
IP4_ADDR(&ipaddr, 10, 0, 0, 10); | ||
IP4_ADDR(&netmask, 255, 255, 255, 0); | ||
IP4_ADDR(&gw, 10, 0, 0, 1); | ||
|
||
IP4_ADDR(&RemoteAddr, 10, 0, 0, 77); | ||
//IP4_ADDR(&Remotenetmask, 255, 255, 255, 0); | ||
//IP4_ADDR(&Remotegw, 10, 0, 0, 1); | ||
|
||
print_app_header(); | ||
|
||
/* Initialize the lwip for UDP */ | ||
lwip_init(); | ||
|
||
/* Add network interface to the netif_list, and set it as default */ | ||
if (!xemac_add(echo_netif, &ipaddr, &netmask, | ||
&gw, mac_ethernet_address, | ||
PLATFORM_EMAC_BASEADDR)) { | ||
xil_printf("Error adding N/W interface\n\r"); | ||
return -1; | ||
} | ||
netif_set_default(echo_netif); | ||
|
||
/* now enable interrupts */ | ||
platform_enable_interrupts(); | ||
|
||
/* specify that the network if is up */ | ||
netif_set_up(echo_netif); | ||
|
||
xil_printf("Zedboard IP settings: \r\n"); | ||
print_ip_settings(&ipaddr, &netmask, &gw); | ||
xil_printf("Remote IP settings: \r\n"); | ||
//print_ip_settings(&RemoteAddr, &Remotenetmask, &Remotegw); | ||
print_ip("Board IP: ", &RemoteAddr); | ||
|
||
/* start the application (web server, rxtest, txtest, etc..) */ | ||
status = start_application(); | ||
if (status != 0){ | ||
xil_printf("Error in start_application() with code: %d\n\r", status); | ||
goto ErrorOrDone; | ||
} | ||
|
||
/* receive and process packets */ | ||
while (Error==0) { | ||
|
||
if (TcpFastTmrFlag) { | ||
tcp_fasttmr(); | ||
TcpFastTmrFlag = 0; | ||
//SendResults = 1; | ||
//xil_printf("*"); | ||
} | ||
if (TcpSlowTmrFlag) { | ||
tcp_slowtmr(); | ||
TcpSlowTmrFlag = 0; | ||
SendResults = 1; | ||
} | ||
//xemacif_input(echo_netif); | ||
//transfer_data(); | ||
|
||
/* Receive packets */ | ||
xemacif_input(echo_netif); | ||
|
||
/* Send results back from time to time */ | ||
if (SendResults == 1){ | ||
|
||
SendResults = 0; | ||
// Read the results from the FPGA | ||
Centroid = 0xA5; | ||
|
||
// Send out the centroid result over UDP | ||
psnd = pbuf_alloc(PBUF_TRANSPORT, sizeof(int), PBUF_REF); | ||
psnd->payload = &Centroid; | ||
udpsenderr = udp_sendto(&send_pcb, psnd, &RemoteAddr, RemotePort); | ||
xil_printf("."); | ||
if (udpsenderr != ERR_OK){ | ||
xil_printf("UDP Send failed with Error %d\n\r", udpsenderr); | ||
goto ErrorOrDone; | ||
} | ||
pbuf_free(psnd); | ||
} | ||
} | ||
|
||
// Jump point for failure | ||
ErrorOrDone: | ||
xil_printf("Catastrophic Error! Shutting down and exiting...\n\r"); | ||
|
||
// Disable the GetCentroid interrupts and disconnect from the GIC | ||
//DisableIntrSystem(&Intc, GETCENTROID_INTR_ID, &GetCentroid, TX_INTR_ID); | ||
|
||
cleanup_platform(); | ||
return 0; | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.