

11 changed files with 598 additions and 1 deletions
@ -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 |
@ -0,0 +1,3 @@
|
||||
MODULE := lwip_contrib
|
||||
|
||||
include $(RIOTBASE)/Makefile.base |
@ -0,0 +1,3 @@
|
||||
/** |
||||
* @defgroup lwip_contrib RIOT lwIP port |
||||
*/ |
@ -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); |
||||
} |
||||
|
||||
/** @} */ |
@ -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; |
||||
} |
||||
|
||||
/** @} */ |
@ -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 */ |
||||
/** @} */ |
@ -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 */ |
||||
/** @} */ |
@ -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_ */ |
||||
/** @} */ |
@ -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_ */ |
||||
/** @} */ |
Loading…
Reference in new issue