路由时TCP无法连接,Raspberry Pi Pico + lwIP + ENC28J60

问题描述 投票:0回答:1

我使用 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一定有问题。我只是看不出出了什么问题。

有什么提示吗?

tcp tcpserver raspberry-pi-pico lwip
1个回答
0
投票

在对lwIP源代码进行挖掘和调试后,如果发现

netif_default
NULL
。拨打
netif_set_default
解决问题。

这封电子邮件中也推荐了同样的事情: https://lists.nongnu.org/archive/html/lwip-users/2012-03/msg00083.html

© www.soinside.com 2019 - 2024. All rights reserved.