LwIP v2 support

This commit is contained in:
Our Air Quality 2017-06-06 12:47:21 +10:00
parent 1cfded6389
commit cd23acaa4a
39 changed files with 1357 additions and 664 deletions

View file

@ -1,14 +1,12 @@
# Component makefile for LWIP
LWIP_DIR = $(lwip_ROOT)lwip/src/
INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/posix $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip
INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/compat/posix $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip
# args for passing into compile rule generation
lwip_INC_DIR = # all in INC_DIRS, needed for normal operation
lwip_SRC_DIR = $(lwip_ROOT) $(LWIP_DIR)api $(LWIP_DIR)core $(LWIP_DIR)core/ipv4 $(LWIP_DIR)netif
# LWIP 1.4.1 generates a single warning so we need to disable -Werror when building it
lwip_CFLAGS = $(CFLAGS) -Wno-address
lwip_SRC_DIR = $(lwip_ROOT) $(LWIP_DIR)api $(LWIP_DIR)core $(LWIP_DIR)core/ipv4 $(LWIP_DIR)core/ipv6 $(LWIP_DIR)netif
lwip_SRC_DIR += $(LWIP_DIR)apps/*
$(eval $(call component_compile_rules,lwip))

View file

@ -37,6 +37,7 @@
* Original Author: Simon Goldschmidt
* Modified by Angus Gratton based on work by @kadamski/Espressif via esp-lwip project.
*/
#include <string.h>
#include "lwip/opt.h"
#include "lwip/def.h"
@ -44,71 +45,138 @@
#include "lwip/pbuf.h"
#include <lwip/stats.h>
#include <lwip/snmp.h>
#include "lwip/ip.h"
#include "lwip/ethip6.h"
#include "netif/etharp.h"
#include "sysparam.h"
#include "netif/ppp/pppoe.h"
/* declared in libnet80211.a */
int8_t sdk_ieee80211_output_pbuf(struct netif *ifp, struct pbuf* pb);
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 'n'
/**
* In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param netif the already initialized lwip network interface structure
* for this ethernetif
*/
static void
low_level_init(struct netif *netif)
{
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* maximum transfer unit */
netif->mtu = 1500;
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6;
/* Do whatever else is needed to initialize interface. */
}
/**
* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become available since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf))
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
/*
* Note the pbuf reference count is generally one here, but not always. For
* example a buffer that had been queued by etharp_query() would have had
* its reference count increased to two, and the caller will free it on that
* return path.
*/
for(q = p; q != NULL; q = q->next) {
sdk_ieee80211_output_pbuf(netif, q);
}
/* If the pbuf does not have contiguous data, or there is not enough room
* for the link layer header, or there are multiple pbufs in the chain then
* clone a pbuf to output. */
if ((p->type_internal & PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS) == 0 ||
(u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF + PBUF_LINK_ENCAPSULATION_HLEN ||
p->next) {
struct pbuf *q = pbuf_clone(PBUF_RAW_TX, PBUF_RAM, p);
if (q == NULL) {
return ERR_MEM;
}
sdk_ieee80211_output_pbuf(netif, q);
/* The sdk will pbuf_ref the pbuf before returning and free it later
* when it has been sent so free the link to it here. */
pbuf_free(q);
} else {
/* The SDK modifies the eth_hdr, well the first 12 bytes of it at least,
* but otherwise leaves the payload unmodified so it can be reused by
* the caller. The only paths that appear to reuse the pbuf are in
* tcp_out for re-transmission of TCP segments, and these paths check
* that the number of references has returned to one before reusing the
* pbuf.
*/
sdk_ieee80211_output_pbuf(netif, p);
}
LINK_STATS_INC(link.xmit);
return ERR_OK;
LINK_STATS_INC(link.xmit);
return ERR_OK;
}
err_t ethernetif_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
// don't touch netif->state here, the field is used internally in the ESP SDK layers
netif->name[0] = 'e';
netif->name[1] = 'n';
netif->output = etharp_output;
netif->linkoutput = low_level_output;
/* low_level_init components */
netif->hwaddr_len = 6;
/* hwaddr seems to be set elsewhere, or (more likely) is set on tx by MAC layer */
netif->mtu = 1500;
netif->flags = NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
return ERR_OK;
}
/**
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* should handle the actual reception of bytes from the network
* interface. Then the type of the received packet is determined and
* the appropriate input function is called.
*
* @param netif the lwip network interface structure for this ethernetif
*/
/* called from ieee80211_deliver_data with new IP frames */
void ethernetif_input(struct netif *netif, struct pbuf *p)
{
struct eth_hdr *ethhdr = p->payload;
/* examine packet payloads ethernet header */
struct eth_hdr *ethhdr;
if (p == NULL) {
return;
}
if (p->payload == NULL) {
return;
}
if (netif == NULL) {
return;
}
ethhdr = p->payload;
switch(htons(ethhdr->type)) {
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_IPV6:
case ETHTYPE_ARP:
// case ETHTYPE_IPV6:
#if PPPOE_SUPPORT
/* PPPoE packet? */
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* full packet send to tcpip_thread to process */
if (netif->input(p, netif)!=ERR_OK)
if (netif->input(p, netif) != ERR_OK)
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
@ -122,3 +190,98 @@ void ethernetif_input(struct netif *netif, struct pbuf *p)
break;
}
}
/* Since the pbuf_type definition has changed in lwip v2 and it is used by the
* sdk when calling pbuf_alloc, the SDK libraries have been modified to rename
* their references to pbuf_alloc to _pbufalloc allowing the pbuf_type to be
* rewritten here. Doing this here keeps this hack out of the lwip code, and
* ensures that this re-writing is only applied to the sdk calls to pbuf_alloc.
*
* The only pbuf types used by the SDK are type 0 for PBUF_RAM when writing
* data, and type 2 for the received data. The receive data path references
* internal buffer objects that need to be freed with custom code so a custom
* pbuf allocation type is used for these.
*
* The pbuf_layer is now also the header offset, but the sdk calls only call
* with a value of 3 which was PBUF_RAW and is now translated to a header
* offset of zero.
*/
struct pbuf *sdk_pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) {
if (type == 0) {
LWIP_ASSERT("Unexpected sdk_pbuf_alloc layer", layer == 3 || layer == 4);
return pbuf_alloc(PBUF_RAW_TX, length, PBUF_RAM);
} else if (type == 2) {
LWIP_ASSERT("Unexpected sdk_pbuf_alloc layer", layer == 3);
return pbuf_alloc_reference(NULL, length, PBUF_ALLOC_FLAG_RX | PBUF_TYPE_ALLOC_SRC_MASK_ESP_RX);
} else {
LWIP_ASSERT("Unexpected pbuf_alloc type", 0);
for (;;);
}
}
/**
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t
ethernetif_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
/* The hwaddr is currently set by sdk_wifi_station_start or
* sdk_wifi_softap_start. */
#if LWIP_IPV6
// Where to do this???
netif_create_ip6_linklocal_address(netif, 1);
netif->ip6_autoconfig_enabled = 1;
printf("ip6 link local address %s\n", ip6addr_ntoa(netif_ip6_addr(netif, 0)));
#endif
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
char *hostname = NULL;
/* Disabled for now as there were reports of crashes here, sysparam issues */
/* sysparam_get_string("hostname", &hostname); */
if (hostname && strlen(hostname) == 0) {
free(hostname);
hostname = NULL;
}
netif->hostname = hostname;
#endif /* LWIP_NETIF_HOSTNAME */
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
// don't touch netif->state here, the field is used internally in the ESP SDK layers
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
#if LWIP_IPV4
netif->output = etharp_output;
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
netif->linkoutput = low_level_output;
/* initialize the hardware */
low_level_init(netif);
return ERR_OK;
}

