From e0d7740a2294ed6bc7c6237f1a12413e0c5a9ce1 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Tue, 27 Oct 2015 00:04:33 +0300 Subject: [PATCH] extmod/modlwip: slip: Use stream protocol and be port-independent. Based on the original patch by Galen Hazelwood: https://github.com/micropython/micropython/pull/1517 . --- extmod/modlwip.c | 34 +++++++++++++++++++++++++++++++--- py/builtin.h | 1 + py/mpstate.h | 5 +++++ py/objmodule.c | 3 +++ py/py.mk | 40 ++++++++++++++++++++++++++++++++++++++++ py/qstrdefs.h | 29 +++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 3 deletions(-) diff --git a/extmod/modlwip.c b/extmod/modlwip.c index 4d4ddd395d..f15766728d 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -31,6 +31,8 @@ #include "py/nlr.h" #include "py/objlist.h" #include "py/runtime.h" +#include "py/stream.h" +#include MICROPY_HAL_H #include "netutils.h" @@ -43,6 +45,7 @@ #ifdef MICROPY_PY_LWIP_SLIP #include "netif/slipif.h" +#include "lwip/sio.h" #endif // FIXME FIXME FIXME @@ -55,7 +58,6 @@ typedef struct _lwip_slip_obj_t { mp_obj_base_t base; - u8_t uart_id; struct netif lwip_netif; } lwip_slip_obj_t; @@ -72,13 +74,39 @@ STATIC void slip_lwip_poll(void *netif) { STATIC const mp_obj_type_t lwip_slip_type; +// lwIP SLIP callback functions +sio_fd_t sio_open(u8_t dvnum) { + // We support singleton SLIP interface, so just return any truish value. + return (sio_fd_t)1; +} + +void sio_send(u8_t c, sio_fd_t fd) { + mp_obj_type_t *type = mp_obj_get_type(MP_STATE_VM(lwip_slip_stream)); + int error; + type->stream_p->write(MP_STATE_VM(lwip_slip_stream), &c, 1, &error); +} + +u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len) { + mp_obj_type_t *type = mp_obj_get_type(MP_STATE_VM(lwip_slip_stream)); + int error; + mp_uint_t out_sz = type->stream_p->read(MP_STATE_VM(lwip_slip_stream), data, len, &error); + if (out_sz == MP_STREAM_ERROR) { + if (mp_is_nonblocking_error(error)) { + return 0; + } + // Can't do much else, can we? + return 0; + } + return out_sz; +} + // constructor lwip.slip(device=integer, iplocal=string, ipremote=string) STATIC mp_obj_t lwip_slip_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 3, 3, false); lwip_slip_obj.base.type = &lwip_slip_type; - lwip_slip_obj.uart_id = (u8_t)mp_obj_get_int(args[0]); + MP_STATE_VM(lwip_slip_stream) = args[0]; ip_addr_t iplocal, ipremote; if (!ipaddr_aton(mp_obj_str_get_str(args[1]), &iplocal)) { @@ -89,7 +117,7 @@ STATIC mp_obj_t lwip_slip_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t } struct netif *n = &(lwip_slip_obj.lwip_netif); - if (netif_add(n, &iplocal, IP_ADDR_BROADCAST, &ipremote, (void *)&lwip_slip_obj.uart_id, slipif_init, ip_input) == NULL) { + if (netif_add(n, &iplocal, IP_ADDR_BROADCAST, &ipremote, NULL, slipif_init, ip_input) == NULL) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "out of memory")); } netif_set_up(n); diff --git a/py/builtin.h b/py/builtin.h index 20ff1f765f..891b93e9a5 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -103,5 +103,6 @@ extern const mp_obj_module_t mp_module_uhashlib; extern const mp_obj_module_t mp_module_ubinascii; extern const mp_obj_module_t mp_module_ussl; extern const mp_obj_module_t mp_module_machine; +extern const mp_obj_module_t mp_module_lwip; #endif // __MICROPY_INCLUDED_PY_BUILTIN_H__ diff --git a/py/mpstate.h b/py/mpstate.h index dd185a7c25..9a8cc02013 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -127,6 +127,11 @@ typedef struct _mp_state_vm_t { // include any root pointers defined by a port MICROPY_PORT_ROOT_POINTERS + // root pointers for extmod + #if MICROPY_PY_LWIP_SLIP + mp_obj_t lwip_slip_stream; + #endif + // // END ROOT POINTER SECTION //////////////////////////////////////////////////////////// diff --git a/py/objmodule.c b/py/objmodule.c index 63cccde2b2..02a106d318 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -189,6 +189,9 @@ STATIC const mp_map_elem_t mp_builtin_module_table[] = { #if MICROPY_PY_USSL { MP_OBJ_NEW_QSTR(MP_QSTR_ussl), (mp_obj_t)&mp_module_ussl }, #endif +#if MICROPY_PY_LWIP + { MP_OBJ_NEW_QSTR(MP_QSTR_lwip), (mp_obj_t)&mp_module_lwip }, +#endif // extra builtin modules as defined by a port MICROPY_PORT_BUILTIN_MODULES diff --git a/py/py.mk b/py/py.mk index b3a991936d..00a8c59b6c 100644 --- a/py/py.mk +++ b/py/py.mk @@ -17,6 +17,46 @@ CFLAGS_MOD += -DMICROPY_PY_USSL=1 -I../lib/axtls/ssl -I../lib/axtls/crypto -I../ LDFLAGS_MOD += -L../lib/axtls/_stage -laxtls endif +#ifeq ($(MICROPY_PY_LWIP),1) +#CFLAGS_MOD += -DMICROPY_PY_LWIP=1 -I../lib/lwip/src/include -I../lib/lwip/src/include/ipv4 -I../extmod/lwip-include +#endif + +ifeq ($(MICROPY_PY_LWIP),1) +LWIP_DIR = lib/lwip/src +INC += -I../lib/lwip/src/include -I../lib/lwip/src/include/ipv4 -I../extmod/lwip-include +CFLAGS_MOD += -DMICROPY_PY_LWIP=1 +SRC_MOD += extmod/modlwip.c lib/netutils/netutils.c +SRC_MOD += $(addprefix $(LWIP_DIR)/,\ + core/def.c \ + core/dns.c \ + core/init.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/timers.c \ + core/udp.c \ + core/ipv4/autoip.c \ + core/ipv4/icmp.c \ + core/ipv4/igmp.c \ + core/ipv4/inet.c \ + core/ipv4/inet_chksum.c \ + core/ipv4/ip_addr.c \ + core/ipv4/ip.c \ + core/ipv4/ip_frag.c \ + ) +ifeq ($(MICROPY_PY_LWIP_SLIP),1) +CFLAGS_MOD += -DMICROPY_PY_LWIP_SLIP=1 +SRC_MOD += $(LWIP_DIR)/netif/slipif.c +endif +endif + # py object files PY_O_BASENAME = \ mpstate.o \ diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 161d231127..e91cfa89c1 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -614,3 +614,32 @@ Q(mem32) Q(ussl) Q(wrap_socket) #endif + +#if MICROPY_PY_LWIP +// for lwip module +Q(lwip) +Q(reset) +Q(callback) +Q(socket) +Q(AF_INET) +Q(AF_INET6) +Q(SOCK_STREAM) +Q(SOCK_DGRAM) +Q(SOCK_RAW) +// for lwip.socket +Q(close) +Q(bind) +Q(listen) +Q(accept) +Q(connect) +Q(send) +Q(recv) +Q(sendto) +Q(recvfrom) +Q(settimeout) +#if MICROPY_PY_LWIP_SLIP +// for lwip.slip +Q(slip) +Q(status) +#endif +#endif