TL-LED 发表于 2024-6-12 18:01

【兆易GD32H759I-EVAL】以太网测试

本帖最后由 TL-LED 于 2024-6-12 18:01 编辑

<p><span style="font-size:16px;">这篇通过参考官网的例程来测试下以太网。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:16px;"><strong>一、硬件电路部分</strong></span></p>

<p>&nbsp;</p>

<p><span style="font-size:16px;">以太网部分电路图</span></p>

<p><span style="font-size:16px;">以太网测试需要板子上跳线JP48, JP51, JP57, JP59, JP60, JP70来选择此功能引脚。</span></p>

<p><span style="font-size:16px;"></span></p>

<p>&nbsp;</p>

<p><span style="font-size:16px;"><strong>二、LWIP源码</strong></span></p>

<p>&nbsp;</p>

<p><span style="font-size:16px;">官网的测试例程使用了LWIP,lwip-2.1.2版本。</span></p>

<p><span style="font-size:16px;">源码下载地址:<a href="http://download-mirror.savannah.gnu.org/releases/lwip/" target="_blank">http://download-mirror.savannah.gnu.org/releases/lwip/</a></span></p>

<p>&nbsp;</p>

<p><strong><span style="font-size:16px;">三、程序</span></strong></p>

<p>&nbsp;</p>

<p><span style="font-size:16px;">3.1、hello_gigadevice.c</span></p>

<pre>
<code>/*!
    \file    hello_gigadevice.c
    \brief   TCP server demo program

    \version 2024-01-05, V1.2.0, demo for GD32H7xx
*/

/*
    Copyright (c) 2024, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors
       may be used to endorse or promote products derived from this software without
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#include "hello_gigadevice.h"
#include "lwip/tcp.h"
#include &lt;string.h&gt;
#include &lt;stdio.h&gt;
#include "gd32h7xx.h"

#define GREETING         "\n\r======= HelloGigaDevice =======\
                        \n\r== GD32 ==\
                        \n\r== Telnet SUCCESS==\
                        \n\rHello. What is your name?\r\n"
#define HELLO            "\n\rGigaDevice Hello "
#define MAX_NAME_SIZE    32

extern const uint8_t gd32_str[];
struct name {
    int length;
    char bytes;
};

static err_t hello_gigadevice_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
static err_t hello_gigadevice_accept(void *arg, struct tcp_pcb *pcb, err_t err);
static void hello_gigadevice_conn_err(void *arg, err_t err);

/*!
    \brief      called when a data is received on the telnet connection
    \paramarg: the user argument
    \parampcb: the tcp_pcb that has received the data
    \paramp: the packet buffer
    \paramerr: the error value linked with the received data
    \param none
    \retval   err_t: error value
*/
static err_t hello_gigadevice_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct pbuf *q;
    struct name *name = (struct name *)arg;
    int done;
    char *c;
    int i;

    /* we perform here any necessary processing on the pbuf */
    if(p != NULL) {
      /* we call this function to tell the LwIp that we have processed the data */
      /* this lets the stack advertise a larger window, so more data can be received*/
      tcp_recved(pcb, p-&gt;tot_len);

      /* check the name if NULL, no data passed, return withh illegal argument error */
      if(!name) {
            pbuf_free(p);
            return ERR_ARG;
      }

      done = 0;
      for(q = p; q != NULL; q = q-&gt;next) {
            c = q-&gt;payload;
            for(i = 0; i &lt; q-&gt;len &amp;&amp; !done; i++) {
                /* a telnet communication packet is ended with an enter key */
                done = ((c == '\r') || (c == '\n'));
                if(name-&gt;length &lt; MAX_NAME_SIZE) {
                  /* save the received data to name-&gt;bytes */
                  name-&gt;bytes = c;
                }
            }
      }

      if(done) {
            if(name-&gt;bytes != '\r' || name-&gt;bytes != '\n') {
                /* limit the received data length to MAX_NAME_SIZE - 2('\r' and '\n' will be put into the buffer) */
                if((name-&gt;bytes == '\r' || name-&gt;bytes == '\n') &amp;&amp; (name-&gt;length + 1 &lt;= MAX_NAME_SIZE)) {
                  /* calculate the buffer size to be sent(including '\r' and '\n') */
                  name-&gt;length += 1;
                } else if(name-&gt;length + 2 &lt;= MAX_NAME_SIZE) {
                  name-&gt;length += 2;
                } else {
                  name-&gt;length = MAX_NAME_SIZE;
                }

                name-&gt;bytes = '\r';
                name-&gt;bytes = '\n';
            }

            tcp_write(pcb, HELLO, strlen(HELLO), 1);
            tcp_write(pcb, name-&gt;bytes, name-&gt;length, TCP_WRITE_FLAG_COPY);
            printf("\n\rGigaDevice\n\rTelnet %s %s", HELLO, name-&gt;bytes);
            name-&gt;length = 0;
      }
      /* end of processing, we free the pbuf */
      pbuf_free(p);

    } else if(err == ERR_OK) {
      /* when the pbuf is NULL and the err is ERR_OK, the remote end is closing the connection. */
      /* we free the allocated memory and we close the connection */
      mem_free(name);
      return tcp_close(pcb);
    }
    return ERR_OK;
}