View file

@ -32,36 +32,18 @@
#ifndef __ARCH_CC_H__
#define __ARCH_CC_H__
/* include ESP SDK prototypes as they're used in some LWIP routines */
#include "espressif/sdk_private.h"
/* ESP8266 SDK Interface
The lwip-esp stack is designed to be also compatible with other ESP8266 SDKs,
so we can't use our 'sdk_' prefixes there
*/
#define system_station_got_ip_set sdk_system_station_got_ip_set
#define system_pp_recycle_rx_pkt sdk_system_pp_recycle_rx_pkt
/* Include some files for defining library routines */
#include <stdio.h> /* printf, fflush, FILE */
#include <stdlib.h> /* abort */
#include <stdint.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <esp/hwrand.h>
#define ERRNO
#define BYTE_ORDER LITTLE_ENDIAN
/** @todo fix some warnings: don't use #pragma if compiling with cygwin gcc */
#ifndef __GNUC__
#include <limits.h>
#pragma warning (disable: 4244) /* disable conversion warning (implicit integer promotion!) */
#pragma warning (disable: 4127) /* conditional expression is constant */
#pragma warning (disable: 4996) /* 'strncpy' was declared deprecated */
#pragma warning (disable: 4103) /* structure packing changed by including file */
#endif
struct ip4_addr;
struct esf_buf;
void sdk_system_station_got_ip_set(struct ip4_addr *, struct ip4_addr *, struct ip4_addr *);
void sdk_system_pp_recycle_rx_pkt(struct esf_buf *);
/* Define generic types used in lwIP */
typedef uint8_t u8_t;
@ -112,4 +94,6 @@ typedef int sys_prot_t;
#define LWIP_PLATFORM_HTONS(_n) ((u16_t)((((_n) & 0xff) << 8) | (((_n) >> 8) & 0xff)))
#define LWIP_PLATFORM_HTONL(_n) ((u32_t)( (((_n) & 0xff) << 24) | (((_n) & 0xff00) << 8) | (((_n) >> 8) & 0xff00) | (((_n) >> 24) & 0xff) ))
#define LWIP_RAND() hwrand()
#endif /* __ARCH_CC_H__ */

View file

