Repository navigation
Conversation
NativeEthernet's static-IP begin() finishes with an unbounded spin on the link status. With TCP listen enabled at power-up, a static IP and no cable (or a dead port), boot hung in MinimalBoot, the extension host and the main image, and ATC hung the Swiftlink session the same way. The DHCP path was already bounded by its own timeout. Bring the stack up first through the DHCP begin() with a zero timeout, which starts the link poll and returns at once, wait up to 5 s for the link, and only then make the static begin(). No link reports the cable as not connected and returns failure, which the callers already handle by leaving TCP listen off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…k timeout After the bounded link wait gives up, the network stack is already running with no address. NativeEthernet's link-up callback starts a DHCP client on an interface still at 0.0.0.0, so a cable plugged in later left the board on a DHCP lease (or no address), and EthernetInit then reported it connected without applying the configured static IP. Set the static address, mask, gateway and DNS before the wait, through the same fnet calls the static begin() makes, so a later link-up has no reason to start DHCP. Calling fnet directly rather than through the Ethernet setters avoids linking those library wrappers into ITCM. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Switching from a static IP to DHCP without a reboot leaves the DHCP init waiting out its timeout with the cable connected, because NativeEthernet only starts its DHCP client from a link-up on an unaddressed interface. This predates the static link-wait change, which extends it to a static init that timed out. Fixing it needs a decision on restarting the fnet DHCP client and a board to check it on, so it is queued rather than fixed here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
b905829 to
990d770
Compare
SensoriumEmbedded
left a comment
There was a problem hiding this comment.
Thank you for the fix, Wes! I've known about this hang for a while and have a fix planned as part of vendoring NativeEthernet into the tree, as we did with USBHost_t36, so every Ethernet init goes through one copy of the library.
With the library in the tree I'll fix it there: bound the static begin()'s link wait with the existing DHCP timeout and have it return a status. That replaces EthBeginStatic() in both images, and the DHCP-after-static case you queued in Known-Issues can then be handled in link_callback too.
So I'm going to hold this one rather than merge it, and close it once the vendored fix lands. Your write-up of the link_callback behavior feeds straight into that.
Thank you!
|
Sounds good -- it was just bothering me and looked like a quick fix, but if a better fix is on the slate, I can wait. Feel free to close this whenever. |
|
Great, thank you. |
With a static IP configured and TCP listen enabled at power-up, a board with no Ethernet link (cable unplugged, dead switch port) hung at boot.
ATCin SwiftLink hung the same way.The cause is in Teensyduino's NativeEthernet: its static-IP
Ethernet.begin(mac, ip, dns, gw, mask)ends inwhile(!link_status){}, with no timeout. DHCP mode was already bounded byAT+DHCPTIME.EthBeginStatic(), added to both the main image (IOH_Swiftlink.c) and MinimalBoot/VMBoot (Min_ServiceTCP.ino), now:begin()with a zero timeout. That starts the link poll and returns at once.begin()makes. With an address already on the interface, the library's link-up callback doesn't start DHCP, so a cable plugged in after a timeout still comes up on the static IP rather than a lease.begin(), which returns at once.With no link, it reports "Ethernet cable is not connected." and returns failure. The callers already handle failure by leaving TCP listen off.
The link wait depends on the stack's poll running, as the DHCP
begin()already does. While Kernal Replace holds the poll inloop()(#85), the only callers that can run are SwiftLink AT commands, and the SwiftLink dispatch unmasks the PIT around them.The branch also queues a related problem in
Known-Issues.md. Switching from static to DHCP without a reboot leaves the DHCP init waiting out its timeout, because the library only starts its DHCP client on a link-up while the address is 0.0.0.0. This already happens onmainafter a successful static init; this change extends it to one that timed out.Host build only, not hardware tested.
Memory impact
From CI: base is
mainat ac24701, head is this PR at 990d770. Figures are in bytes. RAM1 variables are unchanged on every image, and the TR+ extension images are unchanged on every figure.TR+ (Fab 0.4)
TR (Fab 0.2/0.3)
The new functions are
FLASHMEM. On the plain TR's main image, the 64 bytes of RAM1 code come from an inlining shift elsewhere in the same translation unit. A symbol diff of the two ELFs showsLoadFile()(DriveDirLoad.ino, neverFLASHMEM) inlining one moreFile::close()call, so it grows 32 bytes, and an out-of-line copy ofMouseController::mouseDataClear()(20 bytes) dropping out. Padding absorbs the growth, and free for local variables is unchanged.LoadFile()is already on theFLASHMEMaudit list inKnown-Issues.md.🤖 Generated with Claude Code