summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/Makefile42
-rw-r--r--ports/stm32/lwip_inc/arch/cc.h8
-rw-r--r--ports/stm32/lwip_inc/arch/sys_arch.h1
-rw-r--r--ports/stm32/lwip_inc/lwipopts.h61
-rw-r--r--ports/stm32/main.c10
-rw-r--r--ports/stm32/modnetwork.c33
-rw-r--r--ports/stm32/modnetwork.h14
-rw-r--r--ports/stm32/modusocket.c4
-rw-r--r--ports/stm32/mpconfigport.h13
9 files changed, 183 insertions, 3 deletions
diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile
index 99e2995ff..cbfd8baa1 100644
--- a/ports/stm32/Makefile
+++ b/ports/stm32/Makefile
@@ -184,6 +184,7 @@ SRC_LIBM = $(addprefix lib/libm/,\
endif
EXTMOD_SRC_C = $(addprefix extmod/,\
+ modlwip.c \
modonewire.c \
)
@@ -337,6 +338,47 @@ SRC_MOD += $(addprefix $(CC3000_DIR)/src/,\
)
endif
+LWIP_DIR = lib/lwip/src
+INC += -I$(TOP)/$(LWIP_DIR)/include -Ilwip_inc
+$(BUILD)/$(LWIP_DIR)/core/ipv4/dhcp.o: CFLAGS += -Wno-address
+SRC_MOD += $(addprefix $(LWIP_DIR)/,\
+ core/def.c \
+ core/dns.c \
+ core/inet_chksum.c \
+ core/init.c \
+ core/ip.c \
+ core/mem.c \
+ core/memp.c \
+ core/netif.c \
+ core/pbuf.c \
+ core/raw.c \
+ core/stats.c \
+ core/sys.c \
+ core/tcp.c \
+ core/tcp_in.c \
+ core/tcp_out.c \
+ core/timeouts.c \
+ core/udp.c \
+ core/ipv4/autoip.c \
+ core/ipv4/dhcp.c \
+ core/ipv4/etharp.c \
+ core/ipv4/icmp.c \
+ core/ipv4/igmp.c \
+ core/ipv4/ip4_addr.c \
+ core/ipv4/ip4.c \
+ core/ipv4/ip4_frag.c \
+ core/ipv6/dhcp6.c \
+ core/ipv6/ethip6.c \
+ core/ipv6/icmp6.c \
+ core/ipv6/inet6.c \
+ core/ipv6/ip6_addr.c \
+ core/ipv6/ip6.c \
+ core/ipv6/ip6_frag.c \
+ core/ipv6/mld6.c \
+ core/ipv6/nd6.c \
+ netif/ethernet.c \
+ )
+
OBJ =
OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o))
diff --git a/ports/stm32/lwip_inc/arch/cc.h b/ports/stm32/lwip_inc/arch/cc.h
new file mode 100644
index 000000000..635b1c805
--- /dev/null
+++ b/ports/stm32/lwip_inc/arch/cc.h
@@ -0,0 +1,8 @@
+#ifndef MICROPY_INCLUDED_STM32_LWIP_ARCH_CC_H
+#define MICROPY_INCLUDED_STM32_LWIP_ARCH_CC_H
+
+#include <assert.h>
+#define LWIP_PLATFORM_DIAG(x)
+#define LWIP_PLATFORM_ASSERT(x) { assert(1); }
+
+#endif // MICROPY_INCLUDED_STM32_LWIP_ARCH_CC_H
diff --git a/ports/stm32/lwip_inc/arch/sys_arch.h b/ports/stm32/lwip_inc/arch/sys_arch.h
new file mode 100644
index 000000000..8b1a39374
--- /dev/null
+++ b/ports/stm32/lwip_inc/arch/sys_arch.h
@@ -0,0 +1 @@
+// empty
diff --git a/ports/stm32/lwip_inc/lwipopts.h b/ports/stm32/lwip_inc/lwipopts.h
new file mode 100644
index 000000000..b8ab8a2ab
--- /dev/null
+++ b/ports/stm32/lwip_inc/lwipopts.h
@@ -0,0 +1,61 @@
+#ifndef MICROPY_INCLUDED_STM32_LWIP_LWIPOPTS_H
+#define MICROPY_INCLUDED_STM32_LWIP_LWIPOPTS_H
+
+#include <stdint.h>
+
+#define NO_SYS 1
+#define SYS_LIGHTWEIGHT_PROT 1
+#define MEM_ALIGNMENT 4
+
+#define LWIP_CHKSUM_ALGORITHM 3
+
+#define LWIP_ARP 1
+#define LWIP_ETHERNET 1
+#define LWIP_NETCONN 0
+#define LWIP_SOCKET 0
+#define LWIP_STATS 0
+#define LWIP_NETIF_HOSTNAME 1
+
+#define LWIP_IPV6 0
+#define LWIP_DHCP 1
+#define LWIP_DHCP_CHECK_LINK_UP 1
+#define LWIP_DNS 1
+#define LWIP_IGMP 1
+
+#define SO_REUSE 1
+
+extern uint32_t rng_get(void);
+#define LWIP_RAND() rng_get()
+
+// default
+// lwip takes 15800 bytes; TCP d/l: 380k/s local, 7.2k/s remote
+// TCP u/l is very slow
+
+#if 0
+// lwip takes 19159 bytes; TCP d/l and u/l are around 320k/s on local network
+#define MEM_SIZE (5000)
+#define TCP_WND (4 * TCP_MSS)
+#define TCP_SND_BUF (4 * TCP_MSS)
+#endif
+
+#if 1
+// lwip takes 26700 bytes; TCP dl/ul are around 750/600 k/s on local network
+#define MEM_SIZE (8000)
+#define TCP_MSS (800)
+#define TCP_WND (8 * TCP_MSS)
+#define TCP_SND_BUF (8 * TCP_MSS)
+#define MEMP_NUM_TCP_SEG (32)
+#endif
+
+#if 0
+// lwip takes 45600 bytes; TCP dl/ul are around 1200/1000 k/s on local network
+#define MEM_SIZE (16000)
+#define TCP_MSS (1460)
+#define TCP_WND (8 * TCP_MSS)
+#define TCP_SND_BUF (8 * TCP_MSS)
+#define MEMP_NUM_TCP_SEG (32)
+#endif
+
+typedef uint32_t sys_prot_t;
+
+#endif // MICROPY_INCLUDED_STM32_LWIP_LWIPOPTS_H
diff --git a/ports/stm32/main.c b/ports/stm32/main.c
index 460a19ccb..44f5b05c4 100644
--- a/ports/stm32/main.c
+++ b/ports/stm32/main.c
@@ -34,6 +34,7 @@
#include "lib/mp-readline/readline.h"
#include "lib/utils/pyexec.h"
#include "lib/oofatfs/ff.h"
+#include "lwip/init.h"
#include "extmod/vfs.h"
#include "extmod/vfs_fat.h"
@@ -512,6 +513,12 @@ void stm32_main(uint32_t reset_mode) {
sdcard_init();
#endif
storage_init();
+ #if MICROPY_PY_LWIP
+ // lwIP doesn't allow to reinitialise itself by subsequent calls to this function
+ // because the system timeout list (next_timeout) is only ever reset by BSS clearing.
+ // So for now we only init the lwIP stack once on power-up.
+ lwip_init();
+ #endif
soft_reset:
@@ -726,6 +733,9 @@ soft_reset_exit:
storage_flush();
printf("PYB: soft reboot\n");
+ #if MICROPY_PY_NETWORK
+ mod_network_deinit();
+ #endif
timer_deinit();
uart_deinit();
#if MICROPY_HW_ENABLE_CAN
diff --git a/ports/stm32/modnetwork.c b/ports/stm32/modnetwork.c
index 642174532..156c73572 100644
--- a/ports/stm32/modnetwork.c
+++ b/ports/stm32/modnetwork.c
@@ -30,10 +30,34 @@
#include "py/objlist.h"
#include "py/runtime.h"
+#include "py/mphal.h"
#include "modnetwork.h"
#if MICROPY_PY_NETWORK
+#if MICROPY_PY_LWIP
+
+#include "lwip/netif.h"
+#include "lwip/timeouts.h"
+
+u32_t sys_now(void) {
+ return mp_hal_ticks_ms();
+}
+
+void pyb_lwip_poll(void) {
+ // Poll all the NICs for incoming data
+ for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) {
+ if (netif->flags & NETIF_FLAG_LINK_UP) {
+ mod_network_nic_type_t *nic = netif->state;
+ nic->poll_callback(nic, netif);
+ }
+ }
+ // Run the lwIP internal updates
+ sys_check_timeouts();
+}
+
+#endif
+
/// \module network - network configuration
///
/// This module provides network drivers and routing configuration.
@@ -42,6 +66,15 @@ void mod_network_init(void) {
mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0);
}
+void mod_network_deinit(void) {
+ #if MICROPY_PY_LWIP
+ for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) {
+ netif_remove(netif);
+ }
+ // TODO there may be some timeouts that are still pending...
+ #endif
+}
+
void mod_network_register_nic(mp_obj_t nic) {
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) {
diff --git a/ports/stm32/modnetwork.h b/ports/stm32/modnetwork.h
index 6796b087a..af46a54a6 100644
--- a/ports/stm32/modnetwork.h
+++ b/ports/stm32/modnetwork.h
@@ -35,6 +35,17 @@
#define MOD_NETWORK_SOCK_DGRAM (2)
#define MOD_NETWORK_SOCK_RAW (3)
+#if MICROPY_PY_LWIP
+
+struct netif;
+
+typedef struct _mod_network_nic_type_t {
+ mp_obj_type_t base;
+ void (*poll_callback)(void *data, struct netif *netif);
+} mod_network_nic_type_t;
+
+#else
+
struct _mod_network_socket_obj_t;
typedef struct _mod_network_nic_type_t {
@@ -73,10 +84,13 @@ typedef struct _mod_network_socket_obj_t {
};
} mod_network_socket_obj_t;
+#endif
+
extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k;
extern const mod_network_nic_type_t mod_network_nic_type_cc3k;
void mod_network_init(void);
+void mod_network_deinit(void);
void mod_network_register_nic(mp_obj_t nic);
mp_obj_t mod_network_find_nic(const uint8_t *ip);
diff --git a/ports/stm32/modusocket.c b/ports/stm32/modusocket.c
index 0c663437e..715faa3c4 100644
--- a/ports/stm32/modusocket.c
+++ b/ports/stm32/modusocket.c
@@ -35,7 +35,7 @@
#include "lib/netutils/netutils.h"
#include "modnetwork.h"
-#if MICROPY_PY_USOCKET
+#if MICROPY_PY_USOCKET && !MICROPY_PY_LWIP
/******************************************************************************/
// socket class
@@ -465,4 +465,4 @@ const mp_obj_module_t mp_module_usocket = {
.globals = (mp_obj_dict_t*)&mp_module_usocket_globals,
};
-#endif // MICROPY_PY_USOCKET
+#endif // MICROPY_PY_USOCKET && !MICROPY_PY_LWIP
diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h
index 72744f04b..115006367 100644
--- a/ports/stm32/mpconfigport.h
+++ b/ports/stm32/mpconfigport.h
@@ -192,12 +192,21 @@ extern const struct _mp_obj_module_t mp_module_onewire;
#define STM_BUILTIN_MODULE
#endif
-#if MICROPY_PY_USOCKET
+#if MICROPY_PY_USOCKET && MICROPY_PY_LWIP
+// usocket implementation provided by lwIP
+#define SOCKET_BUILTIN_MODULE { MP_ROM_QSTR(MP_QSTR_usocket), MP_ROM_PTR(&mp_module_lwip) },
+#define SOCKET_BUILTIN_MODULE_WEAK_LINKS { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&mp_module_lwip) },
+#define SOCKET_POLL extern void pyb_lwip_poll(void); pyb_lwip_poll();
+#elif MICROPY_PY_USOCKET
+// usocket implementation provided by skeleton wrapper
#define SOCKET_BUILTIN_MODULE { MP_ROM_QSTR(MP_QSTR_usocket), MP_ROM_PTR(&mp_module_usocket) },
#define SOCKET_BUILTIN_MODULE_WEAK_LINKS { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&mp_module_usocket) },
+#define SOCKET_POLL
#else
+// no usocket module
#define SOCKET_BUILTIN_MODULE
#define SOCKET_BUILTIN_MODULE_WEAK_LINKS
+#define SOCKET_POLL
#endif
#if MICROPY_PY_NETWORK
@@ -313,6 +322,7 @@ static inline mp_uint_t disable_irq(void) {
do { \
extern void mp_handle_pending(void); \
mp_handle_pending(); \
+ SOCKET_POLL \
if (pyb_thread_enabled) { \
MP_THREAD_GIL_EXIT(); \
pyb_thread_yield(); \
@@ -328,6 +338,7 @@ static inline mp_uint_t disable_irq(void) {
do { \
extern void mp_handle_pending(void); \
mp_handle_pending(); \
+ SOCKET_POLL \
__WFI(); \
} while (0);