diff --git a/lib/bsp/device/spi.cpp b/lib/bsp/device/spi.cpp index f4641ec..7ba9f58 100644 --- a/lib/bsp/device/spi.cpp +++ b/lib/bsp/device/spi.cpp @@ -292,6 +292,7 @@ double k_spi_driver::set_clock_rate(k_spi_device_driver &device, double clock_ra int k_spi_driver::read(k_spi_device_driver &device, gsl::span buffer) { COMMON_ENTRY; + setup_device(device); uint32_t i = 0; @@ -308,6 +309,7 @@ int k_spi_driver::read(k_spi_device_driver &device, gsl::span buffer) if (rx_frames < SPI_TRANSMISSION_THRESHOLD) { + vTaskEnterCritical(); size_t index, fifo_len; while (rx_frames) { @@ -335,6 +337,7 @@ int k_spi_driver::read(k_spi_device_driver &device, gsl::span buffer) } rx_frames -= fifo_len; } + vTaskExitCritical(); } else { @@ -355,12 +358,14 @@ int k_spi_driver::read(k_spi_device_driver &device, gsl::span buffer) spi_.ser = 0x00; spi_.ssienr = 0x00; spi_.dmacr = 0x00; + return buffer.size(); } int k_spi_driver::write(k_spi_device_driver &device, gsl::span buffer) { COMMON_ENTRY; + setup_device(device); uint32_t i = 0; @@ -371,6 +376,7 @@ int k_spi_driver::write(k_spi_device_driver &device, gsl::span bu if (tx_frames < SPI_TRANSMISSION_THRESHOLD) { + vTaskEnterCritical(); size_t index, fifo_len; spi_.ssienr = 0x01; write_inst_addr(spi_.dr, &buffer_write, device.inst_width_); @@ -399,6 +405,7 @@ int k_spi_driver::write(k_spi_device_driver &device, gsl::span bu } tx_buffer_len -= fifo_len; } + vTaskExitCritical(); } else { @@ -420,6 +427,7 @@ int k_spi_driver::write(k_spi_device_driver &device, gsl::span bu spi_.ser = 0x00; spi_.ssienr = 0x00; spi_.dmacr = 0x00; + return buffer.size(); } @@ -452,6 +460,7 @@ int k_spi_driver::read_write(k_spi_device_driver &device, gsl::span::max()); while (read(DM9051_TCR) & DM9051_TCR_SET) - ; - + { + usleep(5000); + } write(DM9051_TXPLL, length & 0xff); write(DM9051_TXPLH, (length >> 8) & 0xff); } @@ -370,12 +371,12 @@ public: uint16_t len = 0; uint16_t status; - read(DM9051_MRCMDX); // dummy read + read(DM9051_MRCMDX); // dummy read - uint8_t header[4]; - read_memory({ header }); - status = header[0] | (header[1] << 8); - len = header[2] | (header[3] << 8); + uint8_t header[4]; + read_memory({ header }); + status = header[0] | (header[1] << 8); + len = header[2] | (header[3] << 8); if (len > DM9051_PKT_MAX) { // read-error len = 0; // read-error (keep no change to rx fifo) @@ -455,14 +456,14 @@ private: xSemaphoreGiveFromISR(driver.interrupt_event_, &xHigherPriorityTaskWoken); if (xHigherPriorityTaskWoken) { - portYIELD(); + portYIELD_FROM_ISR(); } } uint8_t read(uint8_t addr) { const uint8_t to_write[1] = { addr }; - uint8_t to_read[1]; + uint8_t to_read[1] = { 0 }; spi_dev_->transfer_sequential({ to_write }, { to_read }); return to_read[0]; } diff --git a/lib/freertos/conf/FreeRTOSConfig.h b/lib/freertos/conf/FreeRTOSConfig.h index 6f6c7bf..f4a427d 100644 --- a/lib/freertos/conf/FreeRTOSConfig.h +++ b/lib/freertos/conf/FreeRTOSConfig.h @@ -68,7 +68,7 @@ #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configMAX_PRIORITIES ( 5 ) #define configMAX_TASK_NAME_LEN ( 16 ) -#define configUSE_TRACE_FACILITY 0 +#define configUSE_TRACE_FACILITY 1 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 0 #define configQUEUE_REGISTRY_SIZE 8 diff --git a/lib/freertos/core_sync.c b/lib/freertos/core_sync.c index 72e440c..9888ad9 100644 --- a/lib/freertos/core_sync.c +++ b/lib/freertos/core_sync.c @@ -54,12 +54,15 @@ void handle_irq_m_soft(uintptr_t *regs, uintptr_t cause) void core_sync_request(uint64_t core_id, int event) { + vTaskEnterCritical(); + corelock_lock(&s_core_sync_locks[core_id]); while (s_core_sync_events[core_id] != CORE_SYNC_NONE) ; s_core_sync_events[core_id] = event; clint_ipi_send(core_id); corelock_unlock(&s_core_sync_locks[core_id]); + vTaskExitCritical(); } void core_sync_complete(uint64_t core_id) diff --git a/lib/freertos/include/kernel/driver.hpp b/lib/freertos/include/kernel/driver.hpp index 423a3b8..018bc0b 100644 --- a/lib/freertos/include/kernel/driver.hpp +++ b/lib/freertos/include/kernel/driver.hpp @@ -60,6 +60,23 @@ MAKE_ENUM_CLASS_BITMASK_TYPE(file_access_t); MAKE_ENUM_CLASS_BITMASK_TYPE(file_mode_t); MAKE_ENUM_CLASS_BITMASK_TYPE(socket_message_flag_t); +class errno_exception : public std::runtime_error +{ +public: + explicit errno_exception(const char *msg, int code) noexcept + : runtime_error(msg), code_(code) + { + } + + int code() const noexcept + { + return code_; + } + +private: + int code_; +}; + class object_access : public virtual object { public: @@ -410,7 +427,7 @@ public: virtual void end_receive() = 0; }; -class network_socket : public virtual object_access +class network_socket : public virtual custom_driver, public virtual object_access { public: virtual object_accessor accept(socket_address_t *remote_address) = 0; @@ -424,6 +441,8 @@ public: virtual size_t receive_from(gsl::span buffer, socket_message_flag_t flags, socket_address_t *from) = 0; virtual size_t read(gsl::span buffer) = 0; virtual size_t write(gsl::span buffer) = 0; + virtual int fcntl(int cmd, int val) = 0; + virtual void select(fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) = 0; }; extern driver_registry_t g_hal_drivers[]; diff --git a/lib/freertos/include/network.h b/lib/freertos/include/network.h index 0b6541a..b4d2f94 100644 --- a/lib/freertos/include/network.h +++ b/lib/freertos/include/network.h @@ -257,6 +257,8 @@ int network_socket_send_to(handle_t socket_handle, const uint8_t *data, size_t l * - other Fail */ int network_socket_receive_from(handle_t socket_handle, uint8_t *data, size_t len, socket_message_flag_t flags, socket_address_t *from); +int network_socket_fcntl(handle_t socket_handle, int cmd, int val); +int network_socket_select(handle_t socket_handle, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout); /** * @brief Get host address information by name diff --git a/lib/freertos/include/osdefs.h b/lib/freertos/include/osdefs.h index 8e5a95a..2dccdb1 100644 --- a/lib/freertos/include/osdefs.h +++ b/lib/freertos/include/osdefs.h @@ -335,6 +335,19 @@ typedef enum _dhcp_state DHCP_FAIL } dhcp_state_t; +#define SYS_IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ +#define SYS_IOC_VOID 0x20000000UL /* no parameters */ +#define SYS_IOC_OUT 0x40000000UL /* copy out parameters */ +#define SYS_IOC_IN 0x80000000UL /* copy in parameters */ +#define SYS_IOC_INOUT (SYS_IOC_IN | SYS_IOC_OUT) /* 0x20000000 distinguishes new & old ioctl's */ +#define SYS_IO(x, y) (SYS_IOC_VOID | ((x) << 8) | (y)) + +#define SYS_IOR(x, y, t) (SYS_IOC_OUT | (((uint32_t)sizeof(t) & SYS_IOCPARM_MASK) << 16) | ((x) << 8) | (y)) + +#define SYS_IOW(x, y, t) (SYS_IOC_IN | (((uint32_t)sizeof(t) & SYS_IOCPARM_MASK) << 16) | ((x) << 8) | (y)) + +#define SYS_FIONBIO SYS_IOW('f', 126, uint32_t) /* set/clear non-blocking i/o */ + #ifdef __cplusplus } #endif diff --git a/lib/freertos/kernel/devices.cpp b/lib/freertos/kernel/devices.cpp index 9486596..653f860 100644 --- a/lib/freertos/kernel/devices.cpp +++ b/lib/freertos/kernel/devices.cpp @@ -45,6 +45,13 @@ using namespace sys; } \ } +#define CATCH_ALL \ + catch (errno_exception & e) \ + { \ + errno = e.code(); \ + return -1; \ + } + typedef struct { object_accessor object; @@ -192,19 +199,23 @@ static void dma_add_free(); int io_read(handle_t file, uint8_t *buffer, size_t len) { - configASSERT(file >= HANDLE_OFFSET); - _file *rfile = (_file *)handles_[file - HANDLE_OFFSET]; - /* clang-format off */ - DEFINE_READ_PROXY(uart_driver) - else DEFINE_READ_PROXY(i2c_device_driver) - else DEFINE_READ_PROXY(spi_device_driver) - else DEFINE_READ_PROXY(filesystem_file) - else DEFINE_READ_PROXY(network_socket) - else + try { - return -1; + configASSERT(file >= HANDLE_OFFSET); + _file *rfile = (_file *)handles_[file - HANDLE_OFFSET]; + /* clang-format off */ + DEFINE_READ_PROXY(uart_driver) + else DEFINE_READ_PROXY(i2c_device_driver) + else DEFINE_READ_PROXY(spi_device_driver) + else DEFINE_READ_PROXY(filesystem_file) + else DEFINE_READ_PROXY(network_socket) + else + { + return -1; + } + /* clang-format on */ } - /* clang-format on */ + CATCH_ALL; } static void io_free(_file *file) @@ -273,27 +284,39 @@ int io_close(handle_t file) int io_write(handle_t file, const uint8_t *buffer, size_t len) { - configASSERT(file >= HANDLE_OFFSET); - _file *rfile = (_file *)handles_[file - HANDLE_OFFSET]; - /* clang-format off */ - DEFINE_WRITE_PROXY(uart_driver) - else DEFINE_WRITE_PROXY(i2c_device_driver) - else DEFINE_WRITE_PROXY(spi_device_driver) - else DEFINE_WRITE_PROXY(filesystem_file) - else DEFINE_WRITE_PROXY(network_socket) - else + try { - return -1; + configASSERT(file >= HANDLE_OFFSET); + _file *rfile = (_file *)handles_[file - HANDLE_OFFSET]; + /* clang-format off */ + DEFINE_WRITE_PROXY(uart_driver) + else DEFINE_WRITE_PROXY(i2c_device_driver) + else DEFINE_WRITE_PROXY(spi_device_driver) + else DEFINE_WRITE_PROXY(filesystem_file) + else DEFINE_WRITE_PROXY(network_socket) + else + { + return -1; + } + /* clang-format on */ } - /* clang-format on */ + CATCH_ALL; } int io_control(handle_t file, uint32_t control_code, const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len) { - _file *rfile = (_file *)handles_[file - HANDLE_OFFSET]; - DEFINE_CONTROL_PROXY(custom) - - return -1; + try + { + configASSERT(file >= HANDLE_OFFSET); + _file *rfile = (_file *)handles_[file - HANDLE_OFFSET]; + DEFINE_CONTROL_PROXY(custom) + else + { + return -1; + } + } + CATCH_ALL; + } /* Device IO Implementation Helper Macros */ diff --git a/lib/freertos/kernel/network/network.cpp b/lib/freertos/kernel/network/network.cpp index 3d3826d..d2a91aa 100644 --- a/lib/freertos/kernel/network/network.cpp +++ b/lib/freertos/kernel/network/network.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "network.h" +#include "semphr.h" #include "FreeRTOS.h" #include "devices.h" #include "kernel/driver_impl.hpp" @@ -26,9 +27,11 @@ #include #include #include + using namespace sys; #define MAX_DHCP_TRIES 5 +#define NETIF_GUARD_BLOCK_TIME (250 ) int network_init() { @@ -43,7 +46,7 @@ public: : adapter_(std::move(adapter)) { ip4_addr_t ipaddr, netmask, gw; - completion_event_ = xSemaphoreCreateCounting(20, 0); + completion_event_ = xSemaphoreCreateBinary(); IP4_ADDR(&ipaddr, ip_address.data[0], ip_address.data[1], ip_address.data[2], ip_address.data[3]); IP4_ADDR(&netmask, net_mask.data[0], net_mask.data[1], net_mask.data[2], net_mask.data[3]); @@ -60,7 +63,7 @@ public: netif_set_up(&netif_); TaskHandle_t h; - auto ret = xTaskCreate(poll_thread, "poll", 10240, this, 3, &h); + auto ret = xTaskCreate(poll_thread, "poll", 4096*8, this, 3, &h); configASSERT(ret == pdTRUE); } else @@ -206,7 +209,7 @@ private: static void ethernetif_input(struct netif *netif) { - struct pbuf *p; + struct pbuf *p = NULL; /* move received packet into a new pbuf */ p = low_level_input(netif); @@ -249,10 +252,10 @@ private: #if LWIP_IPV6 && LWIP_IPV6_MLD /* - * For hardware/netifs that implement MAC filtering. - * All-nodes link-local is handled by default, so we must let the hardware know - * to allow multicast packets in. - * Should set mld_mac_filter previously. */ + * For hardware/netifs that implement MAC filtering. + * All-nodes link-local is handled by default, so we must let the hardware know + * to allow multicast packets in. + * Should set mld_mac_filter previously. */ if (netif->mld_mac_filter != NULL) { ip6_addr_t ip6_allnodes_ll; @@ -267,115 +270,135 @@ private: static struct pbuf *low_level_input(struct netif *netif) { + static xSemaphoreHandle xRxSemaphore = NULL; auto ðnetif = *reinterpret_cast(netif->state); auto &adapter = ethnetif.adapter_; - struct pbuf *p, *q; + struct pbuf *p = NULL, *q = NULL; u16_t len; - - /* Obtain the size of the packet and put it into the "len" variable. */ - len = adapter->begin_receive(); - -#if ETH_PAD_SIZE - len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ -#endif - - /* We allocate a pbuf chain of pbufs from the pool. */ - p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - - if (p != NULL) + if (xRxSemaphore == NULL) { + vSemaphoreCreateBinary (xRxSemaphore); + } -#if ETH_PAD_SIZE - pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */ -#endif + if (xSemaphoreTake(xRxSemaphore, NETIF_GUARD_BLOCK_TIME)) + { + /* Obtain the size of the packet and put it into the "len" variable. */ + len = adapter->begin_receive(); - /* We iterate over the pbuf chain until we have read the entire - * packet into the pbuf. */ - for (q = p; q != NULL; q = q->next) + #if ETH_PAD_SIZE + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ + #endif + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + if (p != NULL) { - /* Read enough bytes to fill this pbuf in the chain. The - * available data in the pbuf is given by the q->len - * variable. - * This does not necessarily have to be a memcpy, you can also preallocate - * pbufs for a DMA-enabled MAC and after receiving truncate it to the - * actually received size. In this case, ensure the tot_len member of the - * pbuf is the sum of the chained pbuf len members. - */ - adapter->receive({ (uint8_t *)q->payload, q->len }); - } - adapter->end_receive(); + #if ETH_PAD_SIZE + pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */ + #endif - MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); - if (((u8_t *)p->payload)[0] & 1) - { - /* broadcast or multicast packet*/ - MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); + /* We iterate over the pbuf chain until we have read the entire + * packet into the pbuf. */ + for (q = p; q != NULL; q = q->next) + { + /* Read enough bytes to fill this pbuf in the chain. The + * available data in the pbuf is given by the q->len + * variable. + * This does not necessarily have to be a memcpy, you can also preallocate + * pbufs for a DMA-enabled MAC and after receiving truncate it to the + * actually received size. In this case, ensure the tot_len member of the + * pbuf is the sum of the chained pbuf len members. + */ + adapter->receive({ (uint8_t *)q->payload, q->len }); + } + + adapter->end_receive(); + + MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); + if (((u8_t *)p->payload)[0] & 1) + { + /* broadcast or multicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); + } + else + { + /* unicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifinucastpkts); + } + #if ETH_PAD_SIZE + pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ + #endif + + LINK_STATS_INC(link.recv); } else { - /* unicast packet*/ - MIB2_STATS_NETIF_INC(netif, ifinucastpkts); + adapter->end_receive(); + + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + MIB2_STATS_NETIF_INC(netif, ifindiscards); } -#if ETH_PAD_SIZE - pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ -#endif - - LINK_STATS_INC(link.recv); + xSemaphoreGive(xRxSemaphore); } - else - { - adapter->end_receive(); - - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(netif, ifindiscards); - } - return p; } static err_t low_level_output(struct netif *netif, struct pbuf *p) { + static xSemaphoreHandle xTxSemaphore = NULL; auto ðnetif = *reinterpret_cast(netif->state); auto &adapter = ethnetif.adapter_; struct pbuf *q; - adapter->begin_send(p->tot_len); - -#if ETH_PAD_SIZE - pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */ -#endif - - for (q = p; q != NULL; q = q->next) + if (xTxSemaphore == NULL) { - /* Send the data from the pbuf to the interface, one pbuf at a - time. The size of the data in each pbuf is kept in the ->len - variable. */ - adapter->send({ (uint8_t *)q->payload, q->len }); + xTxSemaphore = xSemaphoreCreateMutex(); } - adapter->end_send(); - - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); - if (((u8_t *)p->payload)[0] & 1) + if (xTxSemaphore != NULL) { - /* broadcast or multicast packet*/ - MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); + if (xSemaphoreTake(xTxSemaphore, NETIF_GUARD_BLOCK_TIME)) + { + adapter->begin_send(p->tot_len); + + #if ETH_PAD_SIZE + pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */ + #endif + + for (q = p; q != NULL; q = q->next) + { + /* Send the data from the pbuf to the interface, one pbuf at a + time. The size of the data in each pbuf is kept in the ->len + variable. */ + adapter->send({ (uint8_t *)q->payload, q->len }); + } + + adapter->end_send(); + + MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); + if (((u8_t *)p->payload)[0] & 1) + { + /* broadcast or multicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); + } + else + { + /* unicast packet */ + MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); + } + /* increase ifoutdiscards or ifouterrors on error */ + + #if ETH_PAD_SIZE + pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ + #endif + + LINK_STATS_INC(link.xmit); + xSemaphoreGive(xTxSemaphore); + } } - else - { - /* unicast packet */ - MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); - } - /* increase ifoutdiscards or ifouterrors on error */ - -#if ETH_PAD_SIZE - pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ -#endif - - LINK_STATS_INC(link.xmit); - return ERR_OK; } diff --git a/lib/freertos/kernel/network/socket.cpp b/lib/freertos/kernel/network/socket.cpp index 9b78b0d..e31ecc9 100644 --- a/lib/freertos/kernel/network/socket.cpp +++ b/lib/freertos/kernel/network/socket.cpp @@ -17,6 +17,7 @@ #include "kernel/driver_impl.hpp" #include "network.h" #include +#include #include using namespace sys; @@ -24,7 +25,9 @@ using namespace sys; static void check_lwip_error(int result) { if (result < 0) - throw std::runtime_error(strerror(errno)); + { + throw errno_exception(strerror(errno), errno); + } } static void to_lwip_sockaddr(sockaddr_in &addr, const socket_address_t &socket_addr) @@ -104,6 +107,10 @@ public: lwip_close(sock_); } + virtual void install() override + { + } + virtual object_accessor accept(socket_address_t *remote_address) override { object_ptr socket(std::in_place, new k_network_socket()); @@ -260,6 +267,25 @@ public: return ret; } + virtual int fcntl(int cmd, int val) override + { + auto ret = lwip_fcntl(sock_, cmd, val); + check_lwip_error(ret); + return ret; + } + + virtual void select(fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) override + { + check_lwip_error(lwip_select(sock_ + 1, readset, writeset, exceptset, timeout)); + } + + virtual int control(uint32_t control_code, gsl::span write_buffer, gsl::span read_buffer) override + { + int val = *reinterpret_cast(write_buffer.data()); + check_lwip_error(lwip_ioctl(sock_, (unsigned int)control_code, &val)); + return 0; + } + private: k_network_socket() : sock_(0) @@ -276,7 +302,11 @@ private: auto f = obj.as(); #define CATCH_ALL \ - catch (...) { return -1; } + catch (errno_exception &e) \ + { \ + errno = e.code(); \ + return -1; \ + } #define CHECK_ARG(x) \ if (!x) \ @@ -411,6 +441,29 @@ int network_socket_receive_from(handle_t socket_handle, uint8_t *data, size_t le CATCH_ALL; } +int network_socket_fcntl(handle_t socket_handle, int cmd, int val) +{ + try + { + SOCKET_ENTRY; + + return f->fcntl(cmd, val); + } + CATCH_ALL; +} + +int network_socket_select(int socket_handle, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) +{ + try + { + SOCKET_ENTRY; + + f->select(readset, writeset, exceptset, timeout); + return 0; + } + CATCH_ALL; +} + int network_socket_addr_parse(const char *ip_addr, int port, uint8_t *socket_addr) { try diff --git a/lib/freertos/tasks.c b/lib/freertos/tasks.c index ac5d965..4f1e44b 100644 --- a/lib/freertos/tasks.c +++ b/lib/freertos/tasks.c @@ -202,9 +202,9 @@ configIDLE_TASK_NAME in FreeRTOSConfig.h. */ UBaseType_t uxTopPriority; \ \ /* Find the highest priority list that contains ready tasks. */ \ - portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ - configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ - listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority[uxPsrId] ); \ + configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[uxPsrId][ uxTopPriority ] ) ) > 0 ); \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB[uxPsrId], &( pxReadyTasksLists[uxPsrId][ uxTopPriority ] ) ); \ } /* taskSELECT_HIGHEST_PRIORITY_TASK() */ /*-----------------------------------------------------------*/ @@ -214,9 +214,9 @@ configIDLE_TASK_NAME in FreeRTOSConfig.h. */ or suspended list then it won't be in a ready list. */ #define taskRESET_READY_PRIORITY( uxPriority ) \ { \ - if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[uxPsrId][ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \ { \ - portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ + portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority[uxPsrId] ) ); \ } \ } @@ -1108,7 +1108,7 @@ void vAddNewTaskToCurrentReadyList(TaskHandle_t pxNewTaskHandle) #if ( configUSE_TRACE_FACILITY == 1 ) { /* Add a counter into the TCB for tracing only. */ - pxNewTCB->uxTCBNumber = uxTaskNumber; + pxNewTCB->uxTCBNumber = uxTaskNumber[uxPsrId]; } #endif /* configUSE_TRACE_FACILITY */ traceTASK_CREATE( pxNewTCB ); @@ -1979,7 +1979,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); pxIdleTaskStackBuffer, pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ - if( xIdleTaskHandle != NULL ) + if( xIdleTaskHandle[uxPsrId] != NULL ) { xReturn = pdPASS; } @@ -2073,7 +2073,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); /* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0, meaning xIdleTaskHandle is not used anywhere else. */ - ( void ) xIdleTaskHandle; + ( void ) xIdleTaskHandle[uxPsrId]; } /*-----------------------------------------------------------*/ @@ -2412,7 +2412,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); { UBaseType_t uxQueue = configMAX_PRIORITIES; TCB_t* pxTCB; - + UBaseType_t uxPsrId = uxPortGetProcessorId(); /* Task names will be truncated to configMAX_TASK_NAME_LEN - 1 bytes. */ configASSERT( strlen( pcNameToQuery ) < configMAX_TASK_NAME_LEN ); @@ -2422,7 +2422,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); do { uxQueue--; - pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) &( pxReadyTasksLists[ uxQueue ] ), pcNameToQuery ); + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) &( pxReadyTasksLists[uxPsrId][ uxQueue ] ), pcNameToQuery ); if( pxTCB != NULL ) { @@ -2435,12 +2435,12 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); /* Search the delayed lists. */ if( pxTCB == NULL ) { - pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxDelayedTaskList, pcNameToQuery ); + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxDelayedTaskList[uxPsrId], pcNameToQuery ); } if( pxTCB == NULL ) { - pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pcNameToQuery ); + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList[uxPsrId], pcNameToQuery ); } #if ( INCLUDE_vTaskSuspend == 1 ) @@ -2448,7 +2448,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); if( pxTCB == NULL ) { /* Search the suspended list. */ - pxTCB = prvSearchForNameWithinSingleList( &xSuspendedTaskList, pcNameToQuery ); + pxTCB = prvSearchForNameWithinSingleList( &xSuspendedTaskList[uxPsrId], pcNameToQuery ); } } #endif @@ -2458,7 +2458,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); if( pxTCB == NULL ) { /* Search the deleted list. */ - pxTCB = prvSearchForNameWithinSingleList( &xTasksWaitingTermination, pcNameToQuery ); + pxTCB = prvSearchForNameWithinSingleList( &xTasksWaitingTermination[uxPsrId], pcNameToQuery ); } } #endif @@ -2476,31 +2476,31 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) { UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES; - + UBaseType_t uxPsrId = uxPortGetProcessorId(); vTaskSuspendAll(); { /* Is there a space in the array for each task in the system? */ - if( uxArraySize >= uxCurrentNumberOfTasks ) + if( uxArraySize >= uxCurrentNumberOfTasks[uxPsrId] ) { /* Fill in an TaskStatus_t structure with information on each task in the Ready state. */ do { uxQueue--; - uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady ); + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[uxPsrId][ uxQueue ] ), eReady ); } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ /* Fill in an TaskStatus_t structure with information on each task in the Blocked state. */ - uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked ); - uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked ); + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList[uxPsrId], eBlocked ); + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList[uxPsrId], eBlocked ); #if( INCLUDE_vTaskDelete == 1 ) { /* Fill in an TaskStatus_t structure with information on each task that has been deleted but not yet cleaned up. */ - uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted ); + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination[uxPsrId], eDeleted ); } #endif @@ -2508,7 +2508,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); { /* Fill in an TaskStatus_t structure with information on each task in the Suspended state. */ - uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended ); + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList[uxPsrId], eSuspended ); } #endif @@ -2549,10 +2549,11 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); TaskHandle_t xTaskGetIdleTaskHandle( void ) { + UBaseType_t uxPsrId = uxPortGetProcessorId(); /* If xTaskGetIdleTaskHandle() is called before the scheduler has been started, then xIdleTaskHandle will be NULL. */ - configASSERT( ( xIdleTaskHandle != NULL ) ); - return xIdleTaskHandle; + configASSERT( ( xIdleTaskHandle[uxPsrId] != NULL ) ); + return xIdleTaskHandle[uxPsrId]; } #endif /* INCLUDE_xTaskGetIdleTaskHandle */ @@ -2942,9 +2943,9 @@ void vTaskSwitchContext( void ) #if ( configGENERATE_RUN_TIME_STATS == 1 ) { #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE - portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime[uxPsrId] ); #else - ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + ulTotalRunTime[uxPsrId] = portGET_RUN_TIME_COUNTER_VALUE(); #endif /* Add the amount of time the task has been running to the @@ -2954,15 +2955,15 @@ void vTaskSwitchContext( void ) overflows. The guard against negative values is to protect against suspect run time stat counter implementations - which are provided by the application, not the kernel. */ - if( ulTotalRunTime > ulTaskSwitchedInTime ) + if( ulTotalRunTime[uxPsrId] > ulTaskSwitchedInTime[uxPsrId] ) { - pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); + pxCurrentTCB[uxPsrId]->ulRunTimeCounter += ( ulTotalRunTime[uxPsrId] - ulTaskSwitchedInTime[uxPsrId] ); } else { mtCOVERAGE_TEST_MARKER(); } - ulTaskSwitchedInTime = ulTotalRunTime; + ulTaskSwitchedInTime[uxPsrId] = ulTotalRunTime[uxPsrId]; } #endif /* configGENERATE_RUN_TIME_STATS */ @@ -3055,7 +3056,7 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xIte xTicksToWait = portMAX_DELAY; } - traceTASK_DELAY_UNTIL( ( xTickCount + xTicksToWait ) ); + traceTASK_DELAY_UNTIL( ( xTickCount[uxPsrId] + xTicksToWait ) ); prvAddCurrentTaskToDelayedList( xTicksToWait, xWaitIndefinitely ); } @@ -3513,6 +3514,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions ) { TCB_t *pxTCB; + UBaseType_t uxPsrId = uxPortGetProcessorId(); /* If null is passed in here then we are modifying the MPU settings of the calling task. */ @@ -3592,7 +3594,7 @@ static void prvCheckTasksWaitingTermination( void ) void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) { TCB_t *pxTCB; - + UBaseType_t uxPsrId = uxPortGetProcessorId(); /* xTask is NULL then get the state of the calling task. */ pxTCB = prvGetTCBFromHandle( xTask ); @@ -3627,7 +3629,7 @@ static void prvCheckTasksWaitingTermination( void ) state is just set to whatever is passed in. */ if( eState != eInvalid ) { - if( pxTCB == pxCurrentTCB ) + if( pxTCB == pxCurrentTCB[uxPsrId] ) { pxTaskStatus->eCurrentState = eRunning; } @@ -3869,7 +3871,7 @@ UBaseType_t uxPsrId = uxPortGetProcessorId(); { BaseType_t xReturn; - if( xSchedulerRunning == pdFALSE ) + if( xSchedulerRunning[uxPortGetProcessorId()] == pdFALSE ) { xReturn = taskSCHEDULER_NOT_STARTED; } @@ -4270,7 +4272,7 @@ uint32_t mstatus_t = 0; TaskStatus_t *pxTaskStatusArray; volatile UBaseType_t uxArraySize, x; char cStatus; - + UBaseType_t uxPsrId = uxPortGetProcessorId(); /* * PLEASE NOTE: * @@ -4301,12 +4303,12 @@ uint32_t mstatus_t = 0; /* Take a snapshot of the number of tasks in case it changes while this function is executing. */ - uxArraySize = uxCurrentNumberOfTasks; + uxArraySize = uxCurrentNumberOfTasks[uxPsrId]; /* Allocate an array index for each task. NOTE! if configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will equate to NULL. */ - pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks[uxPsrId] * sizeof( TaskStatus_t ) ); if( pxTaskStatusArray != NULL ) { @@ -4368,7 +4370,7 @@ uint32_t mstatus_t = 0; TaskStatus_t *pxTaskStatusArray; volatile UBaseType_t uxArraySize, x; uint32_t ulTotalTime, ulStatsAsPercentage; - + UBaseType_t uxPsrId = uxPortGetProcessorId(); #if( configUSE_TRACE_FACILITY != 1 ) { #error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats(). @@ -4405,12 +4407,12 @@ uint32_t mstatus_t = 0; /* Take a snapshot of the number of tasks in case it changes while this function is executing. */ - uxArraySize = uxCurrentNumberOfTasks; + uxArraySize = uxCurrentNumberOfTasks[uxPsrId]; /* Allocate an array index for each task. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will equate to NULL. */ - pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks[uxPsrId] * sizeof( TaskStatus_t ) ); if( pxTaskStatusArray != NULL ) { @@ -5107,24 +5109,24 @@ const TickType_t xConstTickCount = xTickCount[uxPsrId]; xTimeToWake = xConstTickCount + xTicksToWait; /* The list item will be inserted in wake time order. */ - listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB[uxPsrId]->xStateListItem ), xTimeToWake ); if( xTimeToWake < xConstTickCount ) { /* Wake time has overflowed. Place this item in the overflow list. */ - vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + vListInsert( pxOverflowDelayedTaskList[uxPsrId], &( pxCurrentTCB[uxPsrId]->xStateListItem ) ); } else { /* The wake time has not overflowed, so the current block list is used. */ - vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + vListInsert( pxDelayedTaskList[uxPsrId], &( pxCurrentTCB[uxPsrId]->xStateListItem ) ); /* If the task entering the blocked state was placed at the head of the list of blocked tasks then xNextTaskUnblockTime needs to be updated too. */ - if( xTimeToWake < xNextTaskUnblockTime ) + if( xTimeToWake < xNextTaskUnblockTime[uxPsrId] ) { - xNextTaskUnblockTime = xTimeToWake; + xNextTaskUnblockTime[uxPsrId] = xTimeToWake; } else { diff --git a/lib/posix/include/sys/ioctl.h b/lib/posix/include/sys/ioctl.h new file mode 100644 index 0000000..f85f145 --- /dev/null +++ b/lib/posix/include/sys/ioctl.h @@ -0,0 +1,51 @@ +/* Copyright 2018 Canaan Inc. + * + * 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. + */ + +#ifndef _POSIX_SYS_IOCTL_H +#define _POSIX_SYS_IOCTL_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ +#define IOC_VOID 0x20000000UL /* no parameters */ +#define IOC_OUT 0x40000000UL /* copy out parameters */ +#define IOC_IN 0x80000000UL /* copy in parameters */ +#define IOC_INOUT (IOC_IN | IOC_OUT) /* 0x20000000 distinguishes new & old ioctl's */ +#define _IO(x, y) (IOC_VOID | ((x) << 8) | (y)) + +#define _IOR(x, y, t) (IOC_OUT | (((unsigned int)sizeof(t) & IOCPARM_MASK) << 16) | ((x) << 8) | (y)) + +#define _IOW(x, y, t) (IOC_IN | (((unsigned int)sizeof(t) & IOCPARM_MASK) << 16) | ((x) << 8) | (y)) + +#ifndef FIONREAD +#define FIONREAD _IOR('f', 127, unsigned int) /* get # bytes to read */ +#endif +#ifndef FIONBIO +#define FIONBIO _IOW('f', 126, unsigned int) /* set/clear non-blocking i/o */ +#endif + +int ioctl(int handle, unsigned int cmd, void *argp); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/lib/posix/ioctl.cpp b/lib/posix/ioctl.cpp new file mode 100644 index 0000000..b1b262a --- /dev/null +++ b/lib/posix/ioctl.cpp @@ -0,0 +1,46 @@ +/* Copyright 2018 Canaan Inc. + * + * 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 "sys/ioctl.h" +#include "utils.h" +#include +#include +#include +#include + +using namespace sys; + +#define CATCH_ALL \ + catch (errno_exception &e) \ + { \ + errno = e.code(); \ + return -1; \ + } + +int ioctl(int handle, unsigned int cmd, void *argp) +{ + try + { + auto &obj = system_handle_to_object(handle); \ + configASSERT(obj.is()); \ + auto f = obj.as(); + + const int val = *(int *)argp; + f->control((uint32_t)cmd, { (const uint8_t *)&val, 4L }, { NULL, 0L }); + + return 0; + } + CATCH_ALL; +} + diff --git a/lib/posix/socket.cpp b/lib/posix/socket.cpp index 38e9673..66c676d 100644 --- a/lib/posix/socket.cpp +++ b/lib/posix/socket.cpp @@ -17,6 +17,7 @@ #include #include #include +#include using namespace sys; @@ -25,8 +26,12 @@ using namespace sys; configASSERT(obj.is()); \ auto f = obj.as(); -#define CATCH_ALL \ - catch (...) { return -1; } +#define CATCH_ALL \ + catch (errno_exception & e) \ + { \ + errno = e.code(); \ + return -1; \ + } #define CHECK_ARG(x) \ if (!x) \ @@ -279,3 +284,16 @@ int sendto(int socket, const void *data, size_t size, int flags, const struct so } CATCH_ALL; } + +int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) +{ + try + { + int socket = maxfdp1 - 1; + SOCKET_ENTRY; + + f->select(readset, writeset, exceptset, timeout); + return 0; + } + CATCH_ALL; +} diff --git a/third_party/lwip/src/api/sockets.c b/third_party/lwip/src/api/sockets.c index 0fb83a1..8a13451 100644 --- a/third_party/lwip/src/api/sockets.c +++ b/third_party/lwip/src/api/sockets.c @@ -522,14 +522,14 @@ alloc_socket(struct netconn *newconn, int accepted) after having marked it as used. */ SYS_ARCH_UNPROTECT(lev); sockets[i].lastdata.pbuf = NULL; -#if LWIP_SOCKET_SELECT +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL LWIP_ASSERT("sockets[i].select_waiting == 0", sockets[i].select_waiting == 0); sockets[i].rcvevent = 0; /* TCP sendbuf is empty, but the socket is not yet writable until connected * (unless it has been created by accept()). */ sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); sockets[i].errevent = 0; -#endif /* LWIP_SOCKET_SELECT */ +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ return i + LWIP_SOCKET_OFFSET; } SYS_ARCH_UNPROTECT(lev); @@ -1305,7 +1305,7 @@ lwip_recvmsg(int s, struct msghdr *message, int flags) if ((message->msg_iov[i].iov_base == NULL) || ((ssize_t)message->msg_iov[i].iov_len <= 0) || ((size_t)(ssize_t)message->msg_iov[i].iov_len != message->msg_iov[i].iov_len) || ((ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len) <= 0)) { - sock_set_errno(sock, ERR_VAL); + sock_set_errno(sock, err_to_errno(ERR_VAL)); done_socket(sock); return -1; } @@ -2304,7 +2304,6 @@ lwip_poll_dec_sockets_used(struct pollfd *fds, nfds_t nfds) /* Go through each struct pollfd in the array. */ for (fdi = 0; fdi < nfds; fdi++) { struct lwip_sock *sock = tryget_socket_unconn_nouse(fds[fdi].fd); - LWIP_ASSERT("socket gone at the end of select", sock != NULL); if (sock != NULL) { done_socket(sock); } @@ -3741,7 +3740,7 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ } int -lwip_ioctl(int s, long cmd, void *argp) +lwip_ioctl(int s, unsigned int cmd, void *argp) { struct lwip_sock *sock = get_socket(s); u8_t val; @@ -3808,7 +3807,7 @@ lwip_ioctl(int s, long cmd, void *argp) #endif /* LWIP_SO_RCVBUF */ #endif /* LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE */ - case (long)FIONBIO: + case FIONBIO: val = 0; if (argp && *(int *)argp) { val = 1; diff --git a/third_party/lwip/src/core/ipv4/ip4.c b/third_party/lwip/src/core/ipv4/ip4.c index ed8ebe3..26c26a9 100644 --- a/third_party/lwip/src/core/ipv4/ip4.c +++ b/third_party/lwip/src/core/ipv4/ip4.c @@ -214,7 +214,7 @@ ip4_route(const ip4_addr_t *dest) #endif /* !LWIP_SINGLE_NETIF */ if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) || - ip4_addr_isany_val(*netif_ip4_addr(netif_default))) { + ip4_addr_isany_val(*netif_ip4_addr(netif_default)) || ip4_addr_isloopback(dest)) { /* No matching netif found and default netif is not usable. If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */ LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", diff --git a/third_party/lwip/src/core/tcp.c b/third_party/lwip/src/core/tcp.c index dcf2495..bd7d64e 100644 --- a/third_party/lwip/src/core/tcp.c +++ b/third_party/lwip/src/core/tcp.c @@ -583,6 +583,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset) tcp_free(pcb); } else { int send_rst = 0; + u16_t local_port = 0; enum tcp_state last_state; seqno = pcb->snd_nxt; ackno = pcb->rcv_nxt; @@ -597,6 +598,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset) } } else { send_rst = reset; + local_port = pcb->local_port; TCP_PCB_REMOVE_ACTIVE(pcb); } if (pcb->unacked != NULL) { @@ -613,7 +615,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset) tcp_backlog_accepted(pcb); if (send_rst) { LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); - tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); + tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port); } last_state = pcb->state; tcp_free(pcb); @@ -966,6 +968,7 @@ void tcp_recved(struct tcp_pcb *pcb, u16_t len) { u32_t wnd_inflation; + tcpwnd_size_t rcv_wnd; LWIP_ASSERT_CORE_LOCKED(); @@ -975,19 +978,13 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len) LWIP_ASSERT("don't call tcp_recved for listen-pcbs", pcb->state != LISTEN); - pcb->rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len); - if (pcb->rcv_wnd > TCP_WND_MAX(pcb)) { + rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len); + if ((rcv_wnd > TCP_WND_MAX(pcb)) || (rcv_wnd < pcb->rcv_wnd)) { + /* window got too big or tcpwnd_size_t overflow */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: window got too big or tcpwnd_size_t overflow\n")); pcb->rcv_wnd = TCP_WND_MAX(pcb); - } else if (pcb->rcv_wnd == 0) { - /* rcv_wnd overflowed */ - if (TCP_STATE_IS_CLOSING(pcb->state)) { - /* In passive close, we allow this, since the FIN bit is added to rcv_wnd - by the stack itself, since it is not mandatory for an application - to call tcp_recved() for the FIN bit, but e.g. the netconn API does so. */ - pcb->rcv_wnd = TCP_WND_MAX(pcb); - } else { - LWIP_ASSERT("tcp_recved: len wrapped rcv_wnd\n", 0); - } + } else { + pcb->rcv_wnd = rcv_wnd; } wnd_inflation = tcp_update_rcv_ann_wnd(pcb); @@ -1219,6 +1216,7 @@ tcp_slowtmr_start: LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); if (pcb->last_timer == tcp_timer_ctr) { /* skip this pcb, we have already processed it */ + prev = pcb; pcb = pcb->next; continue; } diff --git a/third_party/lwip/src/include/lwip/opt.h b/third_party/lwip/src/include/lwip/opt.h index 71daa85..b4ac56e 100644 --- a/third_party/lwip/src/include/lwip/opt.h +++ b/third_party/lwip/src/include/lwip/opt.h @@ -1290,7 +1290,7 @@ * an upper limit on the MSS advertised by the remote host. */ #if !defined TCP_MSS || defined __DOXYGEN__ -#define TCP_MSS 536 +#define TCP_MSS 1536 #endif /** @@ -1763,7 +1763,7 @@ * sys_thread_new() when the thread is created. */ #if !defined TCPIP_THREAD_PRIO || defined __DOXYGEN__ -#define TCPIP_THREAD_PRIO 1 +#define TCPIP_THREAD_PRIO 2 #endif /** diff --git a/third_party/lwip/src/include/lwip/sockets.h b/third_party/lwip/src/include/lwip/sockets.h index d70d36c..455b4af 100644 --- a/third_party/lwip/src/include/lwip/sockets.h +++ b/third_party/lwip/src/include/lwip/sockets.h @@ -407,27 +407,27 @@ typedef struct ipv6_mreq { #define IOC_INOUT (IOC_IN|IOC_OUT) /* 0x20000000 distinguishes new & old ioctl's */ -#define _IO(x,y) ((long)(IOC_VOID|((x)<<8)|(y))) +#define _IO(x,y) ((unsigned int)(IOC_VOID|((x)<<8)|(y))) -#define _IOR(x,y,t) ((long)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))) +#define _IOR(x,y,t) ((unsigned int)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))) -#define _IOW(x,y,t) ((long)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))) +#define _IOW(x,y,t) ((unsigned int)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))) #endif /* !defined(FIONREAD) || !defined(FIONBIO) */ #ifndef FIONREAD -#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */ +#define FIONREAD _IOR('f', 127, unsigned int) /* get # bytes to read */ #endif #ifndef FIONBIO -#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */ +#define FIONBIO _IOW('f', 126, unsigned int) /* set/clear non-blocking i/o */ #endif /* Socket I/O Controls: unimplemented */ #ifndef SIOCSHIWAT -#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */ -#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */ -#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */ -#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */ -#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */ +#define SIOCSHIWAT _IOW('s', 0, unsigned int) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, unsigned int) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, unsigned int) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, unsigned int) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, unsigned int) /* at oob mark? */ #endif /* commands for fnctl */ @@ -603,7 +603,7 @@ int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptse #if LWIP_SOCKET_POLL int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout); #endif -int lwip_ioctl(int s, long cmd, void *argp); +int lwip_ioctl(int s, unsigned int cmd, void *argp); int lwip_fcntl(int s, int cmd, int val); const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size); int lwip_inet_pton(int af, const char *src, void *dst);