Skip to content

Commit 4545eb8

Browse files
projectgusdpgeorge
authored andcommitted
rp2: Disable the LWIP tick timer when not needed.
Prevents lightsleep being woken up every 64ms to service LWIP timers, when: 1. No netif is up, and 2. No TCP sockets are active The TCP socket check may not be strictly necessary, but without ticking the tcp timer they won't ever time out by themselves. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <[email protected]>
1 parent a1ee42c commit 4545eb8

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

ports/rp2/mpnetworkport.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#if MICROPY_PY_LWIP
3232

3333
#include "shared/runtime/softtimer.h"
34+
#include "lwip/netif.h"
3435
#include "lwip/timeouts.h"
3536

3637
// Poll lwIP every 64ms by default
@@ -39,6 +40,9 @@
3940
// Soft timer for running lwIP in the background.
4041
static soft_timer_entry_t mp_network_soft_timer;
4142

43+
// Callback for change of netif state
44+
NETIF_DECLARE_EXT_CALLBACK(netif_callback)
45+
4246
#if MICROPY_PY_NETWORK_CYW43
4347
#include "lib/cyw43-driver/src/cyw43.h"
4448
#include "lib/cyw43-driver/src/cyw43_stats.h"
@@ -137,17 +141,48 @@ static void mp_network_soft_timer_callback(soft_timer_entry_t *self) {
137141
#if MICROPY_PY_NETWORK_WIZNET5K
138142
wiznet5k_poll();
139143
#endif
144+
145+
// Only keep the timer running if any TCP sockets are active, or any netif is up
146+
struct netif *netif;
147+
extern void *tcp_active_pcbs;
148+
bool keep_running = (tcp_active_pcbs != NULL);
149+
if (!keep_running) {
150+
NETIF_FOREACH(netif) {
151+
if (netif->flags & NETIF_FLAG_LINK_UP) {
152+
keep_running = true;
153+
break;
154+
}
155+
}
156+
}
157+
158+
// Periodic timer will re-queue as soon as this handler exits,
159+
// one shot timer will not
160+
mp_network_soft_timer.mode = keep_running ? SOFT_TIMER_MODE_PERIODIC : SOFT_TIMER_MODE_ONE_SHOT;
140161
}
141162

163+
static void mp_network_netif_status_cb(struct netif *netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args);
164+
142165
void mod_network_lwip_init(void) {
143166
soft_timer_static_init(
144167
&mp_network_soft_timer,
145-
SOFT_TIMER_MODE_PERIODIC,
168+
SOFT_TIMER_MODE_ONE_SHOT,
146169
LWIP_TICK_RATE_MS,
147170
mp_network_soft_timer_callback
148171
);
149172

150-
soft_timer_reinsert(&mp_network_soft_timer, LWIP_TICK_RATE_MS);
173+
if (netif_callback.callback_fn == NULL) {
174+
netif_add_ext_callback(&netif_callback, mp_network_netif_status_cb);
175+
}
176+
}
177+
178+
static void mp_network_netif_status_cb(struct netif *netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args) {
179+
// Start the network soft timer any time an interface comes up, unless
180+
// it's already running
181+
if (reason == LWIP_NSC_LINK_CHANGED && args->link_changed.state
182+
&& mp_network_soft_timer.mode == SOFT_TIMER_MODE_ONE_SHOT) {
183+
mp_network_soft_timer.mode = SOFT_TIMER_MODE_PERIODIC;
184+
soft_timer_reinsert(&mp_network_soft_timer, LWIP_TICK_RATE_MS);
185+
}
151186
}
152187

153188
#endif // MICROPY_PY_LWIP

0 commit comments

Comments
 (0)