netif->name与netdev的网卡名称的问题
芯片: STM32F407IGT6
RT-Thread版本: 4.0.3
lwip版本: 2.0.2(RT-Thread自带)
工具链: RT-Thread Studio 2.2.6 202211231640
- 问题描述:
我在我的板子上有两个网口,一个使用STM32F407默认的网卡+DM9161的PHY芯片,使用RT-Thread提供的物理层驱动注册网卡;另一个使用FSMC+DM9000A的方案,自己写了个DM9000的物理层驱动,最后调用eth_device_init()函数完成初始化。
实际使用时,两个网卡分别插网线,都能实现dhcp自动分配ip地址,并完成通信。
目前的问题是,串口终端输入ifconfig命令时,并不能准确的打印出netdev网卡模块中的设备信息,描述如下:
- 我将两个网卡分别(上述顺序)在
eth_device_init()函数中注册为"e0"和"e1"两个名字 - 在ifconfig中只能显示出"e0"的正确ip等信息,"e1"网卡虽有该条目,但ip等信息均为0.0.0.0等空信息 效果如下
msh />ifconfig
network interface device: e0
MTU: 1500
MAC: 00 80 e1 15 41 51
FLAGS: UP LINK_UP INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP
ip address: 192.168.50.198
gw address: 192.168.50.1
net mask : 255.255.255.0
dns server #0: 192.168.50.1
dns server #1: 0.0.0.0
network interface device: e1 (Default)
MTU: 1500
MAC: 02 ab cd ef a3 3e
FLAGS: DOWN LINK_DOWN INTERNET_DOWN DHCP_ENABLE
ip address: 0.0.0.0
gw address: 0.0.0.0
net mask : 0.0.0.0
dns server #0: 0.0.0.0
dns server #1: 0.0.0.0
但此时网卡e1是可以被ping通的,(ip是从netif和dhcp调试打印中获知的)
- 经过对lwip和netdev的代码加入打印和调试,发现问题出在
lwip/src/core/netif.c中的void netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr)函数中的最后
#ifdef RT_USING_NETDEV
/* rt-thread sal network interface device set IP address operations */
rt_kprintf("netif->name:%s, find_res:%s\n", netif->name, netdev_get_by_name(netif->name)->name);
netdev_low_level_set_ipaddr(netdev_get_by_name(netif->name), &netif->ip_addr);
#endif /* RT_USING_NETDEV */
在这里打印时,网卡"e0"可以被找到,但网卡”e1“在调用netdev_get_by_name(netif->name)时返回空指针,阅读代码后发现,netif->name的定义是char[2],而netdev_get_by_name()函数中使用了rt_strncmp来查找网卡名称,netdev本身是使用const char*来存储网卡名称的,这两者存在name上的差异,导致可能由于netif的name没有\0结尾而导致查找失败。
- 可能的解决方案
- 网卡名称只用一个字符
- 在netif中用name查找netdev设备时,对name进行一下转化
- 或者还有我没考虑到的问题,请大佬指正
这里只展示了ip显示错误的原因,其他条目,包括FLAGS中的打印也是如此原因
将第二块网卡改名为长度为1的字符串"d"后,打印就正常了,如下:
msh />ifconfig
network interface device: e0 (Default)
MTU: 1500
MAC: 00 80 e1 15 41 51
FLAGS: UP LINK_DOWN INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP
ip address: 0.0.0.0
gw address: 0.0.0.0
net mask : 0.0.0.0
dns server #0: 192.168.50.1
dns server #1: 0.0.0.0
network interface device: d
MTU: 1500
MAC: 02 ab cd ef a3 3e
FLAGS: UP LINK_UP INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP
ip address: 192.168.50.186
gw address: 192.168.50.1
net mask : 255.255.255.0
dns server #0: 192.168.50.1
dns server #1: 0.0.0.0
备注:上述打印时网口1未插网线,但插了网线第二块网卡也是正常的
ncmp传入的长度参数是1还是2?如果是2,此时应该会忽略第2个字符之后的内容的吧?
可以单步调下ncmp里面。或改用strncmp对比下
ncmp传入的长度参数是1还是2?如果是2,此时应该会忽略第2个字符之后的内容的吧?
可以单步调下ncmp里面。或改用strncmp对比下
请教一下ncmp是在哪里看,我感觉问题应该就是这个查找netdev的时候没考虑到netif的name属性不是一个标准的字符串?
没考虑到netif的name属性不是一个标准的字符串?
所以这里用了ncmp,而不是直接strcmp。 代码在这 https://github.com/RT-Thread/rt-thread/blob/f5fe1a5d7b9117339ffce00035fd58a2c0ff3f3a/src/kservice.c#L563
多网口在多个项目中用过,所以你这里我感觉是第2个网卡的名称及配置信息与netdev中不同步,而非名称对比不成功,毕竟第1个成功了,且你第2个网卡虽然显示为0却实际有IP还能ping通。
没考虑到netif的name属性不是一个标准的字符串?
所以这里用了ncmp,而不是直接strcmp。 代码在这
https://github.com/RT-Thread/rt-thread/blob/f5fe1a5d7b9117339ffce00035fd58a2c0ff3f3a/src/kservice.c#L563
多网口在多个项目中用过,所以你这里我感觉是第2个网卡的名称及配置信息与netdev中不同步,而非名称对比不成功,毕竟第1个成功了,且你第2个网卡虽然显示为0却实际有IP还能ping通。
我用e1时,用netif->name查询netdev会失败,此时netif->name可以被正确printf出来是e1。用常量字符串"e1"查询netdev却可以查询成功
ncmp传入的长度参数是1还是2?如果是2,此时应该会忽略第2个字符之后的内容的吧?
可以单步调下ncmp里面。或改用strncmp对比下
ncmp传入的貌似是netdev中定义的一个最大名字长度的宏
没考虑到netif的name属性不是一个标准的字符串?
所以这里用了ncmp,而不是直接strcmp。 代码在这 https://github.com/RT-Thread/rt-thread/blob/f5fe1a5d7b9117339ffce00035fd58a2c0ff3f3a/src/kservice.c#L563
多网口在多个项目中用过,所以你这里我感觉是第2个网卡的名称及配置信息与netdev中不同步,而非名称对比不成功,毕竟第1个成功了,且你第2个网卡虽然显示为0却实际有IP还能ping通。
我用e1时,用netif->name查询netdev会失败,此时netif->name可以被正确printf出来是e1。用常量字符串"e1"查询netdev却可以查询成功
我曾经试过把第一块网卡直接不初始化,系统中只有一块网卡,第二块网卡一样的初始化流程,命名为e1,最后ifconfig出来是正确的
/> > 没考虑到netif的name属性不是一个标准的字符串?
所以这里用了ncmp,而不是直接strcmp。 代码在这
https://github.com/RT-Thread/rt-thread/blob/f5fe1a5d7b9117339ffce00035fd58a2c0ff3f3a/src/kservice.c#L563
多网口在多个项目中用过,所以你这里我感觉是第2个网卡的名称及配置信息与netdev中不同步,而非名称对比不成功,毕竟第1个成功了,且你第2个网卡虽然显示为0却实际有IP还能ping通。
单步调试进入netdev_get_by_name中发现,传入的netif->name变成了如下图:
传入参数的地址是没有错的,但是传入参数后貌似出现了问题
传入前,netif->name查看如下:
作为对比,传入常量字符串"e1"进行查询时,进入netdev_get_by_name中的name如下:
ncmp传入的长度参数是1还是2?如果是2,此时应该会忽略第2个字符之后的内容的吧?
可以单步调下ncmp里面。或改用strncmp对比下
所以我觉得对于netif中要操作netdev的地方,查找网卡是不是单独写一个用netif->name查找netdev的函数,比netdev的那个按名称查找函数的通用方法要更合适,这个地方估计就是因为没用终止符导致查找错误的,再加上第二块网卡会把netif->name后一个netif->num从0变成1,如图:
所以导致了字符串识别失败了 @aozima
/我测试了一下,实际再netif.c中加入如下代码就一切正常了
static struct netdev* netif_get_netdev_by_netifname(const char* netifname)
{
char temp[3] = {0};
rt_strncpy(temp, netifname, 2);
return netdev_get_by_name(temp);
}
#define netdev_get_by_name netif_get_netdev_by_netifname
输出如下:
msh />ifconfig
network interface device: e0
MTU: 1500
MAC: 00 80 e1 15 41 51
FLAGS: UP LINK_DOWN INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP
ip address: 192.168.50.198
gw address: 192.168.50.1
net mask : 255.255.255.0
dns server #0: 192.168.50.1
dns server #1: 0.0.0.0
network interface device: e1 (Default)
MTU: 1500
MAC: 02 ab cd ef a3 3e
FLAGS: UP LINK_UP INTERNET_UP DHCP_ENABLE
ip address: 192.168.50.186
gw address: 192.168.50.1
net mask : 255.255.255.0
dns server #0: 0.0.0.0
dns server #1: 0.0.0.0
@aozima 您觉得这能解释我所说的问题吗,以及这属于一个bug吗还是这是我的板子或者开发环境特有的原因导致的。这个如果是一个bug可以提一个pr吗?
将第二块网卡改名为长度为1的字符串"d"后,打印就正常了,如下:
msh />ifconfig network interface device: e0 (Default) MTU: 1500 MAC: 00 80 e1 15 41 51 FLAGS: UP LINK_DOWN INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP ip address: 0.0.0.0 gw address: 0.0.0.0 net mask : 0.0.0.0 dns server #0: 192.168.50.1 dns server #1: 0.0.0.0 network interface device: d MTU: 1500 MAC: 02 ab cd ef a3 3e FLAGS: UP LINK_UP INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP ip address: 192.168.50.186 gw address: 192.168.50.1 net mask : 255.255.255.0 dns server #0: 192.168.50.1 dns server #1: 0.0.0.0备注:上述打印时网口1未插网线,但插了网线第二块网卡也是正常的
这个感觉是存在问题的,欢迎PR (可能需要注意下,需要考虑到多种情况)
将第二块网卡改名为长度为1的字符串"d"后,打印就正常了,如下:
msh />ifconfig network interface device: e0 (Default) MTU: 1500 MAC: 00 80 e1 15 41 51 FLAGS: UP LINK_DOWN INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP ip address: 0.0.0.0 gw address: 0.0.0.0 net mask : 0.0.0.0 dns server #0: 192.168.50.1 dns server #1: 0.0.0.0 network interface device: d MTU: 1500 MAC: 02 ab cd ef a3 3e FLAGS: UP LINK_UP INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP ip address: 192.168.50.186 gw address: 192.168.50.1 net mask : 255.255.255.0 dns server #0: 192.168.50.1 dns server #1: 0.0.0.0备注:上述打印时网口1未插网线,但插了网线第二块网卡也是正常的
这个感觉是存在问题的,欢迎PR (可能需要注意下,需要考虑到多种情况)
您好,请问PR的目标分支选择哪一个分支;lwip在master分支下有多个版本,是否多个版本均要进行修复?
将第二块网卡改名为长度为1的字符串"d"后,打印就正常了,如下:
msh />ifconfig network interface device: e0 (Default) MTU: 1500 MAC: 00 80 e1 15 41 51 FLAGS: UP LINK_DOWN INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP ip address: 0.0.0.0 gw address: 0.0.0.0 net mask : 0.0.0.0 dns server #0: 192.168.50.1 dns server #1: 0.0.0.0 network interface device: d MTU: 1500 MAC: 02 ab cd ef a3 3e FLAGS: UP LINK_UP INTERNET_DOWN DHCP_ENABLE ETHARP BROADCAST IGMP ip address: 192.168.50.186 gw address: 192.168.50.1 net mask : 255.255.255.0 dns server #0: 192.168.50.1 dns server #1: 0.0.0.0备注:上述打印时网口1未插网线,但插了网线第二块网卡也是正常的
这个感觉是存在问题的,欢迎PR (可能需要注意下,需要考虑到多种情况)
已提交一个PR,PR