change in endianness while ethernet transmission

2

I work with zedboard and vivado v2017.3. I am trying to send data stored in a register(slv_reg0 in PL section of Zynq) pointed by baseaddr_p in the following program.

I use lwip echo server application to read this address and send it to the PC via Ethernet.

This part of the code is executed when a echo request (telnet) is received.In this part of the code I also print the read values in gtkterm so that i can verify the received data.

void process_echo_request(void *p)
{
    int sd = (int)p;
    int RECV_BUF_SIZE = 2048;
    char recv_buf[RECV_BUF_SIZE];
    int n,i,nwrote;
    unsigned long my_buffer[10];
    i=0;
    init_platform();
    while(1){
    while(i<11)
    {
    Xuint32 *baseaddr_p = (Xuint32 *)XPAR_MYIP_0_S00_AXI_BASEADDR;
    my_buffer[i] = *(baseaddr_p);
    xil_printf("0x%08x \n\r", my_buffer[i]);
    i++;}
    //xil_printf("0x%08x \n\r", my_buffer);
     /* handle request */
    if ((nwrote = write(sd, my_buffer, sizeof (my_buffer))) < 0) {
        xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",
                __FUNCTION__, n, nwrote);
        xil_printf("Closing socket %d\r\n", sd);
     break;

    }

    while (1) {
        /* read a max of RECV_BUF_SIZE bytes from socket */
        if ((n = read(sd, recv_buf, RECV_BUF_SIZE)) < 0) {
            xil_printf("%s: error reading from socket %d, closing socket\r\n", __FUNCTION__, sd);
            break;
        }

        /* break if the recved message = "quit" */
        if (!strncmp(recv_buf, "quit", 4))
            break;

        /* break if client closed connection */
        if (n <= 0)
            break;


        }
    }

    /* close connection */
    close(sd);
    vTaskDelete(NULL);
    cleanup_platform();
}

gtkterm result: read values 0x00000004 0x00000005 0x00000006 0x00000007 0x00000008 0x00000009 0x0000000A 0x0000000B 0x0000000C 0x0000000D 0x0000000E

While receiving these data there seems to a byte reversal happening.

Received data: 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00 0D 00 00 00

Any suggestion on why its happening and a possible workaround for that?

c
vivado
zynq
asked on Stack Overflow May 18, 2018 by upasana • edited May 18, 2018 by Vinay P

2 Answers

3

The issue is due to endianess. When you are sending and receiving data it is always good to do host to network and vice-versa conversions.

There are two POSIX APIs to do those byte order conversions: htonl and ntohl

On receiving side try to do network to host byte order conversion, if you have access to sender side do the opposite there.

answered on Stack Overflow May 18, 2018 by Vinay P • edited May 18, 2018 by Vinay P
2

Your source machine uses little-endian internal representation for integers. Its xil_printf() function accounts for this to format numbers in the canonical way for human consumption. The byte-swapping is there, and it is benign.

On the other hand, write() doesn't know or care about the significance of the data you hand to it. It treats everything simply as a sequence of bytes, and it transfers them in the order they appear. Similarly, the read() function receives and stores bytes in the order they come over the wire. No byte-swapping occurs there.

If you can rely on the machine receiving the data to interpret it according to the same numeric format (size, byte order, etc.) then there is no problem. If not, then you need either to put the data into a standard format for transmission over the wire, or send some indicator of the source machine's format, which the receiver is expected to handle appropriately.

The former approach is much more common. This is, in fact, the role of the htonl() and ntohl() functions defined by POSIX. If you don't have those, they are not too hard to implement yourself -- the biggest trick (and it's not that big) is determining the native byte order.

answered on Stack Overflow May 18, 2018 by John Bollinger

User contributions licensed under CC BY-SA 3.0