废话文学
笔记更新有点慢,最近又有新的项目了。
不过我尽量慢慢把自己以前写的日记都更新过来,这样以后就不用很多平台,还能帮助别人,少走弯路。如此甚好!
不过现在写的都是以前的存货,慢慢整理吧。
调试笔记大多数来自于项目,教程大多数来自于总结,可能受限于项目平台和应用场景,读者需要自己衡量,我尽量写的通用一些。有问题可以留言讨论交流哦。
废话不多说,上干货!!!
一、双网络调试
背景:
调试内容:
基于MPC#3号板卡(可以忽略,就是7020的芯片),基于lwip的网络调试,需要分别调试出,2#eth和1#eth单网络调试(2号和1号标号也可忽略,硬件设计上标记的),2号eth和1号eth双网络调调试,双网络分为同网段和不同网段。双网络的不同网段是基于单网络调试,相对简单。本次主要介绍双网络的同一网段调试。以适应产品中的不同需求。
测试工程:
server_client_0621.(这是基于vivado 2019创建的一个工程名字,可以忽略)
板卡型号:
#3
调试工程路径:
E:************\MPC.sdk\server_client_0621
修改模块:
基于调试工程路径下内容,server_client_0621为测试应用工程,server_client_0621_bsp为测试依赖的bsp,已调通。(这里就是介绍了一下我用的工程,不重要)
下边才是干货重点,但是前边也不能丢!!!
修改内容(可参考修改):
1. ip4.c:
路径:E:\03-Project\MPC_Ethernet_Debug-ok\MPC-3_Single_Server_Client-20240626-ok\MPC.sdk\server_client_0621_bsp\ps7_cortexa9_0\libsrc\lwip211_v1_0\src\lwip-2.1.1\src\core\ipv4\ip4.c
/**
* Finds the appropriate network interface for a given IP address. It
* searches the list of network interfaces linearly. A match is found
* if the masked IP address of the network interface equals the masked
* IP address given to the function.
*
* @param dest the destination IP address for which to find the route
* @return the netif on which to send to reach dest
*/
struct netif *
ip4_route2(const ip4_addr_t *src, const ip4_addr_t *dest)
{
#if !LWIP_SINGLE_NETIF
struct netif *netif;
LWIP_ASSERT_CORE_LOCKED();
#if LWIP_MULTICAST_TX_OPTIONS
/* Use administratively selected interface for multicast by default */
if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) {
return ip4_default_multicast_netif;
}
#endif /* LWIP_MULTICAST_TX_OPTIONS */
/* bug #54569: in case LWIP_SINGLE_NETIF=1 and LWIP_DEBUGF() disabled, the following loop is optimized away */
LWIP_UNUSED_ARG(src);
LWIP_UNUSED_ARG(dest);
/* iterate through netifs */
NETIF_FOREACH(netif) {
/* is the netif up, does it have a link and a valid address? */
if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
/* network mask matches? */
//if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) {
if (ip4_addr_cmp(src, netif_ip4_addr(netif))) {
/* return netif on which to forward IP packet */
return netif;
}
/* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */
if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) {
/* return netif on which to forward IP packet */
if(ip4_addr_cmp(src, netif_ip4_addr(netif))){
return netif;
}
}
}
}
#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
/* loopif is disabled, looopback traffic is passed through any netif */
if (ip4_addr_isloopback(dest)) {
/* don't check for link on loopback traffic */
if (netif_default != NULL && netif_is_up(netif_default)) {
return netif_default;
}
/* default netif is not up, just use any netif for loopback traffic */
NETIF_FOREACH(netif) {
if (netif_is_up(netif)) {
return netif;
}
}
return NULL;
}
#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
#ifdef LWIP_HOOK_IP4_ROUTE_SRC
netif = LWIP_HOOK_IP4_ROUTE_SRC(NULL, dest);
if (netif != NULL) {
return netif;
}
#elif defined(LWIP_HOOK_IP4_ROUTE)
netif = LWIP_HOOK_IP4_ROUTE(dest);
if (netif != NULL) {
return netif;
}
#endif
#endif /* !LWIP_SINGLE_NETIF */
if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) ||
ip4_addr_isany_val(*netif_ip4_addr(netif_default)) || ip4_addr_isloopback(dest)) {
/* No matching netif found and default netif is not usable.
If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
IP_STATS_INC(ip.rterr);
MIB2_STATS_INC(mib2.ipoutnoroutes);
return NULL;
}
return netif_default;
}
主要修改:
- 保留ip4_route函数,复制此函数并修改函数名为ip4_route2,然后在ip4_route2修改其它位置
- ip4_route2(const ip4_addr_t *src, const ip4_addr_t *dest),修改ip4_route为ip4_route2,增加src参数
- //if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) 屏蔽此行改为if (ip4_addr_cmp(src, netif_ip4_addr(netif)))
- 增加函数声明:参照下图
struct netif *ip4_route2(const ip4_addr_t *src, const ip4_addr_t *dest);
#define ip4_route_src(src, dest) ip4_route2(src, dest)
附赠图片
- 确认修改以下搜索的地方:
- 在应用工程中加入以下接口:
二、注意事项:
- 工程源码中没有用到信号量和标志位,都是在单网络通道的基础上修改的
- 这样修改的原因是ip4_route函数中如果地址是本网卡的网段则认为是本网卡的数据,两个一网段被认为是本网卡的数据,所以同一时段,网络是通的,但是要么只能连客户端,要么只能连服务端。因此更改了判断逻辑,通过比较IP地址的方式来判断是哪个网卡发送的数据
- 注意网口差错会导致出现PHY failure,最有效的测试方式是先用单个网口测试,哪个网口用来作server端,哪个用来作client端,然后再开放两个网口,也避免了设置IP的过程