@ -32,11 +32,15 @@
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
#define LWIP_ESP 1
#define ESP_RTOS 1
#define PBUF_RSV_FOR_WLAN 1
#define EBUF_LWIP 1
#define ESP_OPEN_RTOS 1
/* See tcp.c tcp_alloc(). */
#ifndef ESP_TIMEWAIT_THRESHOLD
#define ESP_TIMEWAIT_THRESHOLD 10000
#endif
/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
* by your system, set this to 0 and include <sys/time.h> in cc.h */
#define LWIP_TIMEVAL_PRIVATE 0
/*
@ -63,6 +67,32 @@
*/
#define SMEMCPY(dst,src,len) memcpy(dst,src,len)
/*
------------------------------------
----------- Core locking -----------
------------------------------------
*/
/**
* LWIP_TCPIP_CORE_LOCKING
* Creates a global mutex that is held during TCPIP thread operations.
* Can be locked by client code to perform lwIP operations without changing
* into TCPIP thread using callbacks. See LOCK_TCPIP_CORE() and
* UNLOCK_TCPIP_CORE().
* Your system should provide mutexes supporting priority inversion to use this.
*/
#define LWIP_TCPIP_CORE_LOCKING 1
/**
* LWIP_TCPIP_CORE_LOCKING_INPUT: when LWIP_TCPIP_CORE_LOCKING is enabled,
* this lets tcpip_input() grab the mutex for input packets as well,
* instead of allocating a message and passing it to tcpip_thread.
*
* ATTENTION: this does not work when tcpip_input() is called from
* interrupt context!
*/
#define LWIP_TCPIP_CORE_LOCKING_INPUT 1
/*
------------------------------------
---------- Memory options ----------
@ -76,16 +106,20 @@
#define MEM_LIBC_MALLOC 1
/**
* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator.
* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution
* speed and usage from interrupts!
*/
* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator.
* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution
* speed (heap alloc can be much slower than pool alloc) and usage from interrupts
* (especially if your netif driver allocates PBUF_POOL pbufs for received frames
* from interrupt)!
* ATTENTION: Currently, this uses the heap for ALL pools (also for private pools,
* not only for internal pools defined in memp_std.h)!
*/
#define MEMP_MEM_MALLOC 1
/**
* MEM_ALIGNMENT: should be set to the alignment of the CPU
* 4 byte alignment -> #define MEM_ALIGNMENT 4
* 2 byte alignment -> #define MEM_ALIGNMENT 2
* 4 byte alignment -> \#define MEM_ALIGNMENT 4
* 2 byte alignment -> \#define MEM_ALIGNMENT 2
*/
#define MEM_ALIGNMENT 4
@ -100,6 +134,14 @@
---------- ARP options -------
--------------------------------
*/
/**
* LWIP_ARP==1: Enable ARP functionality.
*/
#ifndef LWIP_ARP
#define LWIP_ARP 1
#endif
/**
* ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address
* resolution. By default, only the most recent packet is queued per IP address.
@ -107,7 +149,9 @@
* startup time. Set this to 1 if you know your application sends more than one
* packet in a row to an IP address that is not in the ARP cache.
*/
#ifndef ARP_QUEUEING
#define ARP_QUEUEING 1
#endif
/*
--------------------------------
@ -119,21 +163,27 @@
* this option does not affect outgoing packet sizes, which can be controlled
* via IP_FRAG.
*/
#define IP_REASSEMBLY 0
#ifndef IP_REASSEMBLY
#define IP_REASSEMBLY 1
#endif
/**
* IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
* that this option does not affect incoming packet sizes, which can be
* controlled via IP_REASSEMBLY.
*/
#ifndef IP_FRAG
#define IP_FRAG 1
#endif
/**
* IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
* a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
* in this time, the whole packet is discarded.
*/
#ifndef IP_REASS_MAXAGE
#define IP_REASS_MAXAGE 3
#endif
/**
* IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.
@ -141,7 +191,9 @@
* PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive
* packets even if the maximum amount of fragments is enqueued for reassembly!
*/
#define IP_REASS_MAX_PBUFS 10
#ifndef IP_REASS_MAX_PBUFS
#define IP_REASS_MAX_PBUFS 2
#endif
/*
----------------------------------
@ -163,7 +215,16 @@
/**
* LWIP_DHCP==1: Enable DHCP module.
*/
#ifndef LWIP_DHCP
#define LWIP_DHCP 1
#endif
/**
* DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address.
*/
#ifndef DHCP_DOES_ARP_CHECK
#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP))
#endif
#define LWIP_DHCP_BOOTP_FILE 0
@ -174,14 +235,21 @@
*/
/*
----------------------------------
---------- SNMP options ----------
----- SNMP MIB2 support -----
----------------------------------
*/
/*
----------------------------------
---------- IGMP options ----------
----- Multicast/IGMP options -----
----------------------------------
*/
/**
* LWIP_IGMP==1: Turn on IGMP module.
*/
#ifndef LWIP_IGMP
#define LWIP_IGMP 1
#endif
/*
----------------------------------
---------- DNS options -----------
@ -191,10 +259,19 @@
* LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
* transport.
*/
#ifndef LWIP_DNS
#define LWIP_DNS 1
#endif
/** DNS maximum number of entries to maintain locally. */
#ifndef DNS_TABLE_SIZE
#define DNS_TABLE_SIZE 1
#endif
/** DNS maximum host name length supported in the name table. */
#ifndef DNS_MAX_NAME_LENGTH
#define DNS_MAX_NAME_LENGTH 128
#endif
/*
---------------------------------
@ -206,30 +283,74 @@
---------- TCP options ----------
---------------------------------
*/
/**
* TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order.
* Define to 0 if your device is low on memory.
*/
#define TCP_QUEUE_OOSEQ 0
/*
* LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all
* events (accept, sent, etc) that happen in the system.
* LWIP_CALLBACK_API==1: The PCB callback function is called directly
* for the event. This is the default.
*/
#define TCP_MSS 1460
/**
* TCP_MAXRTX: Maximum number of retransmissions of data segments.
*/
#ifndef TCP_MAXRTX
#define TCP_MAXRTX 6
#endif
/**
* TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments.
*/
#ifndef TCP_SYNMAXRTX
#define TCP_SYNMAXRTX 3
#endif
/**
* TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order.
* Define to 0 if your device is low on memory.
*/
#ifndef TCP_QUEUE_OOSEQ
#define TCP_QUEUE_OOSEQ 1
#endif
/**
* TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default,
* you might want to increase this.)
* For the receive side, this MSS is advertised to the remote side
* when opening a connection. For the transmit size, this MSS sets
* an upper limit on the MSS advertised by the remote host.
*/
#ifndef TCP_MSS
#define TCP_MSS 1460
#endif
/**
* TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb.
* Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==1.
*/
#ifndef TCP_OOSEQ_MAX_BYTES
#if TCP_OOSEQ_MAX_BYTES
#define TCP_OOSEQ_MAX_BYTES (2 * TCP_MSS)
#endif
#endif
/**
* TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb.
* Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==1.
*/
#ifndef TCP_OOSEQ_MAX_PBUFS
#if TCP_OOSEQ_MAX_PBUFS
#define TCP_OOSEQ_MAX_PBUFS 2
#endif
#endif
/**
* TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb.
*/
#ifndef TCP_LISTEN_BACKLOG
#define TCP_LISTEN_BACKLOG 1
#endif
/**
* The maximum allowed backlog for TCP listen netconns.
* This backlog is used unless another is explicitly specified.
* 0xff is the maximum (u8_t).
*/
#ifndef TCP_DEFAULT_LISTEN_BACKLOG
#define TCP_DEFAULT_LISTEN_BACKLOG 2
#endif
/*
----------------------------------
@ -237,19 +358,50 @@
----------------------------------
*/
/**
* PBUF_LINK_ENCAPSULATION_HLEN: the number of bytes that should be allocated
* for an additional encapsulation header before ethernet headers (e.g. 802.11)
*
* 1. LINK_HLEN 14Byte will be remove in WLAN layer
* 2. IEEE80211_HDR_MAX_LEN needs 40 bytes.
* 3. encryption needs exra 4 bytes ahead of actual data payload, and require
* DAddr and SAddr to be 4-byte aligned.
* 4. TRANSPORT and IP are all 20, 4 bytes aligned, nice...
* 5. LCC add 6 bytes more, We don't consider WAPI yet...
* 6. define LWIP_MEM_ALIGN to be 4 Byte aligned, pbuf struct is 16B, Only thing may be
* matter is ether_hdr is not 4B aligned.
*
* So, we need extra (40 + 4 - 14) = 30 and it's happen to be 4-Byte aligned
*
* 1. lwip
* | empty 30B | eth_hdr (14B) | payload ...|
* total: 44B ahead payload
* 2. net80211
* | max 80211 hdr, 32B | ccmp/tkip iv (8B) | sec rsv(4B) | payload ...|
* total: 40B ahead sec_rsv and 44B ahead payload
*
*/
#define PBUF_LINK_ENCAPSULATION_HLEN 36
/*
------------------------------------------------
---------- Network Interfaces options ----------
------------------------------------------------
*/
/**
* LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data
* LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname
* field.
*/
#ifndef LWIP_NETIF_HOSTNAME
#define LWIP_NETIF_HOSTNAME 1
#endif
/**
* LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data
* to be sent into one single pbuf. This is for compatibility with DMA-enabled
* MACs that do not support scatter-gather.
* Beware that this might involve CPU-memcpy before transmitting that would not
* be needed without this flag! Use this only if you need to!
*
* @todo: TCP and IP-frag do not work with this, yet:
*/
#define LWIP_NETIF_TX_SINGLE_PBUF 1
@ -275,7 +427,9 @@
* The stack size value itself is platform-dependent, but is passed to
* sys_thread_new() when the thread is created.
*/
#define TCPIP_THREAD_STACKSIZE 512 //not ok:384
#ifndef TCPIP_THREAD_STACKSIZE
#define TCPIP_THREAD_STACKSIZE 768
#endif
/**
* TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread.
@ -327,30 +481,40 @@
* LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and
* SO_SNDTIMEO processing.
*/
#ifndef LWIP_SO_SNDTIMEO
#define LWIP_SO_SNDTIMEO 1
#endif
/**
* LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and
* SO_RCVTIMEO processing.
*/
#ifndef LWIP_SO_RCVTIMEO
#define LWIP_SO_RCVTIMEO 1
#endif
/**
* LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT
* options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set
* in seconds. (does not require sockets.c, and will affect tcp.c)
*/
#ifndef LWIP_TCP_KEEPALIVE
#define LWIP_TCP_KEEPALIVE 1
#endif
/**
* LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing.
*/
#ifndef LWIP_SO_RCVBUF
#define LWIP_SO_RCVBUF 0
#endif
/**
* SO_REUSE==1: Enable SO_REUSEADDR option.
*/
#ifndef SO_REUSE
#define SO_REUSE 1
#endif
/*
----------------------------------------
@ -358,6 +522,20 @@
----------------------------------------
*/
/**
* LWIP_STATS==1: Enable statistics collection in lwip_stats.
*/
#ifndef LWIP_STATS
#define LWIP_STATS 0
#endif
/**
* LWIP_STATS_DISPLAY==1: Compile in the statistics output functions.
*/
#ifndef LWIP_STATS_DISPLAY
#define LWIP_STATS_DISPLAY 0
#endif
/*
---------------------------------
---------- PPP options ----------
@ -375,6 +553,12 @@
---------- IPv6 options ---------------
---------------------------------------
*/
/**
* LWIP_IPV6==1: Enable IPv6
*/
#ifndef LWIP_IPV6
#define LWIP_IPV6 0
#endif
/*
---------------------------------------
@ -391,11 +575,29 @@
// Uncomment this line, and set the individual debug options you want, for IP stack debug output
//#define LWIP_DEBUG
/**
* LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is
* compared against this value. If it is smaller, then debugging
* messages are written.
*/
//#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_WARNING
/**
* LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable
* debug messages of certain types.
*/
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
/**
* ETHARP_DEBUG: Enable debugging in etharp.c.
*/
#define ETHARP_DEBUG LWIP_DBG_OFF
/**
* NETIF_DEBUG: Enable debugging in netif.c.
*/
#define NETIF_DEBUG LWIP_DBG_OFF
/**
* PBUF_DEBUG: Enable debugging in pbuf.c.
*/
@ -406,50 +608,151 @@
*/
#define API_LIB_DEBUG LWIP_DBG_OFF
/**
* API_MSG_DEBUG: Enable debugging in api_msg.c.
*/
#define API_MSG_DEBUG LWIP_DBG_OFF
/**
* SOCKETS_DEBUG: Enable debugging in sockets.c.
*/
#define SOCKETS_DEBUG LWIP_DBG_OFF
/**
* ICMP_DEBUG: Enable debugging in icmp.c.
*/
#define ICMP_DEBUG LWIP_DBG_OFF
/**
* IGMP_DEBUG: Enable debugging in igmp.c.
*/
#define IGMP_DEBUG LWIP_DBG_OFF
/**
* INET_DEBUG: Enable debugging in inet.c.
*/
#define INET_DEBUG LWIP_DBG_OFF
/**
* IP_DEBUG: Enable debugging for IP.
*/
#define IP_DEBUG LWIP_DBG_OFF
/**
* IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass.
*/
#define IP_REASS_DEBUG LWIP_DBG_OFF
/**
* RAW_DEBUG: Enable debugging in raw.c.
*/
#define RAW_DEBUG LWIP_DBG_OFF
/**
* MEM_DEBUG: Enable debugging in mem.c.
*/
#define MEM_DEBUG LWIP_DBG_OFF
/**
* MEMP_DEBUG: Enable debugging in memp.c.
*/
#define MEMP_DEBUG LWIP_DBG_OFF
/**
* SYS_DEBUG: Enable debugging in sys.c.
*/
#define SYS_DEBUG LWIP_DBG_OFF
/**
* TIMERS_DEBUG: Enable debugging in timers.c.
*/
#define TIMERS_DEBUG LWIP_DBG_OFF
/**
* TCP_DEBUG: Enable debugging for TCP.
*/
#define TCP_DEBUG LWIP_DBG_OFF
/**
* TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug.
*/
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
/**
* TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit.
*/
#define TCP_FR_DEBUG LWIP_DBG_OFF
/**
* TCP_RTO_DEBUG: Enable debugging in TCP for retransmit
* timeout.
*/
#define TCP_RTO_DEBUG LWIP_DBG_OFF
/**
* TCP_CWND_DEBUG: Enable debugging for TCP congestion window.
*/
#define TCP_CWND_DEBUG LWIP_DBG_OFF
/**
* TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating.
*/
#define TCP_WND_DEBUG LWIP_DBG_OFF
/**
* TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions.
*/
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
/**
* UDP_DEBUG: Enable debugging in udp.c.
* TCP_RST_DEBUG: Enable debugging for TCP with the RST message.
*/
#define UDP_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
/**
* ICMP_DEBUG: Enable debugging in udp.c.
* TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths.
*/
#define ICMP_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
/**
* UDP_DEBUG: Enable debugging in UDP.
*/
#define UDP_DEBUG LWIP_DBG_OFF
/**
* TCPIP_DEBUG: Enable debugging in tcpip.c.
*/
#define TCPIP_DEBUG LWIP_DBG_OFF
/**
* SLIP_DEBUG: Enable debugging in slipif.c.
*/
#define SLIP_DEBUG LWIP_DBG_OFF
/**
* DHCP_DEBUG: Enable debugging in dhcp.c.
*/
#define DHCP_DEBUG LWIP_DBG_OFF
/**
* AUTOIP_DEBUG: Enable debugging in autoip.c.
*/
#define AUTOIP_DEBUG LWIP_DBG_OFF
/**
* DNS_DEBUG: Enable debugging for DNS.
*/
#define DNS_DEBUG LWIP_DBG_OFF
/**
* IP6_DEBUG: Enable debugging for IPv6.
*/
#define IP6_DEBUG LWIP_DBG_OFF
/*
--------------------------------------------------
---------- Performance tracking options ----------
--------------------------------------------------
*/
#endif /* __LWIPOPTS_H__ */

