Closed veecle-stefan closed 2 months ago
...As of now, both (lwIP_5500 and this lwIP_W6100) cannot run the libraries/WebServer/examples/AdvancedWebServer/AdvancedWebServer.ino due to default stack limits (crashes after few requests because the stack grows too deep...
This is kind of news to me because the default test I run is the AdvancedWebServer (but I normally just run that graph on F5-reload on a few PCs in the house for an hour or so, but if there's some other page/CGI being used to cause the crash it might have been missed). I have a nice W5100-EVB supplied by WizNet, but I do have some AX no-name PCBs that I wire up for the 5500 and ENC chips. Will give it a go. Maybe something got broken recently (or I never tested some special situation)...
I do know MDNS is kind of a bad boy because it does malloc
s from inside an IRQ so maybe that's where things bomb? Do you have a stack trace?
I just checked the pure AdvancedWebServer example again, and you're right: It doesn't crash.
But I found the culprit: In my example, I added #include <FreeRTOS.h>
as well. Nothing else - I don't even use any FreeRTOS functions.
This is the stack trace (after only 3 HTTP requests it crahes)
#3 0x100075c4 in xQueueTakeMutexRecursive (xMutex=0x20013618, xTicksToWait=4294967295) at /Users/stefan/.platformio/packages/framework-arduinopico/libraries/FreeRTOS/src/../lib/FreeRTOS-Kernel/queue.c:837
#4 0x1000671e in __freertos_recursive_mutex_take (mtx=<optimized out>) at /Users/stefan/.platformio/packages/framework-arduinopico/libraries/FreeRTOS/src/variantHooks.cpp:80
#5 0x100119f6 in __retarget_lock_acquire_recursive (lock=<optimized out>) at /Users/stefan/.platformio/packages/framework-arduinopico/cores/rp2040/lock.cpp:150
#6 0x100217c8 in __malloc_lock (ptr=ptr@entry=0x20013c8c) at /workdir/repo/newlib/newlib/libc/stdlib/mlock.c:44
#7 0x10021400 in _malloc_r (reent_ptr=0x20013c8c, bytes=bytes@entry=52) at /workdir/repo/newlib/newlib/libc/stdlib/mallocr.c:2362
#8 0x1002137e in malloc (nbytes=52) at /workdir/repo/newlib/newlib/libc/stdlib/malloc.c:164
#9 0x100126d2 in __wrap_malloc (size=52) at /Users/stefan/.platformio/packages/framework-arduinopico/cores/rp2040/malloc-lock.cpp:30
#10 0x10014666 in operator new (n=n@entry=52) at /home/earle/Arduino/hardware/pico/rp2040/pico-sdk/src/rp2_common/pico_cxx_options/new_delete.cpp:15
#11 0x1000519c in WiFiServer::_accept (this=0x200053dc <server+204>, apcb=0x2000eecc <memp_memory_TCP_PCB_base+656>, err=<optimized out>) at /Users/stefan/.platformio/packages/framework-arduinopico/libraries/WiFi/src/WiFiServer.cpp:197
#12 0x100051c2 in WiFiServer::_s_accept (arg=<optimized out>, newpcb=<optimized out>, err=<optimized out>) at /Users/stefan/.platformio/packages/framework-arduinopico/libraries/WiFi/src/WiFiServer.cpp:218
#13 0x1001be44 in tcp_process (pcb=0x2000eecc <memp_memory_TCP_PCB_base+656>) at /home/earle/Arduino/hardware/pico/rp2040/pico-sdk/lib/lwip/src/core/tcp_in.c:956
#14 tcp_input (p=p@entry=0x2000f2f4 <ram_heap+9>, inp=inp@entry=0x20004c08 <eth+28>) at /home/earle/Arduino/hardware/pico/rp2040/pico-sdk/lib/lwip/src/core/tcp_in.c:438
#15 0x1002023e in ip4_input (p=p@entry=0x2000f2f4 <ram_heap+9>, inp=inp@entry=0x20004c08 <eth+28>) at /home/earle/Arduino/hardware/pico/rp2040/pico-sdk/lib/lwip/src/core/ipv4/ip4.c:743
#16 0x1002064c in ethernet_input (p=0x2000f2f4 <ram_heap+9>, netif=0x20004c08 <eth+28>) at /home/earle/Arduino/hardware/pico/rp2040/pico-sdk/lib/lwip/src/netif/ethernet.c:186
#17 0x10003c26 in LwipIntfDev<Wiznet5500>::handlePackets (this=this@entry=0x20004bec <eth>) at /Users/stefan/.platformio/packages/framework-arduinopico/libraries/lwIP_Ethernet/src/LwipIntfDev.h:586
#18 0x10003c72 in LwipIntfDev<Wiznet5500>::_irq (param=0x20004bec <eth>) at /Users/stefan/.platformio/packages/framework-arduinopico/libraries/lwIP_Ethernet/src/LwipIntfDev.h:450
#19 0x10012902 in CBInfo::callback (this=this@entry=0x20041f54) at /Users/stefan/.platformio/packages/framework-arduinopico/cores/rp2040/wiring_private.cpp:60
#20 0x100129f2 in _gpioInterruptDispatcher (gpio=<optimized out>, events=<optimized out>) at /Users/stefan/.platformio/packages/framework-arduinopico/cores/rp2040/wiring_private.cpp:85
#21 0x1001331c in gpio_default_irq_handler () at /home/earle/Arduino/hardware/pico/rp2040/pico-sdk/src/rp2_common/hardware_gpio/gpio.c:165
#22 0x20000f70 in irq_handler_chain_slots ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
The slightly modified example (to make it work with W5500):
#include <Arduino.h>
#include <W5500lwIP.h>
#include <EthernetCompat.h>
#include <SPI.h>
#include <WebServer.h>
#include <LEAmDNS.h>
#include <StreamString.h>
#include <FreeRTOS.h>
//
ArduinoEthernet<Wiznet5500> eth(17, SPI, 21);
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01};
IPAddress ip(10, 42, 42, 6);
WebServer server(80);
const int led = LED_BUILTIN;
void handleRoot()
{
static int cnt = 0;
digitalWrite(led, 1);
int sec = millis() / 1000;
int hr = sec / 3600;
int min = (sec / 60) % 60;
sec = sec % 60;
StreamString temp;
temp.reserve(500); // Preallocate a large chunk to avoid memory fragmentation
temp.printf("<html>\
<head>\
<meta http-equiv='refresh' content='5'/>\
<title>" BOARD_NAME " Demo</title>\
<style>\
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
</head>\
<body>\
<h1>Hello from the " BOARD_NAME "!</h1>\
<p>Uptime: %02d:%02d:%02d</p>\
<p>Free Memory: %d</p>\
<p>Page Count: %d</p>\
<img src=\"/test.svg\" />\
</body>\
</html>",
hr, min, sec, rp2040.getFreeHeap(), ++cnt);
server.send(200, "text/html", temp);
digitalWrite(led, 0);
}
void handleNotFound()
{
digitalWrite(led, 1);
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++)
{
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
void drawGraph()
{
String out;
out.reserve(2600);
char temp[70];
out += "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"400\" height=\"150\">\n";
out += "<rect width=\"400\" height=\"150\" fill=\"rgb(250, 230, 210)\" stroke-width=\"1\" stroke=\"rgb(0, 0, 0)\" />\n";
out += "<g stroke=\"black\">\n";
int y = rand() % 130;
for (int x = 10; x < 390; x += 10)
{
int y2 = rand() % 130;
sprintf(temp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" stroke-width=\"1\" />\n", x, 140 - y, x + 10, 140 - y2);
out += temp;
y = y2;
}
out += "</g>\n</svg>\n";
server.send(200, "image/svg+xml", out);
}
void setup(void)
{
pinMode(led, OUTPUT);
digitalWrite(led, 0);
Serial.begin(115200);
// Set up SPI pinout to match your HW
SPI.setRX(16);
SPI.setCS(17);
SPI.setSCK(18);
SPI.setTX(19);
// Start the Ethernet port
if (!eth.begin(mac, ip))
{
Serial.println("No wired Ethernet hardware detected. Check pinouts, wiring.");
while (1)
{
delay(1000);
}
}
// Wait for connection
while (eth.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.print("IP address: ");
Serial.println(eth.localIP());
if (MDNS.begin("picow"))
{
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on("/test.svg", drawGraph);
server.on("/inline", []()
{ server.send(200, "text/plain", "this works as well"); });
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop(void)
{
server.handleClient();
MDNS.update();
}
In my using PIO with platformio.ini like so:
[env]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git
board = pico
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
framework = arduino
Yeah, that's calling malloc
from within an IRQ context. Not stack related, just FreeRTOS complaining that a mutex is being grabbed from an IRQ-level. So known restriction and not related to your PR.
This is a first WIP for supporting the Wiznet W6100 Ethernet chip in the
lwIP_Ethernet
.lwip_5500
driverPreliminary Testing & Known Bugs
W5550
toW6100
in the generic of the type for the constructor:ArduinoEthernet<Wiznet6100> Ethernet(17, SPI, 21)
Known Bugs