/*!
    \brief      this function when the Telnet connection is established
    \paramarg: user supplied argument
    \parampcb: the tcp_pcb which accepted the connection
    \paramerr: error value
    \param none
    \retval   err_t: error value
*/
static err_t hello_gigadevice_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
    u32_t ipaddress;
    u8_t iptxt;
    u8_t iptab;

    ipaddress = pcb-&gt;remote_ip.addr;
    printf("\n\rTelnet hello_gigadevice_accept:%d.%d.%d.%d%s",
         (u8_t)(ipaddress), (u8_t)(ipaddress &gt;&gt; 8), (u8_t)(ipaddress &gt;&gt; 16), (u8_t)(ipaddress &gt;&gt; 24), GREETING);

    /* read its IP address */
    iptab = (u8_t)(ipaddress &gt;&gt; 24);
    iptab = (u8_t)(ipaddress &gt;&gt; 16);
    iptab = (u8_t)(ipaddress &gt;&gt; 8);
    iptab = (u8_t)(ipaddress);

    sprintf((char *)iptxt, "Telnet:%d.%d.%d.%d   ", iptab, iptab, iptab, iptab);
    printf("%s\r\n", iptxt);
    /* tell LwIP to associate this structure with this connection. */
    tcp_arg(pcb, mem_calloc(sizeof(struct name), 1));

    /* configure LwIP to use our call back functions. */
    tcp_err(pcb, hello_gigadevice_conn_err);
    tcp_recv(pcb, hello_gigadevice_recv);

    /* send out the first message */
    tcp_write(pcb, iptxt, strlen((char *)iptxt), 1);
    sprintf((char *)iptxt, "You telnet computer's IP is: %d.%d.%d.%d\n", iptab, iptab, iptab, iptab);
    printf("%s\r\n", iptxt);
    tcp_write(pcb, gd32_str, strlen((char *)gd32_str), 1);
    tcp_write(pcb, GREETING, strlen(GREETING), 1);

    return ERR_OK;
}

/*!
    \brief      initialize the hello application
    \paramnone
    \param none
    \retval   none
*/
void hello_gigadevice_init(void)
{
    struct tcp_pcb *pcb;

    /* create a new TCP control block */
    pcb = tcp_new();

    /* assign to the new pcb a local IP address and a port number */
    /* using IP_ADDR_ANY allow the pcb to be used by any local interface */
    tcp_bind(pcb, IP_ADDR_ANY, 8000);

    /* set the connection to the LISTEN state */
    pcb = tcp_listen(pcb);

    /* Specify the function to be called when a connection is established */
    tcp_accept(pcb, hello_gigadevice_accept);
}

/*!
    \brief      this function is called when an error occurs on the connection
    \paramarg: user supplied argument
    \paramerr: error value
    \param none
    \retval   none
*/
static void hello_gigadevice_conn_err(void *arg, err_t err)
{
    struct name *name;
    name = (struct name *)arg;

    mem_free(name);
}
</code></pre>

<p>&nbsp;</p>

<p><span style="font-size:16px;">3.2、tcp_client.c</span></p>

<pre>
<code>/*!
    \file    tcp_client.c
    \brief   TCP client demo program

    \version 2024-01-05, V1.2.0, demo for GD32H7xx
*/

