Tcp_bind() fails after object delete/re-create RP2040 Philhower Core #2822
Replies: 1 comment 3 replies
-
Can you pare down things to just a simple sketch that doesn't have its own HTTP server implementation and other things going on? Just start the Ethernet device, start the WiFiServer, wait for that button (or a character on the Serial port), disable it, wait for one more event, then start a new WiFiServer? I'm doubt that LeaMDNS will work properly when interfaces are added after the initial startup, off the bat. It's not getting notifications that interfaces are added so unless you manually restart everything it'll not be listening on the new device. AIUI, the way LWIP works I think a bind to The |
Beta Was this translation helpful? Give feedback.
-
I am using the Philhower RP2040 core, version 4.4.3, and a WIZNet W5500 Ethernet chip. Rather than creating a global reference to Wiznet5500lwIP, I am using a pointer that I allocate and free as the system starts and stops. (In case you are wondering why, it's because I also plan to send commands to the WIZNet W5500 Ethernet chip to turn it off/put it in low power mode and then back on). I have run into a situation where tcp_bind() fails and I can't properly control the cleanup of the internal data structures that cause the problem.
Attached is sample code that should demonstrate the issue. I am using an HTTP server based on HTTP by Giuseppe Masino. I have included an earlier version of that library because I couldn't get the most recent (7 years old) to compile. So, don't install the HTTP library into Arduino IDE, just use the included code.
MAC address and IP settings are near the beginning of the .ino file - adjust for your network. I hard coded the IP address settings because the network connection starts faster.
To run the example code you'll need a Raspberry Pi Pico, a WIZnet W5500 board, and a pushbutton. The WIZnet is connected to CS 17 and SPI0. The button can be connected to any available pin - I used pin 28. To debug, I use a PicoProbe.
The project setup is mostly defaults. Optimize is turned off to allow set of breakpoint at tcp_bind() result:
· Board: Raspberry Pi Pico
· Debug Level: "None"
· Debug Port: "Disabled"
· C++ Exceptions: "Disabled"
· Flash Size: "2MB (no FS)"
· CPU Speed: "133 MHz"
· IP/Bluetooth Stack: "IPv4 Only"
· Optimize: Disabled (-O0)
· Profiling: "Disabled"
· RTTI: "Disabled"
· Stack Protector: "Disabled"
· Upload Method: "Picoprobe/Debugprobe (CMSIS-DAP)"
· USB Stack: "Pico SDK"
After the code is built and running, press the button to start the Ethernet chip and servers. Notice that ping of DemoOfFailedTCPBind.local works and a browse to http://demooffailedtcpbind.local/ returns the demo web page.
If the button is pressed again, the servers are stopped and the Ethernet object is closed and deleted. Now ping and the demo web page are no longer available.
Here is the problem: If the button is pressed again, which starts Ethernet and the webserver again, the tcp_bind() that is called by the webserver begin() will fail. To see this, set a breakpoint in arduino15/packages/rp2040/hardware/rp2040/4.4.3/libraries/WiFi/src/WiFiServer.cpp, line 68.
Note these observations: tcp_bind() will always succeed if (a) I never refresh the web page http://demooffailedtcpbind.local/, (b) I restart the debugger, or (c) if I wait EXACTLY 2 minutes or more after the web client closes.
Can anyone help me solve this issue? Am I using the client code correctly? Is there a re-init function for the W5500lwIP code?
I also don't see how the translation layer lwip_wrap.cpp in the Philhower core is built - the functions with names like __real_lwip_init() and __real_tcp_bind(). I also cannot debug it. I did try using PlatformIO but those functions are just assembly language code.
Any feedback would be appreciated.
DemonstrateFailedTCPbindTelnet.ino.zip
Beta Was this translation helpful? Give feedback.
All reactions