изменение порядка байтов при передаче Ethernet - PullRequest
0 голосов
/ 18 мая 2018

Я работаю с zedboard и vivado v2017.3.Я пытаюсь отправить данные, хранящиеся в регистре (slv_reg0 в разделе PL в Zynq), на который указывает baseaddr_p в следующей программе.

Я использую приложение lwip echo server, чтобы прочитать этот адрес и отправить его на ПК через Ethernet.

Эта часть кода выполняется при получении эхо-запроса (telnet). В этомчасть кода Я также печатаю прочитанные значения в gtkterm, чтобы я мог проверить полученные данные.

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: чтение значений 0x00000004 0x00000005 0x00000006 0x00000007 0x00000008 0x00000009 0x0000000A 0x0000000 0000000000000x00x00x00x00x00x00x00x00x00x0000x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00000000000000000000001009 * При получении этих данных, похоже, происходит обращение байтов.

Полученные данные: 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 00 00 00 09 00 00 00 0A 00 0000 0B 00 00 00 0C 00 00 00 0D 00 00 00

Любое предложение о том, почему это происходит, и возможный обходной путь для этого?

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Ваш исходный компьютер использует внутреннее представление с прямым порядком байтов для целых чисел.Его функция xil_printf() учитывает это для форматирования чисел каноническим способом для потребления человеком.Подстановка байтов там , и она доброкачественная.

С другой стороны, write() не знает и не заботится о значимости данных, которые вы ему передаете.Он обрабатывает все просто как последовательность байтов и передает их в порядке их появления.Аналогично, функция read() получает и сохраняет байты в порядке их поступления по проводам.Там не происходит перестановка байтов.

Если вы можете полагаться на то, что аппарат, принимающий данные, интерпретирует их в соответствии с тем же числовым форматом (размер, порядок байтов и т. Д.), То проблем нет.Если нет, то вам нужно либо поместить данные в стандартный формат для передачи по проводам, либо отправить какой-либо индикатор формата исходного устройства, с которым, как ожидается, получатель будет обращаться соответствующим образом.

Первый подход заключается в следующем.гораздо чаще встречается.На самом деле это роль функций htonl() и ntohl() , определенных в POSIX.Если у вас их нет, их не сложно реализовать самостоятельно - самый большой трюк (и это не , что большой) - это определение собственного порядка байтов.

0 голосов
/ 18 мая 2018

Проблема связана с endianess .Когда вы отправляете и получаете данные, всегда хорошо выполнять преобразование хост в сеть и наоборот.

Существует два API POSIX для выполнения этих преобразований порядка байтов: htonl и ntohl

На принимающей стороне попробуйте выполнить преобразование порядка следования байтов в сеть, если у вас есть доступ на стороне отправителя, выполните обратное.

...