|
31 | 31 | #if MICROPY_PY_LWIP
|
32 | 32 |
|
33 | 33 | #include "shared/runtime/softtimer.h"
|
| 34 | +#include "lwip/netif.h" |
34 | 35 | #include "lwip/timeouts.h"
|
35 | 36 |
|
36 | 37 | // Poll lwIP every 64ms by default
|
|
39 | 40 | // Soft timer for running lwIP in the background.
|
40 | 41 | static soft_timer_entry_t mp_network_soft_timer;
|
41 | 42 |
|
| 43 | +// Callback for change of netif state |
| 44 | +NETIF_DECLARE_EXT_CALLBACK(netif_callback) |
| 45 | + |
42 | 46 | #if MICROPY_PY_NETWORK_CYW43
|
43 | 47 | #include "lib/cyw43-driver/src/cyw43.h"
|
44 | 48 | #include "lib/cyw43-driver/src/cyw43_stats.h"
|
@@ -137,17 +141,48 @@ static void mp_network_soft_timer_callback(soft_timer_entry_t *self) {
|
137 | 141 | #if MICROPY_PY_NETWORK_WIZNET5K
|
138 | 142 | wiznet5k_poll();
|
139 | 143 | #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; |
140 | 161 | }
|
141 | 162 |
|
| 163 | +static void mp_network_netif_status_cb(struct netif *netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args); |
| 164 | + |
142 | 165 | void mod_network_lwip_init(void) {
|
143 | 166 | soft_timer_static_init(
|
144 | 167 | &mp_network_soft_timer,
|
145 |
| - SOFT_TIMER_MODE_PERIODIC, |
| 168 | + SOFT_TIMER_MODE_ONE_SHOT, |
146 | 169 | LWIP_TICK_RATE_MS,
|
147 | 170 | mp_network_soft_timer_callback
|
148 | 171 | );
|
149 | 172 |
|
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 | + } |
151 | 186 | }
|
152 | 187 |
|
153 | 188 | #endif // MICROPY_PY_LWIP
|
0 commit comments