我使用 Raspberry Pi Pico,其 ENC28J60 PCB 连接到其 SPI 之一。我使用2023年11月29日下载的pico-sdK,并使用当天从https://git.sr.ht/~krystianch/pico-enc28j60下载的pico-enc28j60。由于 lwIP 从 Pico Extras 移至 Pico SDK,我必须修改 enc28j60 项目的 CMakeLists.txt。
初始化函数如下所示:
static bool ethernet_init()
{
err_t err;
lwip_init();
queue_init( &R.rx_queue, sizeof(struct pbuf *), ENC28J60_RX_QUEUE_SIZE );
critical_section_init( &R.spi_cs );
// initialize modbus clients
for( int i=0; i<MODBUS_CLIENTS_MAX; i++ )
{
R.modbus_clients[i].tcp = 0;
R.modbus_clients[i].state = ST_UNUSED;
R.modbus_clients[i].seq_nr = (i << 12) | ((i << 8) ^ 0x0F00);
}
R.enc28j60.spi = spi1;
R.enc28j60.cs_pin = SPI1_CSn_PIN;
R.enc28j60.mac_address[0] = R.cfg.mac_addr[0];
R.enc28j60.mac_address[1] = R.cfg.mac_addr[1];
R.enc28j60.mac_address[2] = R.cfg.mac_addr[2];
R.enc28j60.mac_address[3] = R.cfg.mac_addr[3];
R.enc28j60.mac_address[4] = R.cfg.mac_addr[4];
R.enc28j60.mac_address[5] = R.cfg.mac_addr[5];
R.enc28j60.next_packet = 0;
R.enc28j60.critical_section = &R.spi_cs;
R.netif.name[0] = 'e';
R.netif.name[1] = 'n';
gpio_set_function( SPI1_SCK_PIN, GPIO_FUNC_SPI );
gpio_set_function( SPI1_MOSI_PIN, GPIO_FUNC_SPI );
gpio_set_function( SPI1_MISO_PIN, GPIO_FUNC_SPI );
gpio_init( SPI1_CSn_PIN );
gpio_put( SPI1_CSn_PIN, true );
gpio_set_dir( SPI1_CSn_PIN, true );
gpio_init( ETH_INT_PIN );
gpio_init( ETH_RST_PIN );
// reset the chip
gpio_put( ETH_RST_PIN, false );
gpio_set_dir( ETH_RST_PIN, true );
sleep_ms( 1 );
gpio_put( ETH_RST_PIN, true );
spi_init( R.enc28j60.spi, SPI1_SPEED );
netif_add( &R.netif, &R.cfg.ip_addr, &R.cfg.netmask, &R.cfg.gateway,
&R.enc28j60, ethernetif_init, netif_input );
netif_set_up( &R.netif );
netif_set_link_up( &R.netif ); // +++ should check the enc if the link is up
gpio_set_irq_enabled_with_callback( ETH_INT_PIN, GPIO_IRQ_EDGE_FALL,
true, eth_irq );
enc28j60_interrupts( &R.enc28j60,
ENC28J60_PKTIE | ENC28J60_TXERIE | ENC28J60_RXERIE );
R.tcp_modbus = tcp_new_ip_type( IPADDR_TYPE_V4 );
err = tcp_bind( R.tcp_modbus, IP4_ADDR_ANY, TCP_PORT_MODBUS );
if( err != ERR_OK )
{
return false;
}
R.tcp_modbus = tcp_listen_with_backlog( R.tcp_modbus, BACKLOG_MODBUS );
if( !R.tcp_modbus )
{
return false;
}
tcp_accept( R.tcp_modbus, modbus_accept );
return true;
}
在本地网络上一切正常。我可以 ping 它,我可以连接到 TCP 端口并进行 modbus 查询,工作完美。
但是当在计算机和 Pico 之间放置路由器时,我遇到了问题。 Ping 仍然工作正常,但没有 TCP 连接。我可以看到 SYN 数据包发送至 Pico,但没有看到 SYN/ACK 返回。我在modbus_accept函数中放入了一个printf,看是否调用了,但是根本没有调用。
我相信 pico-enc28j60 工作正常,因为本地网络上没有问题,而且通过路由器进行 ping 操作也能正常工作。
我相信接口配置正确,因为 ping 路由良好。
所以我相信我的代码或lwIP一定有问题。我只是看不出出了什么问题。
有什么提示吗?
在对lwIP源代码进行挖掘和调试后,如果发现
netif_default
是NULL
。拨打netif_set_default
解决问题。
这封电子邮件中也推荐了同样的事情: https://lists.nongnu.org/archive/html/lwip-users/2012-03/msg00083.html