diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index 0a07b3b4..9cf6db58 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -9,7 +9,6 @@ set(include_dirs set(srcs "apps/dhcpserver/dhcpserver.c" - "apps/multi-threads/sockets_mt.c" "apps/ping/esp_ping.c" "apps/ping/ping.c" "apps/ping/ping_sock.c" @@ -136,10 +135,6 @@ if(CONFIG_ETH_ENABLED) list(APPEND srcs "port/esp32/netif/ethernetif.c") endif() -if(CONFIG_LWIP_SOCKET_MULTITHREAD) - set(COMPONENT_OBJEXCLUDE lwip/src/api/sockets.c) -endif() - idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" LDFRAGMENTS linker.lf @@ -161,3 +156,11 @@ if(GCC_NOT_5_2_0) -Wno-implicit-fallthrough ) endif() + +# "comparison is always false due to limited range of data type" warning +# when setting CONFIG_LWIP_TCP_WND_DEFAULT to 65535 +set_source_files_properties( + lwip/src/core/tcp.c + PROPERTIES COMPILE_FLAGS + -Wno-type-limits +) diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index fdc46b61..de890988 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -124,24 +124,6 @@ menu "LWIP" help Enabling this option allows LWIP statistics - config LWIP_SOCKET_MULTITHREAD - bool "LWIP socket supports multithread" - default y - help - Enable the option can enable LWIP socket multithread and all - function will be thread safe. - - config SET_SOLINGER_DEFAULT - bool "set socket SO_LINGER default" - default y - depends on LWIP_SOCKET_MULTITHREAD - help - The function is only used by socket multi-thread. - - Enable this option can set the target socket to enable the "SO_LINGER" and config timeout to be "0" when it is created. - It means that if close the socket, all send queue will be dropped, so heap memory can be collected immediately, - but some packets which are waiting to be sent will lost. - config LWIP_ETHARP_TRUST_IP_MAC bool "Enable LWIP ARP trust" default n diff --git a/components/lwip/apps/multi-threads/sockets_mt.c b/components/lwip/apps/multi-threads/sockets_mt.c deleted file mode 100644 index c02a6645..00000000 --- a/components/lwip/apps/multi-threads/sockets_mt.c +++ /dev/null @@ -1,826 +0,0 @@ -// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "lwip/opt.h" - -#ifdef SOCKETS_MT - -#define SOCKETS_MT_DISABLE_SHUTDOWN - -#include "lwip/priv/api_msg.h" - -/* disable all LWIP socket API when compiling LWIP raw socket */ - -#undef lwip_accept -#undef lwip_bind -#undef lwip_shutdown -#undef lwip_getpeername -#undef lwip_getsockname -#undef lwip_setsockopt -#undef lwip_getsockopt -#undef lwip_close -#undef lwip_connect -#undef lwip_listen -#undef lwip_recv -#undef lwip_recvfrom -#undef lwip_send -#undef lwip_sendmsg -#undef lwip_sendto -#undef lwip_socket -#undef lwip_select -#undef lwip_ioctlsocket - -#define lwip_accept lwip_accept_esp -#define lwip_bind lwip_bind_esp -#define lwip_shutdown lwip_shutdown_esp -#define lwip_getpeername lwip_getpeername_esp -#define lwip_getsockname lwip_getsockname_esp -#define lwip_setsockopt lwip_setsockopt_esp -#define lwip_getsockopt lwip_getsockopt_esp -#define lwip_close lwip_closesocket_esp -#define lwip_connect lwip_connect_esp -#define lwip_listen lwip_listen_esp -#define lwip_recv lwip_recv_esp -#define lwip_recvfrom lwip_recvfrom_esp -#define lwip_send lwip_send_esp -#define lwip_sendmsg lwip_sendmsg_esp -#define lwip_sendto lwip_sendto_esp -#define lwip_socket lwip_socket_esp -#define lwip_select lwip_select_esp -#define lwip_ioctlsocket lwip_ioctl_esp - -#undef lwip_read -#undef lwip_write -#undef lwip_writev -#undef lwip_close -#undef closesocket -#undef lwip_fcntl -#undef lwip_ioctl - -#define lwip_read lwip_read_esp -#define lwip_write lwip_write_esp -#define lwip_writev lwip_writev_esp -#define lwip_close lwip_close_esp -#define lwip_fcntl lwip_fcntl_esp -#define lwip_ioctl lwip_ioctl_esp - -#include "../../lwip/src/api/sockets.c" - -/* disable macros to enable LWIP function */ - -#undef lwip_accept -#undef lwip_bind -#undef lwip_shutdown -#undef lwip_getpeername -#undef lwip_getsockname -#undef lwip_setsockopt -#undef lwip_getsockopt -#undef lwip_close -#undef lwip_connect -#undef lwip_listen -#undef lwip_recv -#undef lwip_recvfrom -#undef lwip_send -#undef lwip_sendmsg -#undef lwip_sendto -#undef lwip_socket -#undef lwip_select -#undef lwip_ioctlsocket - -#undef lwip_read -#undef lwip_write -#undef lwip_writev -#undef lwip_close -#undef closesocket -#undef lwip_fcntl -#undef lwip_ioctl - -/********************************************************************/ -#define LWIP_SYNC_MT_SLEEP_MS 10 - -#define SOCK_MT_DEBUG_LEVEL 255 - -typedef struct socket_conn_sync { - struct tcpip_api_call_data call; - struct netconn *conn; -} socket_conn_sync_t; - -typedef int (*lwip_io_mt_fn)(int, int ); - -/* Use about 2 bit */ -#define SOCK_MT_STATE_SOCK 0 -#define SOCK_MT_STATE_ACCEPT 1 -#define SOCK_MT_STATE_CONNECT 2 -#define SOCK_MT_STATE_SEND 3 -#define SOCK_MT_STATE_ILL 4 - -#define SOCK_MT_LOCK_SEND (1 << 0) -#define SOCK_MT_LOCK_RECV (1 << 1) -#define SOCK_MT_LOCK_IOCTL (1 << 2) - -#define SOCK_MT_LOCK_MIN SOCK_MT_LOCK_SEND -#define SOCK_MT_LOCK_MAX SOCK_MT_LOCK_IOCTL - -#define SOCK_MT_SELECT_RECV (1 << 0) -#define SOCK_MT_SELECT_SEND (1 << 1) - -typedef struct _sock_mt { - uint8_t opened : 1; - uint8_t state : 2; - uint8_t select : 2; - uint8_t lock : 3; -} sock_mt_t; - -#if (SOCK_MT_DEBUG_LEVEL < 16) -#define SOCK_MT_DEBUG(level, ...) \ - if (level >= SOCK_MT_DEBUG_LEVEL) \ - printf(__VA_ARGS__); -#else -#define SOCK_MT_DEBUG(level, ...) -#endif - -#define SOCK_MT_ENTER_CHECK(s, l, st) \ -{ \ - if (_sock_lock(s, l) != ERR_OK) \ - return -1; \ - if (st != SOCK_MT_STATE_ILL) \ - _sock_set_state(s, st); \ -} - -#define SOCK_MT_EXIT_CHECK(s, l, st) \ -{ \ - if (st != SOCK_MT_STATE_ILL) \ - _sock_set_state(s, SOCK_MT_STATE_SOCK); \ - if (_sock_unlock(s, l) != ERR_OK) \ - return -1; \ -} - -static volatile sock_mt_t DRAM_ATTR sockets_mt[NUM_SOCKETS]; - -static inline void _sock_mt_init(int s) -{ - memset((void *)&sockets_mt[s - LWIP_SOCKET_OFFSET], 0, sizeof(sock_mt_t)); -} - -static inline int _sock_is_opened(int s) -{ - return sockets_mt[s - LWIP_SOCKET_OFFSET].opened != 0; -} - -static inline void _sock_set_open(int s, int opened) -{ - SYS_ARCH_DECL_PROTECT(lev); - - SYS_ARCH_PROTECT(lev); - sockets_mt[s - LWIP_SOCKET_OFFSET].opened = opened; - SYS_ARCH_UNPROTECT(lev); -} - -static inline void _sock_set_state(int s, int state) -{ - SYS_ARCH_DECL_PROTECT(lev); - - SYS_ARCH_PROTECT(lev); - sockets_mt[s - LWIP_SOCKET_OFFSET].state = state; - SYS_ARCH_UNPROTECT(lev); -} - -static inline int _sock_get_state(int s) -{ - return sockets_mt[s - LWIP_SOCKET_OFFSET].state; -} - -static inline int _sock_get_select(int s, int select) -{ - return sockets_mt[s - LWIP_SOCKET_OFFSET].select & select; -} - -static int inline _sock_is_lock(int s, int l) -{ - return sockets_mt[s - LWIP_SOCKET_OFFSET].lock & l; -} - -static int inline _sock_next_lock(int lock) -{ - return lock << 1; -} - -static void inline _sock_set_select(int s, int select) -{ - SYS_ARCH_DECL_PROTECT(lev); - - SYS_ARCH_PROTECT(lev); - sockets_mt[s - LWIP_SOCKET_OFFSET].select |= select; - SYS_ARCH_UNPROTECT(lev); -} - -static void inline _sock_reset_select(int s, int select) -{ - SYS_ARCH_DECL_PROTECT(lev); - - SYS_ARCH_PROTECT(lev); - sockets_mt[s - LWIP_SOCKET_OFFSET].select &= ~select; - SYS_ARCH_UNPROTECT(lev); -} - -static int _sock_try_lock(int s, int l) -{ - int ret = ERR_OK; - SYS_ARCH_DECL_PROTECT(lev); - - if (!_sock_is_opened(s)) { - ret = ERR_CLSD; - goto exit; - } - - if (sockets_mt[s - LWIP_SOCKET_OFFSET].lock & l) { - ret = ERR_INPROGRESS; - goto exit; - } - - SYS_ARCH_PROTECT(lev); - sockets_mt[s - LWIP_SOCKET_OFFSET].lock |= l; - SYS_ARCH_UNPROTECT(lev); - -exit: - return ret; -} - -static int _sock_lock(int s, int l) -{ - int ret = ERR_OK; - if (tryget_socket_unconn_nouse(s) == NULL) - return -1; - - SOCK_MT_DEBUG(1, "s %d l %d enter ", s, l); - - while (1) { - ret = _sock_try_lock(s, l); - - if (ret != ERR_INPROGRESS) - break; - - vTaskDelay(1); - } - - SOCK_MT_DEBUG(1, "OK %d\n", ret); - - return ret; -} - -static int _sock_unlock(int s, int l) -{ - int ret = 0; - SYS_ARCH_DECL_PROTECT(lev); - - SOCK_MT_DEBUG(1, "s %d l %d exit ", s, l); - - SYS_ARCH_PROTECT(lev); - sockets_mt[s - LWIP_SOCKET_OFFSET].lock &= ~l; - SYS_ARCH_UNPROTECT(lev); - - if (!_sock_is_opened(s)) { - ret = ERR_CLSD; - goto exit; - } - -exit: - SOCK_MT_DEBUG(1, "OK %d\n", ret); - - return ret; -} - -static int lwip_enter_mt_select(int s, fd_set *read_set, fd_set *write_set) -{ - int i; - - if (s > NUM_SOCKETS + LWIP_SOCKET_OFFSET || s < LWIP_SOCKET_OFFSET) - return -1; - - for (i = 0; i < s; i++) { - if(FD_ISSET(i, read_set) || FD_ISSET(i, write_set)) - if (tryget_socket_unconn_nouse(i) == NULL) - goto failed1; - - if (FD_ISSET(i, read_set)) { - err_t err; - - _sock_set_select(i, SOCK_MT_SELECT_RECV); - err = _sock_lock(i, SOCK_MT_LOCK_RECV); - if (err != ERR_OK) { - goto failed2; - } - } - - if (FD_ISSET(i, write_set)) { - err_t err; - - _sock_set_select(i, SOCK_MT_SELECT_SEND); - err = _sock_lock(i, SOCK_MT_LOCK_SEND); - if (err != ERR_OK) { - goto failed3; - } - } - } - - return 0; - -failed3: - _sock_unlock(i, SOCK_MT_LOCK_SEND); - _sock_reset_select(i, SOCK_MT_SELECT_SEND); -failed2: - if (FD_ISSET(i, read_set)) { - _sock_unlock(i, SOCK_MT_LOCK_RECV); - _sock_reset_select(i, SOCK_MT_SELECT_RECV); - } -failed1: - for (i--; i >=0; i--) { - if (FD_ISSET(i, read_set) ) { - _sock_unlock(i, SOCK_MT_LOCK_RECV); - _sock_reset_select(i, SOCK_MT_SELECT_RECV); - } - - if (FD_ISSET(i, write_set)) { - _sock_unlock(i, SOCK_MT_LOCK_SEND); - _sock_reset_select(i, SOCK_MT_SELECT_SEND); - } - } - - return -1; -} - -static void lwip_exit_mt_select(int s, fd_set *read_set, fd_set *write_set) -{ - int i; - - for (i = 0; i < s; i++) { - if (FD_ISSET(i, read_set)) { - _sock_unlock(i, SOCK_MT_LOCK_RECV); - _sock_reset_select(i, SOCK_MT_SELECT_RECV); - } - - if (FD_ISSET(i, write_set)) { - _sock_unlock(i, SOCK_MT_LOCK_SEND); - _sock_reset_select(i, SOCK_MT_SELECT_SEND); - } - } -} - -static err_t lwip_do_sync_accept(struct tcpip_api_call_data *call) -{ - socket_conn_sync_t *sync = (socket_conn_sync_t *)call; - struct netconn *conn = sync->conn; - - SYS_ARCH_DECL_PROTECT(lev); - SYS_ARCH_PROTECT(lev); - if (sys_mbox_valid(&conn->acceptmbox)) - sys_mbox_trypost(&conn->acceptmbox, NULL); - conn->state = NETCONN_NONE; - SYS_ARCH_UNPROTECT(lev); - - return ERR_OK; -} - -static err_t lwip_do_sync_send(struct tcpip_api_call_data *call) -{ - socket_conn_sync_t *sync = (socket_conn_sync_t *)call; - struct netconn *conn = sync->conn; - - SYS_ARCH_DECL_PROTECT(lev); - SYS_ARCH_PROTECT(lev); - if (conn->current_msg) { - conn->current_msg->err = ERR_OK; - if (sys_sem_valid(conn->current_msg->op_completed_sem)) - sys_sem_signal(conn->current_msg->op_completed_sem); - conn->current_msg = NULL; - } - conn->state = NETCONN_NONE; - SYS_ARCH_UNPROTECT(lev); - - return ERR_OK; -} - -static err_t lwip_do_sync_recv_state(struct tcpip_api_call_data *call) -{ - socket_conn_sync_t *sync = (socket_conn_sync_t *)call; - struct netconn *conn = sync->conn; - - SYS_ARCH_DECL_PROTECT(lev); - SYS_ARCH_PROTECT(lev); - SOCK_MT_DEBUG(1, "sync recv %d\n", conn->socket); - if (sys_mbox_valid(&conn->recvmbox)) - sys_mbox_trypost(&conn->recvmbox, NULL); - conn->state = NETCONN_NONE; - SYS_ARCH_UNPROTECT(lev); - - return ERR_OK; -} - -static err_t lwip_do_sync_select_state(struct tcpip_api_call_data *call) -{ - socket_conn_sync_t *sync = (socket_conn_sync_t *)call; - struct netconn *conn = sync->conn; - - SYS_ARCH_DECL_PROTECT(lev); - SYS_ARCH_PROTECT(lev); - event_callback(conn, NETCONN_EVT_ERROR, 0); - conn->state = NETCONN_NONE; - SYS_ARCH_UNPROTECT(lev); - - return ERR_OK; -} - -static void lwip_sync_state_mt(int s) -{ - struct lwip_sock *sock = tryget_socket_unconn_nouse(s); - int state = _sock_get_state(s); - socket_conn_sync_t sync = { - .conn = sock->conn, - }; - - SOCK_MT_DEBUG(1, "sync state %d\n", state); - - switch (state) { - case SOCK_MT_STATE_ACCEPT : - tcpip_api_call(lwip_do_sync_accept, &sync.call); - break; - case SOCK_MT_STATE_CONNECT: - case SOCK_MT_STATE_SEND : - tcpip_api_call(lwip_do_sync_send, &sync.call); - break; - default : - break; - } -} - -static void lwip_sync_recv_mt(int s) -{ - struct lwip_sock *sock = tryget_socket_unconn_nouse(s); - socket_conn_sync_t sync = { - .conn = sock->conn, - }; - - tcpip_api_call(lwip_do_sync_recv_state, &sync.call); -} - -static void lwip_sync_select_mt(int s) -{ - struct lwip_sock *sock = tryget_socket_unconn_nouse(s); - socket_conn_sync_t sync = { - .conn = sock->conn, - }; - - tcpip_api_call(lwip_do_sync_select_state, &sync.call); -} - -static void lwip_sync_mt(int s, int how) -{ - int lock = SOCK_MT_LOCK_MIN; - - do { - if (_sock_is_lock(s, lock)) { - int need_wait = 0; - - if (!_sock_get_select(s, SOCK_MT_SELECT_RECV | SOCK_MT_SELECT_SEND)) { - switch (lock) { - case SOCK_MT_LOCK_SEND: - lwip_sync_state_mt(s); - need_wait = 1; - break; - case SOCK_MT_LOCK_RECV: - lwip_sync_recv_mt(s); - need_wait = 1; - break; - default : - break; - } - } else { - lwip_sync_select_mt(s); - need_wait = 1; - } - - if (need_wait) - sys_delay_ms(LWIP_SYNC_MT_SLEEP_MS); - } else - lock = _sock_next_lock(lock); - } while (lock < SOCK_MT_LOCK_MAX); -} - -#if SET_SOLINGER_DEFAULT -#if LWIP_SO_LINGER -static void lwip_socket_set_so_link(int s, int linger) -{ - struct lwip_sock *sock = tryget_socket_unconn_nouse(s); - - if (sock) { - /* - * linker: - * -1: nothing - * 0: free sent_buf immediately - */ - sock->conn->linger = linger; - } -} -#else -#error "LWIP_SO_LINGER must be enable" -#endif /* LWIP_SO_LINGER */ -#else /* SET_SOLINGER_DEFAULT */ -#define lwip_socket_set_so_link(_s, _linger) -#endif /* SET_SOLINGER_DEFAULT */ - -int lwip_socket(int domain, int type, int protocol) -{ - int s; - - s = lwip_socket_esp(domain, type, protocol); - if (s < 0) - return -1; - - lwip_socket_set_so_link(s, 0); - _sock_mt_init(s); - _sock_set_open(s, 1); - - return s; -} - -int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ILL); - - ret = lwip_bind_esp(s, name, namelen); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ILL); - - return ret; -} - -int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_CONNECT); - - ret = lwip_connect_esp(s, name, namelen); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_CONNECT); - - return ret; -} - -int lwip_listen(int s, int backlog) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ILL); - - lwip_socket_set_so_link(s, -1); - - ret = lwip_listen_esp(s, backlog); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ILL); - - return ret; -} - -int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ACCEPT) - - lwip_socket_set_so_link(s, -1); - - ret = lwip_accept_esp(s, addr, addrlen); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ACCEPT); - - if (ret < 0) - return -1; - - lwip_socket_set_so_link(ret, 0); - _sock_mt_init(ret); - _sock_set_open(ret, 1); - - return ret; -} - -int lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - ret = lwip_getpeername_esp(s, name, namelen); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - return ret; -} - -int lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - ret = lwip_getsockname_esp(s, name, namelen); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - return ret; -} - -int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - ret = lwip_setsockopt_esp(s, level, optname, optval, optlen); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - return ret; -} - -int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) -{ - int ret; - - if (tryget_socket_unconn_nouse(s) == NULL) - return -1; - - if (optname == SO_ERROR) { - int retval = 0; - - if (!_sock_is_opened(s)) - retval = ENOTCONN; - - if (retval) { - *(int *)optval = retval; - return 0; - } - } - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - ret = lwip_getsockopt_esp(s, level, optname, optval, optlen); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - return ret; -} - -int lwip_ioctl(int s, long cmd, void *argp) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL) - - ret = lwip_ioctl_esp(s, cmd, argp); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - return ret; -} - -int lwip_sendto(int s, const void *data, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_SEND); - - ret = lwip_sendto_esp(s, data, size, flags, to, tolen); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_SEND); - - return ret; -} - -int lwip_send(int s, const void *data, size_t size, int flags) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_SEND); - - ret = lwip_send_esp(s, data, size, flags); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_SEND); - - return ret; -} - -int lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_RECV, SOCK_MT_STATE_ILL); - - ret = lwip_recvfrom_esp(s, mem, len, flags, from, fromlen); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_RECV, SOCK_MT_STATE_ILL); - - return ret; -} - -int lwip_recv(int s, void *mem, size_t len, int flags) -{ - return lwip_recvfrom(s, mem, len, flags, NULL, NULL); -} - -int lwip_read(int s, void *mem, size_t len) -{ - return lwip_recvfrom(s, mem, len, 0, NULL, NULL); -} - -int lwip_write(int s, const void *data, size_t size) -{ - return lwip_send(s, data, size, 0); -} - -int lwip_fcntl(int s, int cmd, int val) -{ - int ret; - - SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - ret = lwip_fcntl_esp(s, cmd, val); - - SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL); - - return ret; -} - -int lwip_shutdown(int s, int how) -{ - return 0; -} - -int lwip_close(int s) -{ - int ret; - SYS_ARCH_DECL_PROTECT(lev); - - if (tryget_socket_unconn_nouse(s) == NULL) - return -1; - - SYS_ARCH_PROTECT(lev); - if (_sock_is_opened(s)) { - _sock_set_open(s, 0); - SYS_ARCH_UNPROTECT(lev); - } else { - SYS_ARCH_UNPROTECT(lev); - return -1; - } - - - lwip_sync_mt(s, SHUT_RDWR); - - ret = lwip_close_esp(s); - - return ret; -} - -int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, - fd_set *exceptset, struct timeval *timeout) -{ - int ret; - fd_set read_set, write_set; - - if (readset) - MEMCPY(&read_set, readset, sizeof(fd_set)); - else - FD_ZERO(&read_set); - - if (writeset) - MEMCPY(&write_set, writeset, sizeof(fd_set)); - else - FD_ZERO(&write_set); - - ret = lwip_enter_mt_select(maxfdp1, &read_set, &write_set); - if (ret) - return ret; - - ret = lwip_select_esp(maxfdp1, readset, writeset, exceptset, timeout); - - lwip_exit_mt_select(maxfdp1, &read_set, &write_set); - - return ret; -} - -#endif diff --git a/components/lwip/component.mk b/components/lwip/component.mk index 2490bf45..2b668e41 100644 --- a/components/lwip/component.mk +++ b/components/lwip/component.mk @@ -30,12 +30,6 @@ ifndef CONFIG_IDF_TARGET_ESP32 COMPONENT_OBJEXCLUDE := port/esp8266/netif/ethernetif.o endif -ifdef CONFIG_LWIP_SOCKET_MULTITHREAD - COMPONENT_SRCDIRS += apps/multi-threads - COMPONENT_OBJEXCLUDE += lwip/src/api/sockets.o -endif - - ifdef CONFIG_LWIP_PPP_SUPPORT COMPONENT_SRCDIRS += lwip/src/netif/ppp lwip/src/netif/ppp/polarssl endif @@ -47,4 +41,6 @@ lwip/src/netif/ppp/ppp.o: CFLAGS += -Wno-uninitialized lwip/src/netif/ppp/pppos.o: CFLAGS += -Wno-implicit-fallthrough endif +lwip/src/core/tcp.o: CFLAGS += -Wno-type-limits + COMPONENT_ADD_LDFRAGMENTS += linker.lf diff --git a/components/lwip/port/esp8266/freertos/sys_arch.c b/components/lwip/port/esp8266/freertos/sys_arch.c index 85bca91c..a3776d59 100644 --- a/components/lwip/port/esp8266/freertos/sys_arch.c +++ b/components/lwip/port/esp8266/freertos/sys_arch.c @@ -41,7 +41,9 @@ #include "lwip/stats.h" #include "esp_log.h" -static const char* TAG = "lwip_arch"; +/* This is the number of threads that can be started with sys_thread_new() */ +#define SYS_THREAD_MAX 4 +#define TAG "lwip_arch" static sys_mutex_t g_lwip_protect_mutex = NULL; @@ -49,167 +51,160 @@ static pthread_key_t sys_thread_sem_key; static void sys_thread_sem_free(void* data); #if !LWIP_COMPAT_MUTEX - -/** - * @brief Create a new mutex - * - * @param pxMutex pointer of the mutex to create - * @return ERR_OK on success, ERR_MEM when out of memory - */ +/** Create a new mutex + * @param mutex pointer to the mutex to create + * @return a new mutex */ err_t sys_mutex_new(sys_mutex_t *pxMutex) { + err_t xReturn = ERR_MEM; + *pxMutex = xSemaphoreCreateMutex(); - if (*pxMutex == NULL) { - LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mutex_new: out of mem\r\n")); - return ERR_MEM; + + if (*pxMutex != NULL) { + xReturn = ERR_OK; } LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mutex_new: m=%p\n", *pxMutex)); - return ERR_OK; + return xReturn; } -/** - * @brief Lock a mutex - * - * @param pxMutex pointer of mutex to lock - */ -void +/** Lock a mutex + * @param mutex the mutex to lock */ +void ESP_IRAM_ATTR sys_mutex_lock(sys_mutex_t *pxMutex) { - BaseType_t ret = xSemaphoreTake(*pxMutex, portMAX_DELAY); - - LWIP_ASSERT("failed to take the mutex", ret == pdTRUE); + while (xSemaphoreTake(*pxMutex, portMAX_DELAY) != pdPASS); } -/** - * @brief Unlock a mutex - * - * @param pxMutex pointer of mutex to unlock - */ -void +err_t +sys_mutex_trylock(sys_mutex_t *pxMutex) +{ + if (xSemaphoreTake(*pxMutex, 0) == pdPASS) return 0; + else return -1; +} + +/** Unlock a mutex + * @param mutex the mutex to unlock */ +void ESP_IRAM_ATTR sys_mutex_unlock(sys_mutex_t *pxMutex) { - BaseType_t ret = xSemaphoreGive(*pxMutex); - - LWIP_ASSERT("failed to give the mutex", ret == pdTRUE); + xSemaphoreGive(*pxMutex); } -/** - * @brief Delete a mutex - * - * @param pxMutex pointer of mutex to delete - */ +/** Delete a semaphore + * @param mutex the mutex to delete */ void sys_mutex_free(sys_mutex_t *pxMutex) { LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mutex_free: m=%p\n", *pxMutex)); - vSemaphoreDelete(*pxMutex); - *pxMutex = NULL; + vQueueDelete(*pxMutex); } +#endif -#endif /* !LWIP_COMPAT_MUTEX */ - -/** - * @brief Creates a new semaphore - * - * @param sem pointer of the semaphore - * @param count initial state of the semaphore - * @return err_t - */ +/*-----------------------------------------------------------------------------------*/ +// Creates and returns a new semaphore. The "count" argument specifies +// the initial state of the semaphore. TBD finish and test err_t sys_sem_new(sys_sem_t *sem, u8_t count) { - LWIP_ASSERT("initial_count invalid (neither 0 nor 1)", - (count == 0) || (count == 1)); + err_t xReturn = ERR_MEM; + vSemaphoreCreateBinary(*sem); - *sem = xSemaphoreCreateBinary(); - if (*sem == NULL) { - LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_sem_new: out of mem\r\n")); - return ERR_MEM; + if ((*sem) != NULL) { + if (count == 0) { // Means it can't be taken + xSemaphoreTake(*sem, 1); + } + + xReturn = ERR_OK; + } else { + ; // TBD need assert } - if (count == 1) { - BaseType_t ret = xSemaphoreGive(*sem); - LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE); - } - - return ERR_OK; + return xReturn; } -/** - * @brief Signals a semaphore - * - * @param sem pointer of the semaphore - */ -void +/*-----------------------------------------------------------------------------------*/ +// Signals a semaphore +void ESP_IRAM_ATTR sys_sem_signal(sys_sem_t *sem) { - BaseType_t ret = xSemaphoreGive(*sem); - /* queue full is OK, this is a signal only... */ - LWIP_ASSERT("sys_sem_signal: sane return value", - (ret == pdTRUE) || (ret == errQUEUE_FULL)); + xSemaphoreGive(*sem); } /*-----------------------------------------------------------------------------------*/ // Signals a semaphore (from ISR) -int -sys_sem_signal_isr(sys_sem_t *sem) +int sys_sem_signal_isr(sys_sem_t *sem) { BaseType_t woken = pdFALSE; xSemaphoreGiveFromISR(*sem, &woken); return woken == pdTRUE; } -/** - * @brief Wait for a semaphore to be signaled - * - * @param sem pointer of the semaphore - * @param timeout if zero, will wait infinitely, or will wait for milliseconds specify by this argument - * @return SYS_ARCH_TIMEOUT when timeout, 0 otherwise - */ -u32_t +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. +*/ +u32_t ESP_IRAM_ATTR sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { - BaseType_t ret; + portTickType StartTime, EndTime, Elapsed; + unsigned long ulReturn; - if (!timeout) { - /* wait infinite */ - ret = xSemaphoreTake(*sem, portMAX_DELAY); - LWIP_ASSERT("taking semaphore failed", ret == pdTRUE); - } else { - TickType_t timeout_ticks = timeout / portTICK_RATE_MS; - ret = xSemaphoreTake(*sem, timeout_ticks); - if (ret == errQUEUE_EMPTY) { - /* timed out */ - return SYS_ARCH_TIMEOUT; + StartTime = xTaskGetTickCount(); + + if (timeout != 0) { + if (xSemaphoreTake(*sem, timeout / portTICK_PERIOD_MS) == pdTRUE) { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS; + + if (Elapsed == 0) { + Elapsed = 1; + } + + ulReturn = Elapsed; + } else { + ulReturn = SYS_ARCH_TIMEOUT; } - LWIP_ASSERT("taking semaphore failed", ret == pdTRUE); + } else { // must block without a timeout + while (xSemaphoreTake(*sem, portMAX_DELAY) != pdTRUE); + + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS; + + if (Elapsed == 0) { + Elapsed = 1; + } + + ulReturn = Elapsed; } - return 0; + return ulReturn ; // return time blocked } -/** - * @brief Delete a semaphore - * - * @param sem pointer of the semaphore to delete - */ +/*-----------------------------------------------------------------------------------*/ +// Deallocates a semaphore void sys_sem_free(sys_sem_t *sem) { vSemaphoreDelete(*sem); - *sem = NULL; } -/** - * @brief Create an empty mailbox. - * - * @param mbox pointer of the mailbox - * @param size size of the mailbox - * @return ERR_OK on success, ERR_MEM when out of memory - */ +/*-----------------------------------------------------------------------------------*/ +// Creates an empty mailbox. err_t sys_mbox_new(sys_mbox_t *mbox, int size) { @@ -222,7 +217,7 @@ sys_mbox_new(sys_mbox_t *mbox, int size) (*mbox)->os_mbox = xQueueCreate(size, sizeof(void *)); if ((*mbox)->os_mbox == NULL) { - LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("fail to new (*mbox)->os_mbox\n")); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("fail to new *mbox->os_mbox\n")); free(*mbox); return ERR_MEM; } @@ -235,32 +230,21 @@ sys_mbox_new(sys_mbox_t *mbox, int size) return ERR_OK; } -/** - * @brief Send message to mailbox - * - * @param mbox pointer of the mailbox - * @param msg pointer of the message to send - */ -void +/*-----------------------------------------------------------------------------------*/ +// Posts the "msg" to the mailbox. +void ESP_IRAM_ATTR sys_mbox_post(sys_mbox_t *mbox, void *msg) { - BaseType_t ret = xQueueSendToBack((*mbox)->os_mbox, &msg, portMAX_DELAY); - LWIP_ASSERT("mbox post failed", ret == pdTRUE); + while (xQueueSendToBack((*mbox)->os_mbox, &msg, portMAX_DELAY) != pdTRUE); } -/** - * @brief Try to post a message to mailbox - * - * @param mbox pointer of the mailbox - * @param msg pointer of the message to send - * @return ERR_OK on success, ERR_MEM when mailbox is full - */ -err_t +/*-----------------------------------------------------------------------------------*/ +err_t ESP_IRAM_ATTR sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { err_t xReturn; - if (xQueueSend((*mbox)->os_mbox, &msg, 0) == pdTRUE) { + if (xQueueSend((*mbox)->os_mbox, &msg, (portTickType)0) == pdPASS) { xReturn = ERR_OK; } else { LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("trypost mbox=%p fail\n", (*mbox)->os_mbox)); @@ -270,95 +254,83 @@ sys_mbox_trypost(sys_mbox_t *mbox, void *msg) return xReturn; } -/** - * @brief Try to post a message to mailbox from ISR - * - * @param mbox pointer of the mailbox - * @param msg pointer of the message to send - * @return ERR_OK on success - * ERR_MEM when mailbox is full - * ERR_NEED_SCHED when high priority task wakes up - */ -err_t -sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg) -{ - BaseType_t ret; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. - ret = xQueueSendFromISR((*mbox)->os_mbox, &msg, &xHigherPriorityTaskWoken); - if (ret == pdTRUE) { - if (xHigherPriorityTaskWoken == pdTRUE) { - return ERR_NEED_SCHED; - } - return ERR_OK; - } else { - LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL); - return ERR_MEM; - } -} + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. -/** - * @brief Fetch message from mailbox - * - * @param mbox pointer of mailbox - * @param msg pointer of the received message, could be NULL to indicate the message should be dropped - * @param timeout if zero, will wait infinitely; or will wait milliseconds specify by this argument - * @return SYS_ARCH_TIMEOUT when timeout, 0 otherwise - */ -u32_t + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. +*/ +u32_t ESP_IRAM_ATTR sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { - BaseType_t ret; - void *msg_dummy; + void *dummyptr; + portTickType StartTime, EndTime, Elapsed; + unsigned long ulReturn; + StartTime = xTaskGetTickCount(); if (msg == NULL) { - msg = &msg_dummy; + msg = &dummyptr; + } + + if (*mbox == NULL){ + *msg = NULL; + return -1; } if (timeout == 0) { - /* wait infinite */ - ret = xQueueReceive((*mbox)->os_mbox, &(*msg), portMAX_DELAY); - LWIP_ASSERT("mbox fetch failed", ret == pdTRUE); + timeout = portMAX_DELAY; } else { - TickType_t timeout_ticks = timeout / portTICK_RATE_MS; - ret = xQueueReceive((*mbox)->os_mbox, &(*msg), timeout_ticks); - if (ret == errQUEUE_EMPTY) { - /* timed out */ - *msg = NULL; - return SYS_ARCH_TIMEOUT; - } - LWIP_ASSERT("mbox fetch failed", ret == pdTRUE); + timeout = timeout / portTICK_PERIOD_MS; } - return 0; + *msg = NULL; + if (pdTRUE == xQueueReceive((*mbox)->os_mbox, &(*msg), timeout)) { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS; + + if (Elapsed == 0) { + Elapsed = 1; + } + + ulReturn = Elapsed; + } else { // timed out blocking for message + ulReturn = SYS_ARCH_TIMEOUT; + } + + return ulReturn ; // return time blocked TBD test } -/** - * @brief try to fetch message from mailbox - * - * @param mbox pointer of mailbox - * @param msg pointer of the received message - * @return SYS_MBOX_EMPTY if mailbox is empty, 1 otherwise - */ +/*-----------------------------------------------------------------------------------*/ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { - BaseType_t ret; - void *msg_dummy; + void *pvDummy; + unsigned long ulReturn; if (msg == NULL) { - msg = &msg_dummy; + msg = &pvDummy; } - ret = xQueueReceive((*mbox)->os_mbox, &(*msg), 0); - if (ret == errQUEUE_EMPTY) { - *msg = NULL; - return SYS_MBOX_EMPTY; + if (pdTRUE == xQueueReceive((*mbox)->os_mbox, &(*msg), 0)) { + ulReturn = ERR_OK; + } else { + ulReturn = SYS_MBOX_EMPTY; } - LWIP_ASSERT("mbox fetch failed", ret == pdTRUE); - return 0; + return ulReturn; } +/*-----------------------------------------------------------------------------------*/ + void sys_mbox_set_owner(sys_mbox_t *mbox, void* owner) { @@ -368,99 +340,88 @@ sys_mbox_set_owner(sys_mbox_t *mbox, void* owner) } } -/** - * @brief Delete a mailbox - * - * @param mbox pointer of the mailbox to delete - */ +/* + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. +*/ void sys_mbox_free(sys_mbox_t *mbox) { - if ((NULL == mbox) || (NULL == *mbox)) { - return; + if ( (NULL == mbox) || (NULL == *mbox) ) { + return; } - UBaseType_t msgs_waiting = uxQueueMessagesWaiting((*mbox)->os_mbox); - LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0); - vQueueDelete((*mbox)->os_mbox); free(*mbox); *mbox = NULL; + } -/** - * @brief Create a new thread - * - * @param name thread name - * @param thread thread function - * @param arg thread arguments - * @param stacksize stacksize of the thread - * @param prio priority of the thread - * @return thread ID - */ +/*-----------------------------------------------------------------------------------*/ +/* + Starts a new thread with priority "prio" that will begin its execution in the + function "thread()". The "arg" argument will be passed as an argument to the + thread() function. The id of the new thread is returned. Both the id and + the priority are system dependent. +*/ sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio) { - TaskHandle_t rtos_task; - BaseType_t ret; + xTaskHandle created_task; + portBASE_TYPE result; - /* LwIP's lwip_thread_fn matches FreeRTOS' TaskFunction_t, so we can pass the - thread function without adaption here. */ - ret = xTaskCreatePinnedToCore(thread, name, stacksize, arg, prio, &rtos_task, + result = xTaskCreatePinnedToCore(thread, name, stacksize, arg, prio, &created_task, CONFIG_LWIP_TCPIP_TASK_AFFINITY); - if (ret != pdTRUE) { + if (result != pdPASS) { return NULL; } - return (sys_thread_t)rtos_task; + return created_task; } -/** - * @brief Initialize the sys_arch layer - * - */ +/*-----------------------------------------------------------------------------------*/ +// Initialize sys arch void sys_init(void) { - if (ERR_OK != sys_mutex_new(&g_lwip_protect_mutex)) { - ESP_LOGE(TAG, "sys_init: failed to init lwip protect mutex\n"); - } + if (ERR_OK != sys_mutex_new(&g_lwip_protect_mutex)) { + ESP_LOGE(TAG, "sys_init: failed to init lwip protect mutex\n"); + } - // Create the pthreads key for the per-thread semaphore storage - pthread_key_create(&sys_thread_sem_key, sys_thread_sem_free); + // Create the pthreads key for the per-thread semaphore storage + pthread_key_create(&sys_thread_sem_key, sys_thread_sem_free); - esp_vfs_lwip_sockets_register(); + esp_vfs_lwip_sockets_register(); } -/** - * @brief Get system ticks - * - * @return system tick counts - */ +/*-----------------------------------------------------------------------------------*/ u32_t sys_jiffies(void) { return xTaskGetTickCount(); } -/** - * @brief Get current time, in miliseconds - * - * @return current time - */ +/*-----------------------------------------------------------------------------------*/ u32_t sys_now(void) { - return xTaskGetTickCount() * portTICK_PERIOD_MS; + return (xTaskGetTickCount()*portTICK_PERIOD_MS); } -/** - * @brief Protect critical region - * - * @note This function is only called during very short critical regions. - * - * @return previous protection level - */ +/* + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. +*/ sys_prot_t sys_arch_protect(void) { @@ -468,23 +429,23 @@ sys_arch_protect(void) return (sys_prot_t) 1; } -/** - * @brief Unprotect critical region - * - * @param pval protection level - */ +/*-----------------------------------------------------------------------------------*/ +/* + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. +*/ void sys_arch_unprotect(sys_prot_t pval) { - LWIP_UNUSED_ARG(pval); sys_mutex_unlock(&g_lwip_protect_mutex); } /* - * get per thread semaphore + * get per thread semphore */ -sys_sem_t* -sys_thread_sem_get(void) +sys_sem_t* sys_thread_sem_get(void) { sys_sem_t *sem = pthread_getspecific(sys_thread_sem_key); @@ -495,8 +456,7 @@ sys_thread_sem_get(void) return sem; } -static void -sys_thread_sem_free(void* data) // destructor for TLS semaphore +static void sys_thread_sem_free(void* data) // destructor for TLS semaphore { sys_sem_t *sem = (sys_sem_t*)(data); @@ -511,8 +471,7 @@ sys_thread_sem_free(void* data) // destructor for TLS semaphore } } -sys_sem_t* -sys_thread_sem_init(void) +sys_sem_t* sys_thread_sem_init(void) { sys_sem_t *sem = (sys_sem_t*)mem_malloc(sizeof(sys_sem_t*)); @@ -532,8 +491,7 @@ sys_thread_sem_init(void) return sem; } -void -sys_thread_sem_deinit(void) +void sys_thread_sem_deinit(void) { sys_sem_t *sem = pthread_getspecific(sys_thread_sem_key); if (sem != NULL) { @@ -542,8 +500,9 @@ sys_thread_sem_deinit(void) } } -void -sys_delay_ms(uint32_t ms) +void sys_delay_ms(uint32_t ms) { vTaskDelay(ms / portTICK_PERIOD_MS); } + + diff --git a/components/lwip/port/esp8266/include/arch/sys_arch.h b/components/lwip/port/esp8266/include/arch/sys_arch.h index d6c5216a..5fea8eb5 100644 --- a/components/lwip/port/esp8266/include/arch/sys_arch.h +++ b/components/lwip/port/esp8266/include/arch/sys_arch.h @@ -29,7 +29,7 @@ * Author: Adam Dunkels * */ - + #ifndef __SYS_ARCH_H__ #define __SYS_ARCH_H__ @@ -44,22 +44,15 @@ extern "C" { #endif -typedef SemaphoreHandle_t sys_sem_t; -typedef SemaphoreHandle_t sys_mutex_t; -typedef TaskHandle_t sys_thread_t; +typedef xSemaphoreHandle sys_sem_t; +typedef xSemaphoreHandle sys_mutex_t; +typedef xTaskHandle sys_thread_t; typedef struct sys_mbox_s { - QueueHandle_t os_mbox; + xQueueHandle os_mbox; void *owner; }* sys_mbox_t; -/** This is returned by _fromisr() sys functions to tell the outermost function - * that a higher priority task was woken and the scheduler needs to be invoked. - */ -#define ERR_NEED_SCHED 123 - -void sys_delay_ms(uint32_t ms); -#define sys_msleep(ms) sys_delay_ms(ms) #define LWIP_COMPAT_MUTEX 0 @@ -71,7 +64,7 @@ void sys_delay_ms(uint32_t ms); #define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) /* Define the sys_mbox_set_invalid() to empty to support lock-free mbox in ESP LWIP. - * + * * The basic idea about the lock-free mbox is that the mbox should always be valid unless * no socket APIs are using the socket and the socket is closed. ESP LWIP achieves this by * following two changes to official LWIP: @@ -79,9 +72,9 @@ void sys_delay_ms(uint32_t ms); * no one is using the socket. * 2. Define the sys_mbox_set_invalid() to empty if the mbox is not actually freed. - * The second change is necessary. Consider a common scenario: the application task calls + * The second change is necessary. Consider a common scenario: the application task calls * recv() to receive packets from the socket, the sys_mbox_valid() returns true. Because there - * is no lock for the mbox, the LWIP CORE can call sys_mbox_set_invalid() to set the mbox at + * is no lock for the mbox, the LWIP CORE can call sys_mbox_set_invalid() to set the mbox at * anytime and the thread-safe issue may happen. * * However, if the sys_mbox_set_invalid() is not called after sys_mbox_free(), e.g. in netconn_alloc(), diff --git a/components/lwip/port/esp8266/include/lwipopts.h b/components/lwip/port/esp8266/include/lwipopts.h index 1a73fd03..fc6b19b5 100644 --- a/components/lwip/port/esp8266/include/lwipopts.h +++ b/components/lwip/port/esp8266/include/lwipopts.h @@ -567,13 +567,6 @@ */ #define LWIP_SO_RCVBUF CONFIG_LWIP_SO_RCVBUF -/** - * LWIP_SO_LINGER==1: Enable SO_LINGER processing. - */ -#define LWIP_SO_LINGER 1 - -#define SET_SOLINGER_DEFAULT CONFIG_SET_SOLINGER_DEFAULT - /** * SO_REUSE==1: Enable SO_REUSEADDR option. * This option is set via menuconfig. @@ -792,9 +785,7 @@ #define LWIP_SOCKET_OFFSET (FD_SETSIZE - CONFIG_LWIP_MAX_SOCKETS) /* Enable all Espressif-only options */ -#ifdef CONFIG_LWIP_SOCKET_MULTITHREAD -#define SOCKETS_MT -#endif + #define ESP_LWIP 1 #define ESP_LWIP_ARP 1 #define ESP_PER_SOC_TCP_WND 0 @@ -824,6 +815,7 @@ #define ESP_IPV6 LWIP_IPV6 #define ESP_SOCKET 1 #define ESP_LWIP_SELECT 1 +#define ESP_LWIP_LOCK 1 #ifdef ESP_IRAM_ATTR #undef ESP_IRAM_ATTR