fix network driver:add select,ioctl;expand TCP packet length

fix/double
jiangxiangbing 2019-02-27 18:09:54 +08:00
parent e5fbb28a9d
commit 863d783ea0
19 changed files with 468 additions and 207 deletions

View File

@ -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<uint8_t> 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<uint8_t> 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<uint8_t> buffer)
}
rx_frames -= fifo_len;
}
vTaskExitCritical();
}
else
{
@ -355,12 +358,14 @@ int k_spi_driver::read(k_spi_device_driver &device, gsl::span<uint8_t> 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<const uint8_t> 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<const uint8_t> 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<const uint8_t> bu
}
tx_buffer_len -= fifo_len;
}
vTaskExitCritical();
}
else
{
@ -420,6 +427,7 @@ int k_spi_driver::write(k_spi_device_driver &device, gsl::span<const uint8_t> 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<const uint8_
if (rx_frames < SPI_TRANSMISSION_THRESHOLD)
{
vTaskEnterCritical();
size_t index, fifo_len;
spi_.ctrlr1 = rx_frames - 1;
spi_.ssienr = 0x01;
@ -504,6 +513,7 @@ int k_spi_driver::read_write(k_spi_device_driver &device, gsl::span<const uint8_
spi_.ser = device.chip_select_mask_;
rx_buffer_len -= fifo_len;
}
vTaskExitCritical();
}
else
{

View File

@ -312,8 +312,8 @@ public:
}
/************************************************
*** Activate DM9051 and Setup DM9051 Registers **
*************************************************/
*** Activate DM9051 and Setup DM9051 Registers **
*************************************************/
/* Clear DM9051 Set and Disable Wakeup function */
write(DM9051_NCR, NCR_DEFAULT);
/* Clear TCR Register set */
@ -348,8 +348,9 @@ public:
{
configASSERT(length <= std::numeric_limits<uint16_t>::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];
}

View File

@ -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

View File

@ -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)

View File

@ -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<network_socket> accept(socket_address_t *remote_address) = 0;
@ -424,6 +441,8 @@ public:
virtual size_t receive_from(gsl::span<uint8_t> buffer, socket_message_flag_t flags, socket_address_t *from) = 0;
virtual size_t read(gsl::span<uint8_t> buffer) = 0;
virtual size_t write(gsl::span<const uint8_t> 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[];

View File

@ -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

View File

@ -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

View File

@ -45,6 +45,13 @@ using namespace sys;
} \
}
#define CATCH_ALL \
catch (errno_exception & e) \
{ \
errno = e.code(); \
return -1; \
}
typedef struct
{
object_accessor<object_access> 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 */

View File

@ -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 <lwip/netdb.h>
#include <netif/ethernet.h>
#include <string.h>
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 &ethnetif = *reinterpret_cast<k_ethernet_interface *>(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 &ethnetif = *reinterpret_cast<k_ethernet_interface *>(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;
}

View File

@ -17,6 +17,7 @@
#include "kernel/driver_impl.hpp"
#include "network.h"
#include <lwip/sockets.h>
#include <lwip/errno.h>
#include <string.h>
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<network_socket> accept(socket_address_t *remote_address) override
{
object_ptr<k_network_socket> 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<const uint8_t> write_buffer, gsl::span<uint8_t> read_buffer) override
{
int val = *reinterpret_cast<const int *>(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<k_network_socket>();
#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

View File

@ -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
{

View File

@ -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 <stddef.h>
#include <stdint.h>
#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

46
lib/posix/ioctl.cpp Normal file
View File

@ -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 <kernel/driver_impl.hpp>
#include <network.h>
#include <string.h>
#include <sys/socket.h>
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<custom_driver>()); \
auto f = obj.as<custom_driver>();
const int val = *(int *)argp;
f->control((uint32_t)cmd, { (const uint8_t *)&val, 4L }, { NULL, 0L });
return 0;
}
CATCH_ALL;
}

View File

@ -17,6 +17,7 @@
#include <kernel/driver_impl.hpp>
#include <network.h>
#include <string.h>
#include <sys/select.h>
using namespace sys;
@ -25,8 +26,12 @@ using namespace sys;
configASSERT(obj.is<network_socket>()); \
auto f = obj.as<network_socket>();
#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;
}

View File

@ -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;

View File

@ -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",

View File

@ -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;
}

View File

@ -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
/**

View File

@ -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);