如何正确设置 ESP32 上 TCP/IP 适配器的主机名

Mic*_*ied 3 c embedded tcp driver esp32

问题

Espressif 的 ESP-32(在本例中特别是 ESP-WROOM-32)出现在默认主机名“Espressif”的网络上。我不想使用这个主机名,所以我选择如下更改它:

    // Initialize the TCP/IP adapter (launches handler task)
    tcpip_adapter_init();

    // Set the hostname for the default TCP/IP station interface
    if ((err = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, g_hostname))
            != ESP_OK) {
        return err;
    }

Run Code Online (Sandbox Code Playgroud)

当然,这行不通。我得到以下错误:ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY.


尝试的解决方案

为了解决这个问题,我会查看 TCP/IP 适配器在完成初始化时是否会发布某种事件。这样我就可以注册一个处理程序来设置主机名。此处的乐鑫 WiFi 驱动程序指南表明任务已启动 - 所以可能有一个事件:

“主任务调用 tcpip_adapter_init() 创建LwIP 核心任务并初始化 LwIP 相关工作。”

好吧,我找不到任何此类事件。无论是API文档,也不是实际的文件本身(tcpip_adapter.h)有它。我检查了事件的头文件,似乎没有任何事件仅用于指示 TCP/IP 适配器已完成启动

/** IP event declarations */
typedef enum {
    IP_EVENT_STA_GOT_IP,               /*!< ESP32 station got IP from connected AP */
    IP_EVENT_STA_LOST_IP,              /*!< ESP32 station lost IP and the IP is reset to 0 */
    IP_EVENT_AP_STAIPASSIGNED,         /*!< ESP32 soft-AP assign an IP to a connected station */
    IP_EVENT_GOT_IP6,                  /*!< ESP32 station or ap or ethernet interface v6IP addr is preferred */
    IP_EVENT_ETH_GOT_IP,               /*!< ESP32 ethernet got IP from connected AP */
} ip_event_t;
Run Code Online (Sandbox Code Playgroud)

可能的铅

我注意到在Espressif 的 WiFi 指南中,他们指出该事件SYSTEM_EVENT_STA_START(表明站点已启动)将:

收到此事件后,事件任务将初始化 LwIP 网络接口 (netif)。

如果我在处理程序收到此事件后发出调用,则不会再收到错误消息:


    // After the event WIFI_EVENT_STA_START
    if (base == WIFI_EVENT && id == WIFI_EVENT_STA_START) {

        // Set the hostname for the default TCP/IP station interface
        if ((err = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, g_hostname))
                != ESP_OK) {
            fprintf(stderr, "Err: %s", esp_err_to_name(err));
        }
        ...
    }

Run Code Online (Sandbox Code Playgroud)

但是,主机名仍然没有改变。因此我发现自己有点卡住了。我怎样才能真正更改主机名?我几乎没有发现搜索这个问题的结果。然而,esp32 是一个流行的模块,我相信很多其他人会发现自己面临同样的问题。

Mic*_*ied 5

事实证明我做对了。是我的路由器未能充分刷新主机名。为了保持一致性,我将重申我为解决这个问题所做的工作:


Espressif无线指南表示事件SYSTEM_EVENT_STA_START一旦发生esp_wifi_start()成功返回。

这个事件的产生也意味着事件任务会初始化LwIP网络接口(netif)。由于我们知道此时 TCP/IP 适配器肯定已经初始化,因此我们可以调用主机名更改函数。这是一个执行此操作的处理程序示例,直接取自他们的示例:

void wifi_event_handler (void *handler_arg, esp_event_base_t base, int32_t id,
    void *event_data) {
    esp_err_t err;

    // If esp_wifi_start() returned ESP_OK and WiFi mode is in station mode
    if (base == WIFI_EVENT && id == WIFI_EVENT_STA_START) {
        const char *name;

        // Set the hostname for the default TCP/IP station interface
        if ((err = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, g_hostname))
                != ESP_OK) {
            fprintf(stderr, "Err: %s", esp_err_to_name(err));
        } else {
            if ((err = tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &name)) != ESP_OK) {
                fprintf(stderr, "Err Get Hostname: %s\n", esp_err_to_name(err));
            } else {
                printf("Hostname: %s\n", (name == NULL ? "<None>" : name));
            }
        }
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,我在设置后获取主机名,并将其打印为stdout. 如果您正在运行 ESP32 的监视器,则可以对其进行验证。主机名集将是从路由器页面可见的主机名。