/*
    Copyright (c) 2024, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors
       may be used to endorse or promote products derived from this software without
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#include "tcp_client.h"
#include "lwip/tcp.h"
#include "lwip/memp.h"
#include &lt;string.h&gt;
#include &lt;stdio.h&gt;
#include "gd32h7xx.h"
#include "main.h"

#define MAX_BUF_SIZE    50

struct recev_packet {
    int length;
    char bytes;
};

static err_t tcp_client_connected(void *arg, struct tcp_pcb *pcb, err_t err);
static err_t tcp_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);

/*!
    \brief      called when a data is received on the tcp connection
    \paramarg: the user argument
    \parampcb: the tcp_pcb that has received the data
    \paramp: the packet buffer
    \paramerr: the error value linked with the received data
    \param none
    \retval   err_t: error value
*/
static err_t tcp_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct pbuf *q;
    struct recev_packet *recev_packet = (struct recev_packet *)arg;
    int buf_full;
    char *c;
    int i;

    /* we perform here any necessary processing on the pbuf */
    if(p != NULL) {
      /* we call this function to tell the LwIp that we have processed the data */
      /* this lets the stack advertise a larger window, so more data can be received*/
      tcp_recved(pcb, p-&gt;tot_len);

      /* check the name if NULL, no data passed, return withh illegal argument error */
      if(!recev_packet) {
            pbuf_free(p);
            return ERR_ARG;
      }

      buf_full = 0;

      for(q = p; q != NULL; q = q-&gt;next) {

            c = q-&gt;payload;
            for(i = 0; i &lt; q-&gt;len &amp;&amp; !buf_full; i++) {
                /* if the received data size is larger than the size we want to get */
                if(recev_packet-&gt;length &lt; MAX_BUF_SIZE) {
                  recev_packet-&gt;bytes = c;
                  recev_packet-&gt;length++;
                } else {
                  buf_full = 1;
                }
            }
      }

      /* send out the message */
      tcp_write(pcb, recev_packet-&gt;bytes, recev_packet-&gt;length, 1);
      recev_packet-&gt;length = 0;

      pbuf_free(p);

    } else if(ERR_OK == err) {

      mem_free(recev_packet);
      return tcp_close(pcb);
    }

    return ERR_OK;
}

/*!
    \brief      this function when the connection is established
    \paramarg: user supplied argument
    \parampcb: the tcp_pcb which accepted the connection
    \paramerr: error value
    \param none
    \retval   err_t: error value
*/
static err_t tcp_client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
    tcp_arg(pcb, mem_calloc(sizeof(struct recev_packet), 1));
    /* configure LwIP to use our call back functions */
    tcp_recv(pcb, tcp_client_recv);

    return ERR_OK;
}

/*!
    \brief      initialize the tcp_client application
    \paramnone
    \param none
    \retval   none
*/

void tcp_client_init(void)
{
    struct tcp_pcb *pcb;
    ip_addr_t ipaddr;

    IP4_ADDR(&amp;ipaddr, IP_S_ADDR0, IP_S_ADDR1, IP_S_ADDR2, IP_S_ADDR3);

    /* create a new TCP control block*/
    pcb = tcp_new();

    /* assign to the new pcb a local IP address and a port number */
    /* using IP_ADDR_ANY allow the pcb to be used by any local interface */
    if(ERR_USE != tcp_bind(pcb, IP_ADDR_ANY, 10260)) {
      /* Specify the function to be called when a connection is established */
      tcp_connect(pcb, &amp;ipaddr, 10260, tcp_client_connected);
    } else {
      printf("connect is still alive \r\n ");
      memp_free(MEMP_TCP_PCB, pcb);
    }

}
</code></pre>

<p>&nbsp;</p>

<p><span style="font-size:16px;">3.3、udp_echo.c</span></p>

<pre>
<code>/*!
    \file    udp_echo.c
    \brief   UDP demo program

    \version 2024-01-05, V1.2.0, demo for GD32H7xx
*/

