You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Zedboard+Vivado环境下PL数据经以太网传输至PC方案咨询

Hey Upasana, great to hear you’ve already nailed the PL-to-PS data reading and terminal output—you’re halfway there! Here’s a practical, step-by-step breakdown to get those 32-bit values sent over Ethernet to your PC:


方案1:PS端运行Linux系统(最便捷,推荐)

Zedboard plays nicely with Linux (Petalinux or pre-built images), and standard socket programming makes this straightforward.

Step 1: Configure Ethernet on Linux

  • Build or flash a Linux image for your Zedboard (Petalinux is ideal for custom setups). Ensure the Ethernet driver is enabled (it’s usually on by default).
  • Boot the board, then set a static IP on the same subnet as your PC. For example:
    ifconfig eth0 192.168.1.10 netmask 255.255.255.0
    
    Set your PC’s IP to something like 192.168.1.20 and confirm connectivity with a ping 192.168.1.20 from the Zedboard.

Step 2: Write a C Program to Read & Send Data

You’ll need to map the PL’s physical register address to user space, then send the data over TCP:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdint.h>

#define REG_PHYS_ADDR 0x43c00000
#define REG_SIZE 4 // 32-bit register

int main() {
    // Map PL register to user space
    int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (mem_fd < 0) { perror("Failed to open /dev/mem"); return -1; }
    
    volatile uint32_t *reg_ptr = mmap(NULL, REG_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, REG_PHYS_ADDR);
    if (reg_ptr == MAP_FAILED) { perror("MMAP failed"); close(mem_fd); return -1; }

    // Create TCP socket
    int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_fd < 0) { perror("Socket creation failed"); return -1; }

    struct sockaddr_in pc_addr;
    pc_addr.sin_family = AF_INET;
    pc_addr.sin_port = htons(8080); // Pick any unused port
    pc_addr.sin_addr.s_addr = inet_addr("192.168.1.20"); // Your PC's IP

    // Connect to PC
    if (connect(sock_fd, (struct sockaddr *)&pc_addr, sizeof(pc_addr)) < 0) {
        perror("Connection to PC failed"); return -1;
    }

    // Loop to read and send data
    while(1) {
        uint32_t value = *reg_ptr;
        printf("Sending value: %u\n", value);
        send(sock_fd, &value, sizeof(value), 0);
        sleep(1); // Adjust interval as needed
    }

    // Cleanup (you'll never reach this, but good practice)
    munmap((void*)reg_ptr, REG_SIZE);
    close(mem_fd);
    close(sock_fd);
    return 0;
}
  • Cross-compile this code using Petalinux’s toolchain or Xilinx SDK, then transfer it to the Zedboard (via scp or SD card).

Step 3: PC-side Receiver

Use a simple Python script to listen for incoming data:

import socket

HOST = '0.0.0.0'  # Listen on all interfaces
PORT = 8080

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    conn, addr = s.accept()
    with conn:
        print(f"Connected to Zedboard at {addr}")
        while True:
            data = conn.recv(4)
            if not data:
                break
            # Zynq is little-endian; adjust if your system uses big-endian
            value = int.from_bytes(data, byteorder='little')
            print(f"Received value: {value}")

Run the PC script first, then execute the program on the Zedboard—you’ll start seeing values pop up!


方案2:PS端裸机运行(Xilinx LWIP Library)

If you don’t want Linux, use Xilinx’s LWIP stack for bare-metal Ethernet communication:

Step 1: Configure Hardware in Vivado

  • Enable the PS’s Ethernet0 interface and confirm MIO pin mappings (Zedboard’s Ethernet pins are pre-configured by default).
  • Generate the bitstream and export the hardware design to Xilinx SDK.

Step 2: Set Up SDK Project

  • Create a bare-metal application project, then add the LWIP library to your project.
  • Modify lwipopts.h to set your Zedboard’s IP, subnet mask, and gateway (match your PC’s subnet).

Step 3: Bare-Metal Code Example

Directly access the PL register and send data over TCP:

#include "xil_printf.h"
#include "lwip/tcp.h"
#include "stdint.h"

#define REG_ADDR ((volatile uint32_t *)0x43c00000)
#define PC_IP "192.168.1.20"
#define PC_PORT 8080

static err_t tcp_send_callback(void *arg, struct tcp_pcb *pcb, err_t err) {
    (void)arg; (void)err;
    return ERR_OK;
}

void send_pl_data(void) {
    struct tcp_pcb *pcb;
    err_t err;
    ip_addr_t pc_ip;

    // Initialize TCP connection
    pcb = tcp_new();
    if (!pcb) { xil_printf("Failed to create TCP PCB\n"); return; }

    IP4_ADDR(&pc_ip, 192, 168, 1, 20);
    err = tcp_connect(pcb, &pc_ip, PC_PORT, tcp_send_callback);
    if (err != ERR_OK) { xil_printf("TCP connect failed: %d\n", err); return; }

    // Loop to read and send data
    while(1) {
        uint32_t value = *REG_ADDR;
        xil_printf("Sending: %u\n", value);
        tcp_write(pcb, &value, sizeof(value), TCP_WRITE_FLAG_COPY);
        tcp_output(pcb);
        sleep(1);
    }
}

int main() {
    lwip_init();
    send_pl_data();
    return 0;
}
  • Reference Xilinx’s LWIP example projects to handle timers and network stack initialization properly—bare-metal requires a bit more setup for LWIP to run smoothly.

Quick Tips

  • Byte Order: Zynq uses little-endian format. Most PCs do too, but if you see garbled values, use ntohl() (for network-to-host byte order) in your receiver code.
  • Reliability: Use TCP for guaranteed delivery, or UDP if you prioritize speed over perfect reliability.
  • Debugging: If Ethernet fails, first ping between the Zedboard and PC. On Linux, check ifconfig eth0 to confirm the interface is up. On bare-metal, use SDK’s debug console to check network initialization logs.

内容的提问来源于stack exchange,提问作者upasana

火山引擎 最新活动