自学内容网 自学内容网

​HPM6700——以太网通信lwip_udpecho_freertos_socket

1. 概述

本示例展示在FreeRTOS系统下的UDP回送通讯

  • PC 通过以太网发送UDP数据帧至MCU,MCU将接收的数据帧回发至PC

2. 硬件设置

  • 使用USB Type-C线缆连接PC USB端口和PWR DEBUG端口

  • 使用以太网线缆连接PC以太网端口和开发板RGMII或RMII端口

3. 工程配置

  • 以太网端口配置:参考 以太网通用工程设置

  • 以太网DHCP配置

    • lwIP sample: 在 CMakeLists.txt中,支持如下配置:

      • sdk_compile_definitions(-DLWIP_DHCP=0): 禁用DHCP功能

      • sdk_compile_definitions(-DLWIP_DHCP=1): 启用DHCP功能

主线程示例

void Main_task(void *pvParameters)
{
    (void)pvParameters;

    TimerHandle_t timer_handle;

    /* Initialize MAC and DMA */
    enet_init(ENET);

    /* Initialize LwIP stack */
    tcpip_init(NULL, NULL);
    netif_config(&gnetif);

    udp_echo_init();

#if defined(LWIP_DHCP) && LWIP_DHCP
    /* Start DHCP Client */
    xTaskCreate(LwIP_DHCP_task, "DHCP", configMINIMAL_STACK_SIZE * 2, &gnetif, DHCP_TASK_PRIO, NULL);
#endif

    xTaskCreate(netif_update_link_status, "netif update status", configMINIMAL_STACK_SIZE * 2, &gnetif, NETIF_STA_TASK_PRIO, NULL);

    timer_handle = xTimerCreate((const char *)NULL,
                                (TickType_t)1000,
                                (UBaseType_t)pdTRUE,
                                (void * const)1,
                                (TimerCallbackFunction_t)timer_callback);

    if (NULL != timer_handle)  {
        xTimerStart(timer_handle, 0);
    }

    vTaskDelete(NULL);
}

UDP_ECHO线程

static void udp_echo_thread(void *arg)
{
    (void)arg;

    int sock = -1;
    char *recv_data;
    struct sockaddr_in udp_addr, seraddr;
    int recv_data_len;
    socklen_t addrlen;

    while (1) {
        recv_data = (char *)pvPortMalloc(RECV_DATA);
        if (recv_data == NULL) {
            printf("Memory error\n");
            goto __exit;
        }

        sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock < 0) {
            printf("Socket error\n");
            goto __exit;
        }

        udp_addr.sin_family = AF_INET;
        udp_addr.sin_addr.s_addr = INADDR_ANY;
        udp_addr.sin_port = htons(UDP_ECHO_PORT);
        memset(&(udp_addr.sin_zero), 0, sizeof(udp_addr.sin_zero));

        if (bind(sock, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1) {
            printf("Bind error\n");
            goto __exit;
        }
        while (1) {
            recv_data_len = recvfrom(sock, recv_data, RECV_DATA, 0, (struct sockaddr *)&seraddr, &addrlen);
            sendto(sock, recv_data, recv_data_len, 0, (struct sockaddr *)&seraddr, addrlen);
        }

__exit:
        if (sock >= 0) {
            closesocket(sock);
        }

        if (recv_data) {
            free(recv_data);
        }
    }
}
/*-----------------------------------------------------------------------------------*/
void udp_echo_init(void)
{
    sys_thread_new("udp_echo_thread", udp_echo_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
}

4. 运行示例

  • 编译下载程序

  • 串口终端显示如下信息:

    This is an ethernet demo: UDP Echo With Socket API On FreeRTOS
    LwIP Version: 2.1.2
    Enet phy init passed !
    Link Status: Down
    Link Status: Up
    Link Speed:  1000Mbps
    Link Duplex: Full duplex
    IPv4 Address: 192.168.100.10
    IPv4 Netmask: 255.255.255.0
    IPv4 Gateway: 192.168.100.1
    
  • 打开以太网调试工具

    • 选择协议类型:UDP

    • 选择本地主机地址及端口

    • 打开

    • 选择远程主机地址及端口

    • 在数据发送窗口编辑发送字符

    • 观察回送数据

      img


原文地址:https://blog.csdn.net/weixin_55171106/article/details/145155808

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!