/*
    Copyright (c) 2024, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors
       may be used to endorse or promote products derived from this software without
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#include "udp_echo.h"
#include "lwip/udp.h"
#include &lt;string.h&gt;
#include &lt;stdio.h&gt;
#include "gd32h7xx.h"

static void udp_echo_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);


/*!
    \brief      called when a data is received on the udp connection
    \paramargs: the user argument
    \parampcb: the udp_pcb that has received the data
    \paramp: the packet buffer
    \paramaddr: pointer on the receive IP address
    \paramport: receive port number
    \param none
    \retval   none
*/
static void udp_echo_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
    ip_addr_t destaddr = *addr;

    if(p != NULL) {
      udp_sendto(pcb, p, &amp;destaddr, port);
      /* end of processing, we free the pbuf */
      pbuf_free(p);
    }
}

/*!
    \brief      initialize the udp_client application
    \paramnone
    \param none
    \retval   none
*/
void udp_echo_init(void)
{
    struct udp_pcb *udppcb;

    /* create a new UDP control block */
    udppcb = udp_new();
    /* assign to the new pcb a local IP address and a port number */
    udp_bind(udppcb, IP_ADDR_ANY, 1025);
    udp_recv(udppcb, udp_echo_recv, NULL);

}

</code></pre>

<p>&nbsp;</p>

<p>3.4、main.c</p>

<pre>
<code>#include "main.h"

#define SYSTEMTICK_PERIOD_MS10

__IO uint32_t g_localtime = 0; /* for creating a time reference incremented by 10ms */
uint32_t g_timedelay;
void cache_enable(void);
void mpu_config(void);


int main(void)
{
        cache_enable();
        //systick_config();
        mpu_config();
        init_usart(115200);
       
        enet_system_setup();
        lwip_stack_init();
       
       
while(1) {

#ifdef USE_ENET0
#ifndef USE_ENET_INTERRUPT
      /* check if any packet received */
      if(enet_rxframe_size_get(ENET0)) {
            /* process received ethernet packet */
            lwip_pkt_handle0();
      }
#endif /* USE_ENET_INTERRUPT */
#endif /* USE_ENET0 */

#ifdef USE_ENET1
#ifndef USE_ENET_INTERRUPT
      /* check if any packet received */
      if(enet_rxframe_size_get(ENET1)) {
            /* process received ethernet packet */
            lwip_pkt_handle1();
      }
#endif /* USE_ENET_INTERRUPT */
#endif /* USE_ENET1 */

      /* handle periodic timers for LwIP */
#ifdef TIMEOUT_CHECK_USE_LWIP
      sys_check_timeouts();

#ifdef USE_DHCP
      lwip_dhcp_process_handle();
#endif /* USE_DHCP */

#else
      lwip_periodic_handle(g_localtime);
#endif /* TIMEOUT_CHECK_USE_LWIP */


    }
}

void cache_enable(void)
{
    /* enable i-cache */
    SCB_EnableICache();

    /* enable d-cache */
    SCB_EnableDCache();
}

/*!
    \brief      after the netif is fully configured, it will be called to initialize the function of telnet, client and udp
    \paramnetif: the struct used for lwIP network interface
    \param none
    \retval   none
*/
void lwip_netif_status_callback(struct netif *netif)
{
    if(((netif-&gt;flags &amp; NETIF_FLAG_UP) != 0) &amp;&amp; (0 != netif-&gt;ip_addr.addr)) {
      /* initilaize the helloGigadevice module telnet 8000 */
      hello_gigadevice_init();
      /* initilaize the tcp client: echo 10260 */
      tcp_client_init();
      /* initilaize the udp: echo 1025 */
      udp_echo_init();
    }
}

/*!
    \brief      insert a delay time
    \paramncount: number of 10ms periods to wait for
    \param none
    \retval   none
*/
void delay_10ms(uint32_t ncount)
{
    /* capture the current local time */
    g_timedelay = g_localtime + ncount;

    /* wait until the desired delay finish */
    while(g_timedelay &gt; g_localtime) {
    }
}

/*!
    \brief      updates the system local time
    \paramnone
    \param none
    \retval   none
*/
void time_update(void)
{
    g_localtime += SYSTEMTICK_PERIOD_MS;
}

