From 932bec50ed1fce9ed06eae75c3970cc282043a70 Mon Sep 17 00:00:00 2001 From: Martine Lenders <mlenders@inf.fu-berlin.de> Date: Sun, 15 Nov 2015 20:58:39 +0100 Subject: [PATCH] lwip: add port for RIOT --- Makefile.dep | 5 + pkg/lwip/Makefile.include | 4 + pkg/lwip/contrib/Makefile | 3 + pkg/lwip/contrib/doc.txt | 3 + pkg/lwip/contrib/lwip.c | 32 +++++ pkg/lwip/contrib/sys_arch.c | 221 +++++++++++++++++++++++++++++++ pkg/lwip/include/arch/cc.h | 132 ++++++++++++++++++ pkg/lwip/include/arch/sys_arch.h | 91 +++++++++++++ pkg/lwip/include/lwip.h | 45 +++++++ pkg/lwip/include/lwipopts.h | 54 ++++++++ sys/auto_init/auto_init.c | 9 +- 11 files changed, 598 insertions(+), 1 deletion(-) create mode 100644 pkg/lwip/contrib/Makefile create mode 100644 pkg/lwip/contrib/doc.txt create mode 100644 pkg/lwip/contrib/lwip.c create mode 100644 pkg/lwip/contrib/sys_arch.c create mode 100644 pkg/lwip/include/arch/cc.h create mode 100644 pkg/lwip/include/arch/sys_arch.h create mode 100644 pkg/lwip/include/lwip.h create mode 100644 pkg/lwip/include/lwipopts.h diff --git a/Makefile.dep b/Makefile.dep index 7d78585519..9854b0ee87 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -356,9 +356,14 @@ endif ifneq (,$(filter lwip,$(USEMODULE))) USEPKG += lwip + USEMODULE += lwip_contrib USEMODULE += lwip_core endif +ifneq (,$(filter lwip_contrib,$(USEMODULE))) + USEMODULE += sema +endif + ifneq (,$(filter sema,$(USEMODULE))) USEMODULE += xtimer endif diff --git a/pkg/lwip/Makefile.include b/pkg/lwip/Makefile.include index e944a48255..de6a9f0069 100644 --- a/pkg/lwip/Makefile.include +++ b/pkg/lwip/Makefile.include @@ -1,2 +1,6 @@ INCLUDES += -I$(RIOTBASE)/pkg/lwip/include \ -I$(BINDIRBASE)/pkg/$(BOARD)/lwip/src/include + +ifneq (,$(filter lwip_contrib,$(USEMODULE))) + DIRS += $(RIOTBASE)/pkg/lwip/contrib +endif \ No newline at end of file diff --git a/pkg/lwip/contrib/Makefile b/pkg/lwip/contrib/Makefile new file mode 100644 index 0000000000..048d70b685 --- /dev/null +++ b/pkg/lwip/contrib/Makefile @@ -0,0 +1,3 @@ +MODULE := lwip_contrib + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/lwip/contrib/doc.txt b/pkg/lwip/contrib/doc.txt new file mode 100644 index 0000000000..d11a87565b --- /dev/null +++ b/pkg/lwip/contrib/doc.txt @@ -0,0 +1,3 @@ +/** + * @defgroup lwip_contrib RIOT lwIP port + */ diff --git a/pkg/lwip/contrib/lwip.c b/pkg/lwip/contrib/lwip.c new file mode 100644 index 0000000000..83ee33a1ba --- /dev/null +++ b/pkg/lwip/contrib/lwip.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file + * @author Martine Lenders <mlenders@inf.fu-berlin.de> + */ + +#include "lwip/tcpip.h" +#include "lwip/netif/netdev2.h" +#include "lwip/netif.h" + +#include "netdev2_tap.h" + +#include "lwip.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +void lwip_bootstrap(void) +{ + tcpip_init(NULL, NULL); +} + +/** @} */ diff --git a/pkg/lwip/contrib/sys_arch.c b/pkg/lwip/contrib/sys_arch.c new file mode 100644 index 0000000000..767e74d7a2 --- /dev/null +++ b/pkg/lwip/contrib/sys_arch.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file + */ + +#include <errno.h> +#include <stdbool.h> +#include <string.h> + +#include "arch/cc.h" +#include "arch/sys_arch.h" +#include "lwip/err.h" +#include "lwip/mem.h" +#include "lwip/opt.h" +#include "lwip/sys.h" + +#include "msg.h" +#include "sema.h" +#include "thread.h" +#include "xtimer.h" + +void sys_init(void) +{ + return; +} + +err_t sys_mutex_new(sys_mutex_t *mutex) +{ + mutex_init((mutex_t *)mutex); + return ERR_OK; +} + +void sys_mutex_lock(sys_mutex_t *mutex) +{ + mutex_lock((mutex_t *)mutex); +} + +void sys_mutex_unlock(sys_mutex_t *mutex) +{ + mutex_unlock((mutex_t *)mutex); +} + +void sys_mutex_free(sys_mutex_t *mutex) +{ + mem_free(mutex); +} + +err_t sys_sem_new(sys_sem_t *sem, u8_t count) +{ + if (sema_create((sema_t *)sem, (unsigned int)count) < 0) { + return ERR_VAL; + } + return ERR_OK; +} + +void sys_sem_free(sys_sem_t *sem) +{ + sema_destroy((sema_t *)sem); +} + +void sys_sem_signal(sys_sem_t *sem) +{ + LWIP_ASSERT("invalid semaphor", sys_sem_valid(sem)); + sema_post((sema_t *)sem); +} + +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t count) +{ + LWIP_ASSERT("invalid semaphor", sys_sem_valid(sem)); + if (count != 0) { + uint64_t stop, start; + start = xtimer_now64(); + int res = sema_wait_timed((sema_t *)sem, count * MS_IN_USEC); + stop = xtimer_now64() - start; + if (res == -ETIMEDOUT) { + return SYS_ARCH_TIMEOUT; + } + return (u32_t)(stop / MS_IN_USEC); + } + else { + sema_wait_timed((sema_t *)sem, 0); + return 0; + } +} + +err_t sys_mbox_new(sys_mbox_t *mbox, int size) +{ + (void)size; + mbox->waiting = 0; + cib_init(&mbox->cib, SYS_MBOX_SIZE); + mutex_init(&mbox->mutex); + if (sema_create(&mbox->not_empty, 0) < 0) { + return ERR_VAL; + } + if (sema_create(&mbox->not_full, 0) < 0) { + return ERR_VAL; + } + return ERR_OK; +} + +void sys_mbox_free(sys_mbox_t *mbox) +{ + sema_destroy(&mbox->not_empty); + sema_destroy(&mbox->not_full); +} + +void sys_mbox_post(sys_mbox_t *mbox, void *msg) +{ + int idx; + + LWIP_ASSERT("invalid mbox", sys_mbox_valid(mbox)); + mutex_lock(&mbox->mutex); + while ((idx = cib_put(&mbox->cib)) < 0) { + mbox->waiting++; + mutex_unlock(&mbox->mutex); + sema_wait_timed(&mbox->not_full, 0); + mutex_lock(&mbox->mutex); + mbox->waiting--; + } + mbox->msgs[idx] = msg; + if (cib_avail(&mbox->cib) == 1) { + sema_post(&mbox->not_empty); + } + mutex_unlock(&mbox->mutex); +} + +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ + int idx; + + LWIP_ASSERT("invalid mbox", sys_mbox_valid(mbox)); + mutex_lock(&mbox->mutex); + if ((idx = cib_put(&mbox->cib)) < 0) { + mutex_unlock(&mbox->mutex); + return ERR_MEM; + } + mbox->msgs[idx] = msg; + if (cib_avail(&mbox->cib) == 1) { + sema_post(&mbox->not_empty); + } + mutex_unlock(&mbox->mutex); + return ERR_OK; +} + +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) +{ + u32_t time_needed = 0; + unsigned int idx; + + LWIP_ASSERT("invalid mbox", sys_mbox_valid(mbox)); + mutex_lock(&mbox->mutex); + while (cib_avail(&mbox->cib) == 0) { + sys_sem_t *not_empty = (sys_sem_t *)(&mbox->not_empty); + mutex_unlock(&mbox->mutex); + if (timeout != 0) { + time_needed = sys_arch_sem_wait(not_empty, timeout); + if (time_needed == SYS_ARCH_TIMEOUT) { + return SYS_ARCH_TIMEOUT; + } + } + else { + sys_arch_sem_wait(not_empty, 0); + } + mutex_lock(&mbox->mutex); + } + idx = cib_get(&mbox->cib); + if (msg != NULL) { + *msg = mbox->msgs[idx]; + } + if (mbox->waiting) { + sema_post(&mbox->not_full); + } + mutex_unlock(&mbox->mutex); + return time_needed; +} + +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ + int idx; + + LWIP_ASSERT("invalid mbox", sys_mbox_valid(mbox)); + mutex_lock(&mbox->mutex); + if (cib_avail(&mbox->cib) == 0) { + mutex_unlock(&mbox->mutex); + return SYS_MBOX_EMPTY; + } + idx = cib_get(&mbox->cib); + if (msg != NULL) { + *msg = mbox->msgs[idx]; + } + mutex_unlock(&mbox->mutex); + return 0; +} + +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, + int stacksize, int prio) +{ + kernel_pid_t res; + char *stack = mem_malloc((size_t)stacksize); + + if (stack == NULL) { + return ERR_MEM; + } + if ((res = thread_create(stack, stacksize, prio, THREAD_CREATE_STACKTEST, + (thread_task_func_t)thread, arg, name)) <= KERNEL_PID_UNDEF) { + abort(); + } + sched_switch((char)prio); + return res; +} + +/** @} */ diff --git a/pkg/lwip/include/arch/cc.h b/pkg/lwip/include/arch/cc.h new file mode 100644 index 0000000000..663efe794a --- /dev/null +++ b/pkg/lwip/include/arch/cc.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup lwip_arch_cc Compiler and processor description + * @ingroup lwip + * @brief Describes compiler and processor to lwIP + * @{ + * + * @file + * @brief Compiler and processor definitions + * + * @author Martine Lenders <mlenders@inf.fu-berlin.de> + */ +#ifndef LWIP_ARCH_CC_H +#define LWIP_ARCH_CC_H + +#include <assert.h> +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> + +#include "irq.h" +#include "byteorder.h" +#include "mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BYTE_ORDER +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define BYTE_ORDER (LITTLE_ENDIAN) /**< platform's endianess */ +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define BYTE_ORDER (BIG_ENDIAN) /**< platform's endianess */ +#else +# error "Byte order is neither little nor big!" +#endif +#endif + +/** + * @brief Generic types for lwIP + * @{ + */ +typedef uint8_t u8_t; /**< unsigned 8-bit type */ +typedef int8_t s8_t; /**< signed 8-bit type */ +typedef uint16_t u16_t; /**< unsigned 16-bit type */ +typedef int16_t s16_t; /**< signed 16-bit type */ +typedef uint32_t u32_t; /**< unsigned 32-bit type */ +typedef int32_t s32_t; /**< signed 32-bit type */ + +typedef unsigned long mem_ptr_t; /**< A generic pointer type. It has to be an integer type + * (not void*, due to some pointer arithmetics). */ +/** + * @} + */ + +/** + * @brief (sn)printf formatters for the generic lwIP types + * @{ + */ +#define X8_F "02" PRIx8 +#define U16_F PRIu16 +#define S16_F PRId16 +#define X16_F PRIx16 +#define U32_F PRIu32 +#define S32_F PRId32 +#define X32_F PRIx32 + +#define SZT_F "lu" +/** + * @} + */ + +/** + * @brief Compiler hints for packing structures + * @{ + */ +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_STRUCT __attribute__((packed)) +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_END +/** + * @} + */ + +/** + * @todo check for best value + */ +#define LWIP_CHKSUM_ALGORITHM (3) + +#ifdef MODULE_LOG +# define LWIP_PLATFORM_DIAG(x) LOG_INFO x +# ifdef NDEBUG +# define LWIP_PLATFORM_ASSERT(x) +# else +# define LWIP_PLATFORM_ASSERT(x) \ + do { \ + LOG_ERROR("Assertion \"%s\" failed at %s:%d\n", x, __FILE__, __LINE__); \ + fflush(NULL); \ + abort(); \ + } while (0) +# endif +#else +# define LWIP_PLATFORM_DIAG(x) printf x +# ifdef NDEBUG +# define LWIP_PLATFORM_ASSERT(x) +# else +# define LWIP_PLATFORM_ASSERT(x) \ + do { \ + printf("Assertion \"%s\" failed at %s:%d\n", x, __FILE__, __LINE__); \ + fflush(NULL); \ + abort(); \ + } while (0) +# endif +#endif + +#define SYS_ARCH_PROTECT(x) mutex_lock(&x) +#define SYS_ARCH_UNPROTECT(x) mutex_unlock(&x) +#define SYS_ARCH_DECL_PROTECT(x) mutex_t x = MUTEX_INIT + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_ARCH_CC_H */ +/** @} */ diff --git a/pkg/lwip/include/arch/sys_arch.h b/pkg/lwip/include/arch/sys_arch.h new file mode 100644 index 0000000000..1b02458e2c --- /dev/null +++ b/pkg/lwip/include/arch/sys_arch.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup lwip_arch_sys_arch Architecture depentent definitions + * @ingroup lwip + * @brief Semaphores and mailboxes. + * @{ + * + * @file + * @brief Semaphore and mailboxes definitions. + * + * @author Martine Lenders <mlenders@inf.fu-berlin.de> + */ +#ifndef LWIP_ARCH_SYS_ARCH_H +#define LWIP_ARCH_SYS_ARCH_H + +#include <stdbool.h> +#include <stdint.h> + +#include "cib.h" +#include "kernel_types.h" +#include "mutex.h" +#include "random.h" +#include "sema.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LWIP_COMPAT_MUTEX (0) +#define SYS_SEM_NULL { 0, PRIORITY_QUEUE_INIT } +#define SYS_MBOX_SIZE (8) + +typedef struct { + cib_t cib; + void *msgs[SYS_MBOX_SIZE]; + mutex_t mutex; + sema_t not_empty; + sema_t not_full; + volatile int waiting; +} sys_mbox_t; + +typedef mutex_t sys_mutex_t; +typedef sema_t sys_sem_t; +typedef kernel_pid_t sys_thread_t; + +static inline bool sys_mutex_valid(sys_mutex_t *mutex) +{ + return mutex != NULL; +} + +static inline bool sys_sem_valid(sys_sem_t *sem) +{ + return sem != NULL; +} + +static inline bool sys_mbox_valid(sys_mbox_t *mbox) +{ + return (mbox != NULL) && (mbox->cib.mask != 0); +} + +static inline void sys_mbox_set_invalid(sys_mbox_t *mbox) +{ + if (mbox != NULL) { + mbox->cib.mask = 0; + } +} + +#define sys_mutex_valid(mutex) (sys_mutex_valid(mutex)) +#define sys_mutex_set_invalid(mutex) +#define sys_sem_valid(sem) (sys_sem_valid(sem)) +#define sys_sem_set_invalid(sem) +#define sys_mbox_valid(mbox) (sys_mbox_valid(mbox)) +#define sys_mbox_set_invalid(mbox) (sys_mbox_set_invalid(mbox)) + +#ifdef MODULE_RANDOM +#define LWIP_RAND() (random_uint32()) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_ARCH_SYS_ARCH_H */ +/** @} */ diff --git a/pkg/lwip/include/lwip.h b/pkg/lwip/include/lwip.h new file mode 100644 index 0000000000..999d07bca0 --- /dev/null +++ b/pkg/lwip/include/lwip.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup pkg_lwip lwIP + * @ingroup pkg + * @brief A lightweight TCP/IP stack + * @see http://savannah.nongnu.org/projects/lwip/ + * + * lwIP is a lightweight TCP/IP stack primarily for usage with Ethernet. + * It can be used with the the @ref conn. + * + * @{ + * + * @file + * @brief lwIP bootstrap definitions + * + * @author Martine Lenders <mlenders@inf.fu-berlin.de> + */ +#ifndef LWIP_H_ +#define LWIP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initializes lwIP stack. + * + * This initializes lwIP, i.e. all netdevs are added to as interfaces to the + * stack and the stack's thread is started. + */ +void lwip_bootstrap(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_H_ */ +/** @} */ diff --git a/pkg/lwip/include/lwipopts.h b/pkg/lwip/include/lwipopts.h new file mode 100644 index 0000000000..5d9d9dfac1 --- /dev/null +++ b/pkg/lwip/include/lwipopts.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup lwip_opts lwIP options + * @ingroup lwip + * @brief Options for the lwIP stack + * @{ + * + * @file + * @brief Option definitions + * + * @author Martine Lenders <mlenders@inf.fu-berlin.de> + */ +#ifndef LWIP_LWIPOPTS_H_ +#define LWIP_LWIPOPTS_H_ + +#include "thread.h" +#include "net/gnrc/netif/hdr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief lwIP configuration macros. + * @see lwIP documentation + * @{ + */ +#define LWIP_SOCKET (0) +#define MEMP_MEM_MALLOC (1) +#define NETIF_MAX_HWADDR_LEN (GNRC_NETIF_HDR_L2ADDR_MAX_LEN) + +#define TCPIP_THREAD_STACKSIZE (THREAD_STACKSIZE_DEFAULT) + +#define MEM_ALIGNMENT (4) +#ifndef MEM_SIZE +/* packet buffer size of GNRC + stack for TCP/IP */ +#define MEM_SIZE (TCPIP_THREAD_STACKSIZE + 6144) +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_LWIPOPTS_H_ */ +/** @} */ diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index 1d1f43d00a..ff98b4a8f9 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -76,6 +76,10 @@ #include "net/gnrc/udp.h" #endif +#ifdef MODULE_LWIP +#include "lwip.h" +#endif + #ifdef MODULE_FIB #include "net/fib.h" #endif @@ -150,7 +154,10 @@ void auto_init(void) extern void dht_auto_init(void); dht_auto_init(); #endif - +#ifdef MODULE_LWIP + DEBUG("Bootstraping lwIP.\n"); + lwip_bootstrap(); +#endif /* initialize network devices */ #ifdef MODULE_AUTO_INIT_GNRC_NETIF -- GitLab