@ -1 +1 @@
Subproject commit 3cf8d514bd76e6ef77e6fa514d0ec6d96da7fd9a
Subproject commit ae317fe74dd61ab5eacf5c83dfe8f2af4795421e

View file

@ -49,17 +49,147 @@
#include "lwip/mem.h"
#include "lwip/stats.h"
extern bool esp_in_isr;
/* Based on the default xInsideISR mechanism to determine
if an ISR is running.
Doesn't support the possibility that LWIP functions are called from the NMI
handler (none are called from NMI when using current/SDK implementation.)
*/
static inline bool is_inside_isr()
/*---------------------------------------------------------------------------*
* Routine: sys_sem_new
*---------------------------------------------------------------------------*
* Description:
* Creates and returns a new semaphore. The "ucCount" argument specifies
* the initial state of the semaphore.
* NOTE: Currently this routine only creates counts of 1 or 0
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* u8_t ucCount -- Initial ucCount of semaphore (1 or 0)
* Outputs:
* sys_sem_t -- Created semaphore or 0 if could not create.
*---------------------------------------------------------------------------*/
err_t sys_sem_new(sys_sem_t *pxSemaphore, u8_t ucCount)
{
return esp_in_isr;
err_t xReturn = ERR_MEM;
vSemaphoreCreateBinary(*pxSemaphore);
if (*pxSemaphore != NULL) {
if (ucCount == 0U) {
xSemaphoreTake(*pxSemaphore, 1UL);
}
xReturn = ERR_OK;
SYS_STATS_INC_USED(sem);
} else {
SYS_STATS_INC(sem.err);
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_free
*---------------------------------------------------------------------------*
* Description:
* Deallocates a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to free
*---------------------------------------------------------------------------*/
void sys_sem_free(sys_sem_t *pxSemaphore)
{
SYS_STATS_DEC(sem.used);
vQueueDelete(*pxSemaphore);
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_signal
*---------------------------------------------------------------------------*
* Description:
* Signals (releases) a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to signal
*---------------------------------------------------------------------------*/
void sys_sem_signal(sys_sem_t *pxSemaphore)
{
xSemaphoreGive(*pxSemaphore);
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_sem_wait
*---------------------------------------------------------------------------*
* Description:
* 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 zero, the thread should be blocked until the semaphore is signalled.
*
* The return value is SYS_ARCH_TIMEOUT if the semaphore wasn't signaled
* within the specified time or any other value if it was signaled (with or
* without waiting).
*
* Notice that lwIP implements a function with a similar name,
* sys_sem_wait(), that uses the sys_arch_sem_wait() function.
* Inputs:
* sys_sem_t sem -- Semaphore to wait on
* u32_t timeout -- Number of milliseconds until timeout
* Outputs:
* u32_t -- SYS_ARCH_TIMEOUT on timeout, any other value on success
*---------------------------------------------------------------------------*/
u32_t sys_arch_sem_wait(sys_sem_t *pxSemaphore, u32_t ulTimeout)
{
u32_t ulReturn;
if (ulTimeout != 0UL) {
if (xSemaphoreTake(*pxSemaphore, ulTimeout / portTICK_PERIOD_MS) == pdTRUE) {
ulReturn = 0;
} else {
ulReturn = SYS_ARCH_TIMEOUT;
}
} else {
while (xSemaphoreTake(*pxSemaphore, portMAX_DELAY) != pdTRUE);
ulReturn = 0;
}
return ulReturn;
}
/** 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;
*pxMutex = xSemaphoreCreateMutex();
if (*pxMutex != NULL) {
xReturn = ERR_OK;
SYS_STATS_INC_USED(mutex);
} else {
xReturn = ERR_MEM;
SYS_STATS_INC(mutex.err);
}
return xReturn;
}
/** Lock a mutex
* @param mutex the mutex to lock */
void sys_mutex_lock(sys_mutex_t *pxMutex)
{
while (xSemaphoreTake(*pxMutex, portMAX_DELAY) != pdPASS);
}
/** Unlock a mutex
* @param mutex the mutex to unlock */
void sys_mutex_unlock(sys_mutex_t *pxMutex)
{
xSemaphoreGive(*pxMutex);
}
/** Delete a semaphore
* @param mutex the mutex to delete */
void sys_mutex_free(sys_mutex_t *pxMutex)
{
SYS_STATS_DEC(mutex.used);
vQueueDelete(*pxMutex);
}
/*---------------------------------------------------------------------------*
@ -72,16 +202,15 @@ static inline bool is_inside_isr()
* Outputs:
* sys_mbox_t -- Handle to new mailbox
*---------------------------------------------------------------------------*/
err_t sys_mbox_new( sys_mbox_t *pxMailBox, int iSize )
err_t sys_mbox_new(sys_mbox_t *pxMailBox, int iSize)
{
err_t xReturn = ERR_MEM;
*pxMailBox = xQueueCreate( iSize, sizeof( void * ) );
*pxMailBox = xQueueCreate(iSize, sizeof(void *));
if( *pxMailBox != NULL )
{
if (*pxMailBox != NULL) {
xReturn = ERR_OK;
SYS_STATS_INC_USED( mbox );
SYS_STATS_INC_USED(mbox);
}
return xReturn;
@ -100,25 +229,24 @@ err_t sys_mbox_new( sys_mbox_t *pxMailBox, int iSize )
* Outputs:
* sys_mbox_t -- Handle to new mailbox
*---------------------------------------------------------------------------*/
void sys_mbox_free( sys_mbox_t *pxMailBox )
void sys_mbox_free(sys_mbox_t *pxMailBox)
{
unsigned long ulMessagesWaiting;
unsigned long ulMessagesWaiting;
ulMessagesWaiting = uxQueueMessagesWaiting( *pxMailBox );
configASSERT( ( ulMessagesWaiting == 0 ) );
ulMessagesWaiting = uxQueueMessagesWaiting(*pxMailBox);
configASSERT(ulMessagesWaiting == 0);
#if SYS_STATS
{
if( ulMessagesWaiting != 0UL )
{
SYS_STATS_INC( mbox.err );
if (ulMessagesWaiting != 0UL) {
SYS_STATS_INC(mbox.err);
}
SYS_STATS_DEC( mbox.used );
SYS_STATS_DEC(mbox.used);
}
#endif /* SYS_STATS */
vQueueDelete( *pxMailBox );
vQueueDelete(*pxMailBox);
}
/*---------------------------------------------------------------------------*
@ -130,9 +258,9 @@ unsigned long ulMessagesWaiting;
* sys_mbox_t mbox -- Handle of mailbox
* void *data -- Pointer to data to post
*---------------------------------------------------------------------------*/
void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost )
void sys_mbox_post(sys_mbox_t *pxMailBox, void *pxMessageToPost)
{
while( xQueueSendToBack( *pxMailBox, &pxMessageToPost, portMAX_DELAY ) != pdTRUE );
while (xQueueSendToBack(*pxMailBox, &pxMessageToPost, portMAX_DELAY) != pdTRUE);
}
/*---------------------------------------------------------------------------*
@ -148,26 +276,13 @@ void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost )
* err_t -- ERR_OK if message posted, else ERR_MEM
* if not.
*---------------------------------------------------------------------------*/
err_t sys_mbox_trypost( sys_mbox_t *pxMailBox, void *pxMessageToPost )
err_t sys_mbox_trypost(sys_mbox_t *pxMailBox, void *pxMessageToPost)
{
err_t xReturn;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
err_t xReturn;
if( is_inside_isr() != pdFALSE )
{
xReturn = xQueueSendFromISR( *pxMailBox, &pxMessageToPost, &xHigherPriorityTaskWoken );
}
else
{
xReturn = xQueueSend( *pxMailBox, &pxMessageToPost, ( TickType_t ) 0 );
}
if( xReturn == pdPASS )
{
if (xQueueSend(*pxMailBox, &pxMessageToPost, 0)) {
xReturn = ERR_OK;
}
else
{
} else {
/* The queue was already full. */
xReturn = ERR_MEM;
SYS_STATS_INC( mbox.err );
@ -188,8 +303,8 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
* should be dropped.
*
* 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.
* SYS_ARCH_TIMEOUT if there was a timeout, any other value if a messages
* is received.
*
* Note that a function with a similar name, sys_mbox_fetch(), is
* implemented by lwIP.
@ -198,52 +313,28 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
* void **msg -- Pointer to pointer to msg received
* u32_t timeout -- Number of milliseconds until timeout
* Outputs:
* u32_t -- SYS_ARCH_TIMEOUT if timeout, else number
* of milliseconds until received.
* u32_t -- SYS_ARCH_TIMEOUT on timeout, any other value if a message has been received
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_fetch( sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut )
u32_t sys_arch_mbox_fetch(sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut)
{
void *pvDummy;
TickType_t xStartTime, xEndTime, xElapsed;
unsigned long ulReturn;
void *pvDummy;
unsigned long ulReturn;
xStartTime = xTaskGetTickCount();
if( NULL == ppvBuffer )
{
if (ppvBuffer == NULL) {
ppvBuffer = &pvDummy;
}
if( ulTimeOut != 0UL )
{
configASSERT( is_inside_isr() == ( portBASE_TYPE ) 0 );
if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), ulTimeOut/ portTICK_PERIOD_MS ) )
{
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS;
ulReturn = xElapsed;
}
else
{
if (ulTimeOut != 0UL) {
if (xQueueReceive(*pxMailBox, &(*ppvBuffer), ulTimeOut / portTICK_PERIOD_MS) == pdTRUE) {
ulReturn = 0;
} else {
/* Timed out. */
*ppvBuffer = NULL;
ulReturn = SYS_ARCH_TIMEOUT;
}
}
else
{
while( pdTRUE != xQueueReceive( *pxMailBox, &( *ppvBuffer ), portMAX_DELAY ) );
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS;
if( xElapsed == 0UL )
{
xElapsed = 1UL;
}
ulReturn = xElapsed;
} else {
while (xQueueReceive(*pxMailBox, &(*ppvBuffer), portMAX_DELAY) != pdTRUE);
ulReturn = 0;
}
return ulReturn;
@ -263,218 +354,24 @@ unsigned long ulReturn;
* u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise,
* return ERR_OK.
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_tryfetch( sys_mbox_t *pxMailBox, void **ppvBuffer )
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *pxMailBox, void **ppvBuffer)
{
void *pvDummy;
unsigned long ulReturn;
long lResult;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
void *pvDummy;
unsigned long ulReturn;
if( ppvBuffer== NULL )
{
if (ppvBuffer== NULL) {
ppvBuffer = &pvDummy;
}
if( is_inside_isr() != pdFALSE )
{
lResult = xQueueReceiveFromISR( *pxMailBox, &( *ppvBuffer ), &xHigherPriorityTaskWoken );
}
else
{
lResult = xQueueReceive( *pxMailBox, &( *ppvBuffer ), 0UL );
}
if( lResult == pdPASS )
{
if (xQueueReceive(*pxMailBox, &(*ppvBuffer), 0UL) == pdPASS) {
ulReturn = ERR_OK;
}
else
{
} else {
ulReturn = SYS_MBOX_EMPTY;
}
return ulReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_new
*---------------------------------------------------------------------------*
* Description:
* Creates and returns a new semaphore. The "ucCount" argument specifies
* the initial state of the semaphore.
* NOTE: Currently this routine only creates counts of 1 or 0
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* u8_t ucCount -- Initial ucCount of semaphore (1 or 0)
* Outputs:
* sys_sem_t -- Created semaphore or 0 if could not create.
*---------------------------------------------------------------------------*/
err_t sys_sem_new( sys_sem_t *pxSemaphore, u8_t ucCount )
{
err_t xReturn = ERR_MEM;
vSemaphoreCreateBinary( ( *pxSemaphore ) );
if( *pxSemaphore != NULL )
{
if( ucCount == 0U )
{
xSemaphoreTake( *pxSemaphore, 1UL );
}
xReturn = ERR_OK;
SYS_STATS_INC_USED( sem );
}
else
{
SYS_STATS_INC( sem.err );
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_sem_wait
*---------------------------------------------------------------------------*
* Description:
* 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.
* Inputs:
* sys_sem_t sem -- Semaphore to wait on
* u32_t timeout -- Number of milliseconds until timeout
* Outputs:
* u32_t -- Time elapsed or SYS_ARCH_TIMEOUT.
*---------------------------------------------------------------------------*/
u32_t sys_arch_sem_wait( sys_sem_t *pxSemaphore, u32_t ulTimeout )
{
TickType_t xStartTime, xEndTime, xElapsed;
unsigned long ulReturn;
xStartTime = xTaskGetTickCount();
if( ulTimeout != 0UL )
{
if( xSemaphoreTake( *pxSemaphore, ulTimeout / portTICK_PERIOD_MS ) == pdTRUE )
{
xEndTime = xTaskGetTickCount();
xElapsed = (xEndTime - xStartTime) * portTICK_PERIOD_MS;
ulReturn = xElapsed;
}
else
{
ulReturn = SYS_ARCH_TIMEOUT;
}
}
else
{
while( xSemaphoreTake( *pxSemaphore, portMAX_DELAY ) != pdTRUE );
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS;
if( xElapsed == 0UL )
{
xElapsed = 1UL;
}
ulReturn = xElapsed;
}
return ulReturn;
}
/** 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 )
{
xReturn = ERR_OK;
SYS_STATS_INC_USED( mutex );
}
else
{
SYS_STATS_INC( mutex.err );
}
return xReturn;
}
/** Lock a mutex
* @param mutex the mutex to lock */
void sys_mutex_lock( sys_mutex_t *pxMutex )
{
while( xSemaphoreTake( *pxMutex, portMAX_DELAY ) != pdPASS );
}
/** Unlock a mutex
* @param mutex the mutex to unlock */
void sys_mutex_unlock(sys_mutex_t *pxMutex )
{
xSemaphoreGive( *pxMutex );
}
/** Delete a semaphore
* @param mutex the mutex to delete */
void sys_mutex_free( sys_mutex_t *pxMutex )
{
SYS_STATS_DEC( mutex.used );
vQueueDelete( *pxMutex );
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_signal
*---------------------------------------------------------------------------*
* Description:
* Signals (releases) a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to signal
*---------------------------------------------------------------------------*/
void sys_sem_signal( sys_sem_t *pxSemaphore )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if( is_inside_isr() != pdFALSE )
{
xSemaphoreGiveFromISR( *pxSemaphore, &xHigherPriorityTaskWoken );
}
else
{
xSemaphoreGive( *pxSemaphore );
}
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_free
*---------------------------------------------------------------------------*
* Description:
* Deallocates a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to free
*---------------------------------------------------------------------------*/
void sys_sem_free( sys_sem_t *pxSemaphore )
{
SYS_STATS_DEC(sem.used);
vQueueDelete( *pxSemaphore );
}
/*---------------------------------------------------------------------------*
* Routine: sys_init
*---------------------------------------------------------------------------*
@ -508,20 +405,17 @@ u32_t sys_now(void)
* Outputs:
* sys_thread_t -- Pointer to per-thread timeouts.
*---------------------------------------------------------------------------*/
sys_thread_t sys_thread_new( const char *pcName, void( *pxThread )( void *pvParameters ), void *pvArg, int iStackSize, int iPriority )
sys_thread_t sys_thread_new(const char *pcName, void(*pxThread)(void *pvParameters), void *pvArg, int iStackSize, int iPriority)
{
TaskHandle_t xCreatedTask;
portBASE_TYPE xResult;
sys_thread_t xReturn;
TaskHandle_t xCreatedTask;
portBASE_TYPE xResult;
sys_thread_t xReturn;
xResult = xTaskCreate( pxThread, pcName, iStackSize, pvArg, iPriority, &xCreatedTask );
xResult = xTaskCreate(pxThread, pcName, iStackSize, pvArg, iPriority, &xCreatedTask);
if( xResult == pdPASS )
{
if (xResult == pdPASS) {
xReturn = xCreatedTask;
}
else
{
} else {
xReturn = NULL;
}
@ -547,13 +441,14 @@ sys_thread_t xReturn;
* Outputs:
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
sys_prot_t sys_arch_protect( void )
static uint32_t my_nesting = 0;
sys_prot_t sys_arch_protect(void)
{
if( is_inside_isr() == pdFALSE )
{
taskENTER_CRITICAL();
}
return ( sys_prot_t ) 1;
taskENTER_CRITICAL();
uint32_t prev = my_nesting;
my_nesting++;
return prev;
//return (sys_prot_t)1;
}
/*---------------------------------------------------------------------------*
@ -567,26 +462,16 @@ sys_prot_t sys_arch_protect( void )
* Inputs:
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
void sys_arch_unprotect( sys_prot_t xValue )
void sys_arch_unprotect(sys_prot_t xValue)
{
(void) xValue;
if( is_inside_isr() == pdFALSE )
{
taskEXIT_CRITICAL();
//(void) xValue;
my_nesting--;
if (xValue != my_nesting) {
printf("lwip nesting %d\n", my_nesting);
}
taskEXIT_CRITICAL();
}
/*
* Prints an assertion messages and aborts execution.
*/
void sys_assert( const char *pcMessage )
{
(void) pcMessage;
for (;;)
{
}
}
/*-------------------------------------------------------------------------*
* End of File: sys_arch.c
*-------------------------------------------------------------------------*/