/*!
    \brief      configure the MPU
    \paramnone
    \param none
    \retval   none
*/
void mpu_config(void)
{
    mpu_region_init_struct mpu_init_struct;
    mpu_region_struct_para_init(&amp;mpu_init_struct);

    /* disable the MPU */
    ARM_MPU_SetRegion(0U, 0U);

    /* Configure the DMA descriptors and Rx/Tx buffer*/
    mpu_init_struct.region_base_address = 0x30000000;
    mpu_init_struct.region_size = MPU_REGION_SIZE_16KB;
    mpu_init_struct.access_permission = MPU_AP_FULL_ACCESS;
    mpu_init_struct.access_bufferable = MPU_ACCESS_BUFFERABLE;
    mpu_init_struct.access_cacheable = MPU_ACCESS_NON_CACHEABLE;
    mpu_init_struct.access_shareable = MPU_ACCESS_NON_SHAREABLE;
    mpu_init_struct.region_number = MPU_REGION_NUMBER0;
    mpu_init_struct.subregion_disable = MPU_SUBREGION_ENABLE;
    mpu_init_struct.instruction_exec = MPU_INSTRUCTION_EXEC_PERMIT;
    mpu_init_struct.tex_type = MPU_TEX_TYPE0;
    mpu_region_config(&amp;mpu_init_struct);
    mpu_region_enable();

    /* Configure the LwIP RAM heap */
    mpu_init_struct.region_base_address = 0x30004000;
    mpu_init_struct.region_size = MPU_REGION_SIZE_16KB;
    mpu_init_struct.access_permission = MPU_AP_FULL_ACCESS;
    mpu_init_struct.access_bufferable = MPU_ACCESS_NON_BUFFERABLE;
    mpu_init_struct.access_cacheable = MPU_ACCESS_NON_CACHEABLE;
    mpu_init_struct.access_shareable = MPU_ACCESS_SHAREABLE;
    mpu_init_struct.region_number = MPU_REGION_NUMBER1;
    mpu_init_struct.subregion_disable = MPU_SUBREGION_ENABLE;
    mpu_init_struct.instruction_exec = MPU_INSTRUCTION_EXEC_PERMIT;
    mpu_init_struct.tex_type = MPU_TEX_TYPE1;
    mpu_region_config(&amp;mpu_init_struct);
    mpu_region_enable();

    /* enable the MPU */
    ARM_MPU_Enable(MPU_MODE_PRIV_DEFAULT);
}
</code></pre>

<p>&nbsp;</p>

<p><span style="font-size:16px;"><strong>四、测试</strong></span></p>

<p>&nbsp;</p>

<p><span style="font-size:16px;">4.1、TCP服务器测试</span></p>

<p><span style="font-size:16px;">开发板为TCP服务器端,PC为TCP客户端。</span></p>

<p><span style="font-size: 16px;">建立连接后,通信内容如下:</span></p>

<p></p>

<p>&nbsp;</p>

<p><span style="font-size:16px;">4.2、TCP客户端测试</span></p>

<p><span style="font-size:16px;">开发板为TCP客户端,PC为TCP服务器端。测试时先打开PC端服务器再给开发板上电。</span></p>

<p><span style="font-size:16px;">建立连接后,通信内容如下:</span></p>

<p></p>

<div style="text-align: center;">&nbsp;</div>

<p>4.3、UDP测试</p>

<p>PC的IP地址端口号和开发板IP地址端口号要一致。</p>

<p>建立连接后,通信内容如下:</p>

<p></p>

<p>&nbsp;</p>

<p><strong><span style="font-size:16px;">五、附件</span></strong></p>

<p>&nbsp;</p>

<div><span style="font-size:16px;">源代码:</span></div>

Jacktang 发表于 2024-6-14 07:32

<p>官网的例程结合硬件电路,可以看懂了</p>

NA·World 发表于 2024-8-5 14:30

<pre id="code_3">
<code class="hljs cs">ARM_MPU_Enable 找不到定义</code></pre>

TL-LED 发表于 2024-8-5 15:20

<div style="text-align: center;">&nbsp;</div>

<p>&nbsp;</p>

<div style="text-align: center;">&nbsp;</div>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

bwxz 发表于 2024-8-26 15:52

<p>速率多少?</p>
页: [1]
查看完整版本: 【兆易GD32H759I-EVAL】以太网测试