- HAL库版本:STM32Cube_FW_H7_V1.11.0
- LwIP版本:V2.1.2(HAL库中自带的LwIP)
1 使能 IGMP
mDNS 依赖 IGMP 协议,这里先使能 IGMP 协议。
- 在
lwipopts.h
文件中添加
#define LWIP_ICMP 1
- 在
ethernetif.c
中low_level_init()
函数中打开网卡的 IGMP 功能
netif->flags |= NETIF_FLAG_IGMP;
- STM32 H7 中的 MAC 默认会打开广播、屏蔽组播,需要配置 MAC 过滤器。同样在
ethernetif.c
中low_level_init()
函数中添加
/* 从 ETH 寄存器中获取 Mac 过滤器参数 */
ETH_MACConfigTypeDef MACConf = {0};
ETH_MACFilterConfigTypeDef MACFilterConfig;
EthHandle.Instance = ETH;
/* 此处省略一部分 */
/* 从 ETH 寄存器中获取默认的 Mac 过滤器参数 */
HAL_ETH_GetMACFilterConfig(&EthHandle, &MACFilterConfig);
/* 使能组播过滤器, 接收组播消息 */
MACFilterConfig.PassAllMulticast = ENABLE;
/* 设置 Mac 过滤器参数 */
HAL_ETH_SetMACFilterConfig(&EthHandle, &MACFilterConfig);
- 如果需要屏蔽广播, 可以将
netif->flags
中的NETIF_FLAG_BROADCAST
标志位取消掉,或者添加下面代码从 MAC 层屏蔽掉广播
/* 从 ETH 寄存器中获取默认的 Mac 过滤器参数 */
HAL_ETH_GetMACFilterConfig(&EthHandle, &MACFilterConfig);
/* 关闭广播过滤器, 拒绝所有广播消息 */
MACFilterConfig.BroadcastFilter = DISABLE;
/* 设置 Mac 过滤器参数 */
HAL_ETH_SetMACFilterConfig(&EthHandle, &MACFilterConfig);
2 使能 mDNS
- 将
LwIP/src/apps/mdns/mdns.c
文件添加到工程中
- 在
lwipopts.h
文件中添加
/* 使能 mDNS */
#define LWIP_MDNS_RESPONDER 1
/* 每个 Netif 最大的服务数量, 如果不设置, 则默认为 1 */
#define MDNS_MAX_SERVICES 1
/* mDNS 需要 Netif 上的 1 个条目, 如果之前没有, 则设为 1, 如果存在则增加 1 */
#define LWIP_NUM_NETIF_CLIENT_DATA 1
/* mDNS 需要 1 个udp pcb 块, 在之前的基础上增加 1 */
#define MEMP_NUM_UDP_PCB 5
- 添加下列函数, 并在网络初始化的时候调用
mdns_init()
函数
static void srv_txt(struct mdns_service *service, void *txt_userdata)
{
err_t res;
LWIP_UNUSED_ARG(txt_userdata);
res = mdns_resp_add_service_txtitem(service, "path=/", 6);
LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return);
}
static void mdns_report(struct netif* netif, u8_t result)
{
if (result == MDNS_PROBING_SUCCESSFUL) {
LWIP_PLATFORM_DIAG(("mdns status[netif %d]: MDNS_PROBING_SUCCESSFUL\n", netif->num));
} else if (result == MDNS_PROBING_SUCCESSFUL) {
LWIP_PLATFORM_DIAG(("mdns status[netif %d]: MDNS_PROBING_CONFLICT \n", netif->num));
} else {
LWIP_PLATFORM_DIAG(("mdns status[netif %d]: %d \n", netif->num, result));
}
}
void mdns_init(void)
{
mdns_resp_register_name_result_cb(mdns_report);
mdns_resp_init();
/* 添加 mDNS 主机, 在支持 mDNS 的电脑上, 可以直接 ping lwip.local 得到 IP 地址 */
mdns_resp_add_netif(&gnetif, "lwip", 3600);
/* 在 mDNS 主机上注册服务, 表示可以通过访问 lwip.local:80 端口访问开发板上的 web 服务器 */
mdns_resp_add_service(&gnetif, "myweb", "_http", DNSSD_PROTO_TCP, 80, 3600, srv_txt, NULL);
}
- 手动在 IP 会发生变化的地方调用
mdns_resp_announcer()
函数,在每次网络接口端口断开重连的时候调用mdns_resp_restart()
函数。或者,在lwipopts.h
中添加
#define LWIP_NETIF_EXT_STATUS_CALLBACK 1
#define MDNS_RESP_USENETIF_EXTCALLBACK 1
mDNS 会在网络接口断开重连或者 IP 发生变化的时候,自动调用 mdns_resp_restart()
函数和 mdns_resp_announce()
函数。
3 测试
- ping lwip.local
- 在游览器中访问 lwip.local