update + NAT + rtlbtool

This commit is contained in:
pvvx 2018-01-18 22:51:24 +03:00
parent b381813514
commit 54bf751b9c
62 changed files with 2268 additions and 3067 deletions

View file

@ -6,6 +6,11 @@
<project>RTL00_SDKV35a</project> <project>RTL00_SDKV35a</project>
</projects> </projects>
<buildSpec> <buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand> <buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers> <triggers>clean,full,incremental,</triggers>
@ -24,6 +29,7 @@
<nature>org.eclipse.cdt.core.ccnature</nature> <nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>org.python.pydev.pythonNature</nature>
</natures> </natures>
<linkedResources> <linkedResources>
<link> <link>

View file

@ -6,7 +6,7 @@ mp: ram_all_mp
.PHONY: ram_all .PHONY: ram_all
ram_all: ram_all:
@$(MAKE) -f $(SDK_PATH)sdkbuild.mk @$(MAKE) -f $(SDK_PATH)sdkbuild.mk
@$(MAKE) -f $(SDK_PATH)flasher.mk genbin1 genbin23 @$(MAKE) -f $(SDK_PATH)flasher.mk genbin
.PHONY: ram_all_mp .PHONY: ram_all_mp
ram_all_mp: ram_all_mp:

View file

@ -6,7 +6,7 @@ mp: ram_all_mp
.PHONY: ram_all .PHONY: ram_all
ram_all: ram_all:
@$(MAKE) -f $(SDK_PATH)sdkbuild.mk @$(MAKE) -f $(SDK_PATH)sdkbuild.mk
@$(MAKE) -f $(SDK_PATH)flasher.mk genbin1 genbin23 @$(MAKE) -f $(SDK_PATH)flasher.mk genbin
.PHONY: ram_all_mp .PHONY: ram_all_mp
ram_all_mp: ram_all_mp:

View file

@ -904,16 +904,17 @@ int wifi_off(void) {
uint32 timeout = xTaskGetTickCount(); uint32 timeout = xTaskGetTickCount();
if ((rltk_wlan_running(WLAN0_IDX) == 0)
&& (rltk_wlan_running(WLAN1_IDX) == 0)) {
info_printf("WIFI is not running\n");
wifi_mode = RTW_MODE_NONE;
return 0;
}
#if CONFIG_LWIP_LAYER #if CONFIG_LWIP_LAYER
dhcps_deinit(); dhcps_deinit();
LwIP_DHCP(0, DHCP_STOP); LwIP_DHCP(0, DHCP_STOP);
LwIP_DHCP(1, DHCP_STOP); LwIP_DHCP(1, DHCP_STOP);
#endif #endif
if ((rltk_wlan_running(WLAN0_IDX) == 0)
&& (rltk_wlan_running(WLAN1_IDX) == 0)) {
info_printf("WIFI is not running\n");
return 0;
}
info_printf("Deinitializing WIFI ...\n"); info_printf("Deinitializing WIFI ...\n");
#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP #if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP

View file

@ -43,7 +43,7 @@
#include "main.h" #include "main.h"
#include "wifi_user_set.h" #include "wifi_user_set.h"
#if 1 #if 0
#undef debug_printf #undef debug_printf
#define debug_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) #define debug_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__)
#undef info_printf #undef info_printf
@ -701,6 +701,9 @@ int wifi_run(rtw_mode_t mode) {
switch(mode) { switch(mode) {
case RTW_MODE_STA_AP: case RTW_MODE_STA_AP:
ret = wifi_run_ap() | wifi_run_st(); ret = wifi_run_ap() | wifi_run_st();
#if IP_NAPT
xnetif[WLAN_AP_NETIF_NUM].napt = 1;
#endif
// _wext_enable_powersave(0, 0, 0); // _wext_enable_powersave(0, 0, 0);
break; break;
case RTW_MODE_STA: case RTW_MODE_STA:

View file

@ -10,6 +10,7 @@
#include "wifi_constants.h" #include "wifi_constants.h"
#include "queue.h" #include "queue.h"
/* Get one byte from the 4-byte address */
#ifndef ip4_addr1 #ifndef ip4_addr1
#define ip4_addr1(ipaddr) (((uint8_t*)(ipaddr))[0]) #define ip4_addr1(ipaddr) (((uint8_t*)(ipaddr))[0])
#define ip4_addr2(ipaddr) (((uint8_t*)(ipaddr))[1]) #define ip4_addr2(ipaddr) (((uint8_t*)(ipaddr))[1])

View file

@ -665,7 +665,7 @@ __inline static uint get_WLAN_BSSID_EX_sz(WLAN_BSSID_EX *bss)
} }
struct wlan_network { struct wlan_network {
_list list; struct list_head list;
int network_type; //refer to ieee80211.h for WIRELESS_11A/B/G int network_type; //refer to ieee80211.h for WIRELESS_11A/B/G
int fixed; // set to fixed when not to be removed as site-surveying int fixed; // set to fixed when not to be removed as site-surveying
unsigned long last_scanned; //timestamp for the network unsigned long last_scanned; //timestamp for the network

View file

@ -153,8 +153,18 @@ void rltk_wlan_recv(int idx, struct eth_drv_sg *sg_list, int sg_len)
#endif #endif
} }
/* uses in void __fastcall rltk_netif_rx(sk_buff *skb) */
int netif_is_valid_IP(int idx, unsigned char *ip_dest) int netif_is_valid_IP(int idx, unsigned char *ip_dest)
{ {
#if IP_FORWARD // add pvvx
return 1;
#elif defined(CONFIG_DONT_CARE_TP)
if(pnetif->flags & NETIF_FLAG_IPSWITCH)
return 1;
else
return 0;
#else
#if CONFIG_LWIP_LAYER == 1 #if CONFIG_LWIP_LAYER == 1
#if DEVICE_EMAC #if DEVICE_EMAC
struct netif *pnetif = xnetif[idx]; struct netif *pnetif = xnetif[idx];
@ -187,13 +197,9 @@ int netif_is_valid_IP(int idx, unsigned char *ip_dest)
return 1; return 1;
DBG_TRACE("invalid IP: %d.%d.%d.%d ",ip_dest[0],ip_dest[1],ip_dest[2],ip_dest[3]); DBG_TRACE("invalid IP: %d.%d.%d.%d ",ip_dest[0],ip_dest[1],ip_dest[2],ip_dest[3]);
#endif
#ifdef CONFIG_DONT_CARE_TP
if(pnetif->flags & NETIF_FLAG_IPSWITCH)
return 1;
else
#endif
return 0; return 0;
#endif // CONFIG_LWIP_LAYER
#endif // IP_FORWARD / CONFIG_DONT_CARE_TP
} }
int netif_get_idx(struct netif *pnetif) int netif_get_idx(struct netif *pnetif)

View file

@ -143,7 +143,11 @@ static void add_offer_options(uint8_t *option_start_address)
The option specifies a list of DNS servers available to the client. */ The option specifies a list of DNS servers available to the client. */
temp_option_addr = fill_one_option_content(temp_option_addr, temp_option_addr = fill_one_option_content(temp_option_addr,
DHCP_OPTION_CODE_DNS_SERVER, DHCP_OPTION_LENGTH_FOUR, DHCP_OPTION_CODE_DNS_SERVER, DHCP_OPTION_LENGTH_FOUR,
#if IP_NAPT
(void *)&dhcps_local_gateway);
#else
(void *)&dhcps_local_address); (void *)&dhcps_local_address);
#endif
/* add DHCP options 51. /* add DHCP options 51.
This option is used to request a lease time for the IP address. */ This option is used to request a lease time for the IP address. */
temp_option_addr = fill_one_option_content(temp_option_addr, temp_option_addr = fill_one_option_content(temp_option_addr,

View file

@ -30,7 +30,7 @@
* *
*/ */
#if defined(__IAR_SYSTEMS_ICC__) #if defined(__IAR_SYSTEMS_ICC__)|| defined (__GNUC__)
#pragma pack(1) #pragma pack(1)
#endif #endif

View file

@ -85,6 +85,7 @@ typedef int sys_prot_t;
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) #define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
#define PACK_STRUCT_END #define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x #define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_USE_INCLUDES
#elif defined (__TASKING__) #elif defined (__TASKING__)

View file

@ -32,5 +32,7 @@
#if defined(__IAR_SYSTEMS_ICC__) #if defined(__IAR_SYSTEMS_ICC__)
#pragma pack() #pragma pack()
#elif defined (__GNUC__)
#pragma pack()
#endif #endif

View file

@ -42,6 +42,7 @@
#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE #define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
typedef xSemaphoreHandle sys_sem_t; typedef xSemaphoreHandle sys_sem_t;
typedef xSemaphoreHandle sys_mutex_t;
typedef xQueueHandle sys_mbox_t; typedef xQueueHandle sys_mbox_t;
typedef xTaskHandle sys_thread_t; typedef xTaskHandle sys_thread_t;

View file

@ -114,7 +114,7 @@ static void low_level_init(struct netif *netif)
netif->hwaddr_len = ETHARP_HWADDR_LEN; netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* set netif maximum transfer unit */ /* set netif maximum transfer unit */
netif->mtu = 1500; netif->mtu = netifMTU;
/* Accept broadcast address and ARP traffic */ /* Accept broadcast address and ARP traffic */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;

View file

@ -443,7 +443,6 @@ void sys_mutex_unlock(sys_mutex_t *mutex)
thread() function. The id of the new thread is returned. Both the id and thread() function. The id of the new thread is returned. Both the id and
the priority are system dependent. the priority are system dependent.
*/ */
#if 0
sys_thread_t sys_thread_new_tcm(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio) sys_thread_t sys_thread_new_tcm(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio)
{ {
xTaskHandle CreatedTask; xTaskHandle CreatedTask;
@ -456,6 +455,9 @@ int result;
{ {
void *stack_addr = tcm_heap_malloc(stacksize * sizeof(int)); void *stack_addr = tcm_heap_malloc(stacksize * sizeof(int));
if(stack_addr == NULL){
}
result = xTaskGenericCreate( result = xTaskGenericCreate(
thread, thread,
( signed portCHAR * ) name, ( signed portCHAR * ) name,
@ -489,7 +491,6 @@ int result;
return NULL; return NULL;
} }
} }
#endif
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
// TODO // TODO
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View file

@ -1,36 +0,0 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#if defined(__IAR_SYSTEMS_ICC__)
#pragma pack(1)
#endif

View file

@ -1,93 +0,0 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CC_H__
#define __CC_H__
#include "cpu.h"
typedef unsigned char u8_t;
typedef signed char s8_t;
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned int u32_t;
typedef signed int s32_t;
typedef u32_t mem_ptr_t;
typedef int sys_prot_t;
#define U16_F "hu"
#define S16_F "d"
#define X16_F "hx"
#define U32_F "u"
#define S32_F "d"
#define X32_F "x"
#define SZT_F "uz"
/* define compiler specific symbols */
#if defined (__ICCARM__)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_USE_INCLUDES
#elif defined (__CC_ARM)
#define PACK_STRUCT_BEGIN __packed
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#elif defined (__GNUC__)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#elif defined (__TASKING__)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#endif
#define LWIP_PLATFORM_ASSERT(x) //do { if(!(x)) while(1); } while(0)
#endif /* __CC_H__ */

View file

@ -1,37 +0,0 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CPU_H__
#define __CPU_H__
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* __CPU_H__ */

View file

@ -1,36 +0,0 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#if defined(__IAR_SYSTEMS_ICC__)
#pragma pack()
#endif

View file

@ -1,44 +0,0 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __ARCH_INIT_H__
#define __ARCH_INIT_H__
#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg)
void tcpip_init_done(void *);
int wait_for_tcpip_init(void);
#endif /* __ARCH_INIT_H__ */

View file

@ -1,38 +0,0 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LIB_H__
#define __LIB_H__
#include <string.h>
#endif /* __LIB_H__ */

View file

@ -1,38 +0,0 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PERF_H__
#define __PERF_H__
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif /* __PERF_H__ */

View file

@ -1,67 +0,0 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __SYS_RTXC_H__
#define __SYS_RTXC_H__
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#define SYS_MBOX_NULL (xQueueHandle)0
#define SYS_SEM_NULL (xSemaphoreHandle)0
#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
typedef xSemaphoreHandle sys_sem_t;
typedef xSemaphoreHandle sys_mutex_t;
typedef xQueueHandle sys_mbox_t;
typedef xTaskHandle sys_thread_t;
typedef struct _sys_arch_state_t
{
// Task creation data.
char cTaskName[configMAX_TASK_NAME_LEN];
unsigned short nStackDepth;
unsigned short nTaskCount;
} sys_arch_state_t;
//extern sys_arch_state_t s_sys_arch_state;
//void sys_set_default_state();
//void sys_set_state(signed char *pTaskName, unsigned short nStackSize);
/* Message queue constants. */
#define archMESG_QUEUE_LENGTH ( 6 )
#endif /* __SYS_RTXC_H__ */

View file

@ -1,489 +0,0 @@
/**
* @file
* Ethernet Interface Skeleton
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*
* This file is a skeleton for developing Ethernet network interface
* drivers for lwIP. Add code to the low_level functions and do a
* search-and-replace for the word "ethernetif" to replace it with
* something that better describes your network interface.
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
//#include "lwip/sys.h"
//#include "lwip/tcpip.h"
//#include "lwip/icmp.h"
#include "lwip/lwip_timers.h"
#include "netif/etharp.h"
#include "err.h"
#include "ethernetif.h"
//#include "queue.h"
#include "main.h" // for the definition of CONFIG_WLAN
#if !CONFIG_WLAN
#include "stm32f2x7_eth.h"
#else
#include <lwip_intf.h>
#endif
#include <platform/platform_stdlib.h>
#include <string.h>
#define netifMTU (1500)
#define netifINTERFACE_TASK_STACK_SIZE ( 350 )
#define netifINTERFACE_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define netifGUARD_BLOCK_TIME ( 250 )
/* The time to block waiting for input. */
#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 )
#if !CONFIG_WLAN
/* Define those to better describe your network interface. */
#define IFNAME0 's'
#define IFNAME1 't'
static struct netif *s_pxNetIf = NULL;
xSemaphoreHandle s_xSemaphore = NULL;
/* Ethernet Rx & Tx DMA Descriptors */
extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
/* Ethernet Receive buffers */
extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
/* Ethernet Transmit buffers */
extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
/* Global pointers to track current transmit and receive descriptors */
extern ETH_DMADESCTypeDef *DMATxDescToSet;
extern ETH_DMADESCTypeDef *DMARxDescToGet;
/* Global pointer for last received frame infos */
extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos;
static void ethernetif_input( void * pvParameters );
#endif
static void arp_timer(void *arg);
/**
* 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)
{
uint32_t i;
/* set netif MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
#if !CONFIG_WLAN
/* set netif MAC hardware address */
netif->hwaddr[0] = MAC_ADDR0;
netif->hwaddr[1] = MAC_ADDR1;
netif->hwaddr[2] = MAC_ADDR2;
netif->hwaddr[3] = MAC_ADDR3;
netif->hwaddr[4] = MAC_ADDR4;
netif->hwaddr[5] = MAC_ADDR5;
#endif
/* set netif maximum transfer unit */
netif->mtu = 1500;
/* Accept broadcast address and ARP traffic */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
#if !CONFIG_WLAN
s_pxNetIf =netif;
/* create binary semaphore used for informing ethernetif of frame reception */
if (s_xSemaphore == NULL)
{
vSemaphoreCreateBinary(s_xSemaphore);
xSemaphoreTake( s_xSemaphore, 0);
}
/* initialize MAC address in ethernet MAC */
ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr);
/* Initialize Tx Descriptors list: Chain Mode */
ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
/* Initialize Rx Descriptors list: Chain Mode */
ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
/* Enable Ethernet Rx interrrupt */
{
for(i=0; i<ETH_RXBUFNB; i++)
{
ETH_DMARxDescReceiveITConfig(&DMARxDscrTab[i], ENABLE);
}
}
#ifdef CHECKSUM_BY_HARDWARE
/* Enable the checksum insertion for the Tx frames */
{
for(i=0; i<ETH_TXBUFNB; i++)
{
ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
}
}
#endif
/* create the task that handles the ETH_MAC */
xTaskCreate(ethernetif_input, (signed char*) "Eth_if", netifINTERFACE_TASK_STACK_SIZE, NULL,
netifINTERFACE_TASK_PRIORITY,NULL);
/* Enable MAC and DMA transmission and reception */
ETH_Start();
#else //#if !CONFIG_WLAN
/* WLAN interface is initialized later */
#endif
}
/**
* 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 availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
#if !CONFIG_WLAN
static xSemaphoreHandle xTxSemaphore = NULL;
struct pbuf *q;
u8 *buffer ;
__IO ETH_DMADESCTypeDef *DmaTxDesc;
uint16_t framelength = 0;
uint32_t bufferoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t payloadoffset = 0;
if (xTxSemaphore == NULL)
{
vSemaphoreCreateBinary (xTxSemaphore);
}
if (xSemaphoreTake(xTxSemaphore, netifGUARD_BLOCK_TIME))
{
DmaTxDesc = DMATxDescToSet;
buffer = (u8 *)(DmaTxDesc->Buffer1Addr);
bufferoffset = 0;
for(q = p; q != NULL; q = q->next)
{
if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
{
goto error;
}
/* Get bytes in current lwIP buffer */
byteslefttocopy = q->len;
payloadoffset = 0;
/* Check if the length of data to copy is bigger than Tx buffer size*/
while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE )
{
/* Copy data to Tx buffer*/
memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) );
/* Point to next descriptor */
DmaTxDesc = (ETH_DMADESCTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
/* Check if the buffer is available */
if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
{
goto error;
}
buffer = (u8 *)(DmaTxDesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);
framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}
/* Copy the remaining bytes */
memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), byteslefttocopy );
bufferoffset = bufferoffset + byteslefttocopy;
framelength = framelength + byteslefttocopy;
}
/* Prepare transmit descriptors to give to DMA*/
ETH_Prepare_Transmit_Descriptors(framelength);
/* Give semaphore and exit */
error:
xSemaphoreGive(xTxSemaphore);
}
#endif // #if !CONFIG_WLAN
return ERR_OK;
}
#if !CONFIG_WLAN
/**
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this ethernetif
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf * low_level_input(struct netif *netif)
{
struct pbuf *p= NULL, *q;
u32_t len;
FrameTypeDef frame;
u8 *buffer;
__IO ETH_DMADESCTypeDef *DMARxDesc;
uint32_t bufferoffset = 0;
uint32_t payloadoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t i=0;
/* get received frame */
frame = ETH_Get_Received_Frame_interrupt();
/* Obtain the size of the packet and put it into the "len" variable. */
len = frame.length;
buffer = (u8 *)frame.buffer;
if (len > 0)
{
/* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
}
if (p != NULL)
{
DMARxDesc = frame.descriptor;
bufferoffset = 0;
for(q = p; q != NULL; q = q->next)
{
byteslefttocopy = q->len;
payloadoffset = 0;
/* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE )
{
/* Copy data to pbuf*/
memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
/* Point to next descriptor */
DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr);
buffer = (unsigned char *)(DMARxDesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}
/* Copy remaining data in pbuf */
memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), byteslefttocopy);
bufferoffset = bufferoffset + byteslefttocopy;
}
/* Release descriptors to DMA */
DMARxDesc =frame.descriptor;
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
{
DMARxDesc->Status = ETH_DMARxDesc_OWN;
DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr);
}
/* Clear Segment_Count */
DMA_RX_FRAME_infos->Seg_Count =0;
/* added for test*/
}
/* When Rx Buffer unavailable flag is set: clear it and resume reception */
if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
{
/* Clear RBUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_RBUS;
/* Resume DMA reception */
ETH->DMARPDR = 0;
}
return p;
}
/**
* This function is the ethernetif_input task, it is processed 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
*/
void ethernetif_input( void * pvParameters )
{
struct pbuf *p;
for( ;; )
{
if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE)
{
TRY_GET_NEXT_FRAME:
p = low_level_input( s_pxNetIf );
if (p != NULL)
{
if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf))
{
pbuf_free(p);
}
else
{
goto TRY_GET_NEXT_FRAME;
}
}
}
}
}
#endif
/**
* 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));
#if !CONFIG_WLAN
/* ethernet */
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
#else
/* wlan interface*/
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
#endif // WLAN
netif->output = etharp_output;
netif->linkoutput = low_level_output;
/* initialize the hardware */
low_level_init(netif);
etharp_init();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
return ERR_OK;
}
static void arp_timer(void *arg)
{
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
}
/*
* For FreeRTOS tickless
*/
int lwip_tickless_used = 0;
/*
int arp_timeout_exist(void)
{
struct sys_timeouts *timeouts;
struct sys_timeo *t;
timeouts = sys_arch_timeouts();
for(t = timeouts->next; t != NULL;t = t->next)
if(t->h == arp_timer)
return 1;
return 0;
}
*/
//Called by rltk_wlan_PRE_SLEEP_PROCESSING()
void lwip_PRE_SLEEP_PROCESSING(void)
{
if(arp_timeout_exist()) {
tcpip_untimeout(arp_timer, NULL);
}
lwip_tickless_used = 1;
}
//Called in ips_leave() path, support tickless when wifi power wakeup due to ioctl or deinit
void lwip_POST_SLEEP_PROCESSING(void)
{
if(lwip_tickless_used) {
tcpip_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
}
}

View file

@ -1,653 +0,0 @@
/**
* @file
* Ethernet Interface Skeleton
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*
* This file is a skeleton for developing Ethernet network interface
* drivers for lwIP. Add code to the low_level functions and do a
* search-and-replace for the word "ethernetif" to replace it with
* something that better describes your network interface.
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/tcpip.h"
#include "lwip/icmp.h"
#include "lwip/lwip_timers.h"
#include "netif/etharp.h"
#include "err.h"
#include "ethernetif.h"
#include "queue.h"
#include "main.h" // for the definition of CONFIG_WLAN
#if !CONFIG_WLAN
#include "stm32f2x7_eth.h"
#else
#include <lwip_intf.h>
#endif
#include <platform/platform_stdlib.h>
#include <string.h>
#ifdef CONFIG_DONT_CARE_TP
#define netifMTU (576)
#else
#define netifMTU (1500)
#endif
#define netifINTERFACE_TASK_STACK_SIZE ( 350 )
#define netifINTERFACE_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define netifGUARD_BLOCK_TIME ( 250 )
/* The time to block waiting for input. */
#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 )
#define FAKE_PING_REPLY 0
#if !CONFIG_WLAN
/* Define those to better describe your network interface. */
#define IFNAME0 's'
#define IFNAME1 't'
static struct netif *s_pxNetIf = NULL;
xSemaphoreHandle s_xSemaphore = NULL;
/* Ethernet Rx & Tx DMA Descriptors */
extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
/* Ethernet Receive buffers */
extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
/* Ethernet Transmit buffers */
extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
/* Global pointers to track current transmit and receive descriptors */
extern ETH_DMADESCTypeDef *DMATxDescToSet;
extern ETH_DMADESCTypeDef *DMARxDescToGet;
/* Global pointer for last received frame infos */
extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos;
static void ethernetif_input( void * pvParameters );
#endif
static void arp_timer(void *arg);
/**
* 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)
{
uint32_t i;
/* set netif MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
#if !CONFIG_WLAN
/* set netif MAC hardware address */
netif->hwaddr[0] = MAC_ADDR0;
netif->hwaddr[1] = MAC_ADDR1;
netif->hwaddr[2] = MAC_ADDR2;
netif->hwaddr[3] = MAC_ADDR3;
netif->hwaddr[4] = MAC_ADDR4;
netif->hwaddr[5] = MAC_ADDR5;
#endif
/* set netif maximum transfer unit */
netif->mtu = netifMTU;
/* Accept broadcast address and ARP traffic */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
#if !CONFIG_WLAN
s_pxNetIf =netif;
/* create binary semaphore used for informing ethernetif of frame reception */
if (s_xSemaphore == NULL)
{
s_xSemaphore= xSemaphoreCreateCounting(20,0);
}
/* initialize MAC address in ethernet MAC */
ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr);
/* Initialize Tx Descriptors list: Chain Mode */
ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
/* Initialize Rx Descriptors list: Chain Mode */
ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
/* Enable Ethernet Rx interrrupt */
{
for(i=0; i<ETH_RXBUFNB; i++)
{
ETH_DMARxDescReceiveITConfig(&DMARxDscrTab[i], ENABLE);
}
}
#ifdef CHECKSUM_BY_HARDWARE
/* Enable the checksum insertion for the Tx frames */
{
for(i=0; i<ETH_TXBUFNB; i++)
{
ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
}
}
#endif
/* create the task that handles the ETH_MAC */
xTaskCreate(ethernetif_input, (signed char*) "Eth_if", netifINTERFACE_TASK_STACK_SIZE, NULL,
netifINTERFACE_TASK_PRIORITY,NULL);
/* Enable MAC and DMA transmission and reception */
ETH_Start();
#else //#if !CONFIG_WLAN
/* WLAN interface is initialized later */
#endif
}
#if FAKE_PING_REPLY
void fake_arp_reply(struct netif *netif, struct pbuf *p)
{
struct pbuf *q, *tq, *tp;
int q_len, p_len;
struct eth_hdr *p_eth, *q_eth;
struct etharp_hdr *p_arp, *q_arp;
struct eth_addr fake_src_mac = {0xb0, 0x48, 0x7a, 0xfe, 0xea, 0xe0};
// Allocate buffer to store received packet
q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_POOL);
if (p == NULL) {
printf("\n\rCannot allocate pbuf to receive packet");
return;
}
for (tq = q, tp = p, q_len = tq->len; tp != NULL ; tp = tp->next)
{
p_len = tp->len;
while(p_len)
{
if(q_len > p_len) {
memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), p_len);
q_len -= p_len;
p_len = 0;
}else{
memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), q_len);
p_len -= q_len;
tq = tq->next;
q_len = tq->len;
}
}
}
p_eth = (struct eth_hdr *)p->payload;
q_eth = (struct eth_hdr *)q->payload;
p_arp = (struct etharp_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr));
q_arp = (struct etharp_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr));
q_eth->dest = p_eth->src;
q_eth->src = fake_src_mac;
q_arp->opcode = htons(ARP_REPLY);
q_arp->shwaddr = fake_src_mac;
q_arp->sipaddr = p_arp->dipaddr;
q_arp->dhwaddr = p_eth->src;
q_arp->dipaddr = p_arp->sipaddr;
if(0){
int i;
char *buf = q->payload;
printf("\n\r");
for(i=0;i<q->tot_len;i++)
printf("0x%02x, ", buf[i]);
printf("\n\r");
}
if (ERR_OK != netif->input(q, netif)){
printf("\n\rfake_arp_reply input error");
pbuf_free(q);
}else
printf("\n\rfake arp reply \n\r");
}
void fake_echo_reply(struct netif *netif, struct pbuf *p)
{
struct pbuf *q, *tq, *tp;
int q_len, p_len;
struct eth_hdr *p_eth, *q_eth;
struct ip_hdr *p_ip, *q_ip;
struct icmp_echo_hdr *p_echo, *q_echo;
// Allocate buffer to store received packet
q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_POOL);
if (p == NULL) {
printf("\n\rCannot allocate pbuf to receive packet");
return;
}
for (tq = q, tp = p, q_len = tq->len; tp != NULL ; tp = tp->next)
{
p_len = tp->len;
while(p_len)
{
if(q_len > p_len) {
memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), p_len);
q_len -= p_len;
p_len = 0;
}else{
memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), q_len);
p_len -= q_len;
tq = tq->next;
q_len = tq->len;
}
}
}
p_eth = (struct eth_hdr *)p->payload;
q_eth = (struct eth_hdr *)q->payload;
p_ip = (struct ip_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr));
q_ip = (struct ip_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr));
p_echo = (struct icmp_echo_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr) + sizeof(struct ip_hdr));
q_echo = (struct icmp_echo_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr) + sizeof(struct ip_hdr));
q_eth->dest = p_eth->src;
q_eth->src = p_eth->dest;
q_ip->src.addr = p_ip->dest.addr;
q_ip->dest.addr = p_ip->src.addr;
q_ip->_chksum = 0;
q_ip->_chksum = inet_chksum(q_ip, sizeof(struct ip_hdr));
q_echo->type = ICMP_ER;
q_echo->code = 0;
q_echo->chksum = 0;
q_echo->chksum = inet_chksum(q_echo, q->tot_len - sizeof(struct eth_hdr) - sizeof(struct ip_hdr));
if(0){
int i;
char *buf = q->payload;
printf("\n\r");
for(i=0;i<q->tot_len;i++)
printf("0x%02x, ", buf[i]);
printf("\n\r");
}
if (ERR_OK != netif->input(q, netif)){
printf("\n\rfake_echo_reply input error");
pbuf_free(q);
}else
printf("\n\rfake echo reply \n\r");
}
#endif // #if FAKE_PING_REPLY
/**
* 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 availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
#if !CONFIG_WLAN
static xSemaphoreHandle xTxSemaphore = NULL;
struct pbuf *q;
uint32_t l = 0;
u8 *buffer ;
if (xTxSemaphore == NULL)
{
vSemaphoreCreateBinary (xTxSemaphore);
}
if (xSemaphoreTake(xTxSemaphore, netifGUARD_BLOCK_TIME))
{
buffer = (u8 *)(DMATxDescToSet->Buffer1Addr);
for(q = p; q != NULL; q = q->next)
{
memcpy((u8_t*)&buffer[l], q->payload, q->len);
l = l + q->len;
}
ETH_Prepare_Transmit_Descriptors(l);
xSemaphoreGive(xTxSemaphore);
}
#else
/* Refer to eCos lwip eth_drv_send() */
struct eth_drv_sg sg_list[MAX_ETH_DRV_SG];
int sg_len = 0;
struct pbuf *q;
if(!rltk_wlan_running(netif_get_idx(netif)))
return ERR_IF;
for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) {
sg_list[sg_len].buf = (unsigned int) q->payload;
sg_list[sg_len++].len = q->len;
}
#if FAKE_PING_REPLY
{
char *header = p->payload;
if(header[12] == 0x08 && header[13] == 0x06)
{ // arp packet
if(header[21] == 0x01)
{ // arp request packet
printf("\n\rfake_ping: arp request packet.");
if(0)
{
int i;
printf("\n\r");
for (q = p; q != NULL; q = q->next)
{
char *buf = q->payload;
for(i=0;i<q->len;i++)
printf("0x%02x, ", buf[i]);
}
printf("\n\r");
}
fake_arp_reply(netif, p);
return ERR_OK;
}
}else if(header[12] == 0x08 && header[13] == 0x00)
{ // ip packet
if(header[15] == 0x00 && header[23] == 0x01)
{ // icmp packet
printf("\n\rfake_ping: icmp packet.");
if(0){
int i;
printf("\n\r");
for (q = p; q != NULL; q = q->next)
{
char *buf = q->payload;
for(i=0;i<q->len;i++)
printf("0x%02x, ", buf[i]);
}
printf("\n\r");
}
fake_echo_reply(netif, p);
return ERR_OK;
}
}
}
#endif // #if FAKE_PING_REPLY
if (sg_len)
rltk_wlan_send(netif_get_idx(netif), sg_list, sg_len, p->tot_len);
#endif // #if !CONFIG_WLAN
return ERR_OK;
}
#if !CONFIG_WLAN
/**
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this ethernetif
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf * low_level_input(struct netif *netif)
{
struct pbuf *p, *q;
u16_t len;
uint32_t l=0,i =0;
FrameTypeDef frame;
u8 *buffer;
__IO ETH_DMADESCTypeDef *DMARxNextDesc;
p = NULL;
/* Get received frame */
frame = ETH_Get_Received_Frame_interrupt();
/* check that frame has no error */
if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET)
{
/* Obtain the size of the packet and put it into the "len" variable. */
len = frame.length;
buffer = (u8 *)frame.buffer;
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
/* Copy received frame from ethernet driver buffer to stack buffer */
if (p != NULL)
{
for (q = p; q != NULL; q = q->next)
{
memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len);
l = l + q->len;
}
}
}
/* Release descriptors to DMA */
/* Check if received frame with multiple DMA buffer segments */
if (DMA_RX_FRAME_infos->Seg_Count > 1)
{
DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc;
}
else
{
DMARxNextDesc = frame.descriptor;
}
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
{
DMARxNextDesc->Status = ETH_DMARxDesc_OWN;
DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr);
}
/* Clear Segment_Count */
DMA_RX_FRAME_infos->Seg_Count =0;
/* When Rx Buffer unavailable flag is set: clear it and resume reception */
if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
{
/* Clear RBUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_RBUS;
/* Resume DMA reception */
ETH->DMARPDR = 0;
}
return p;
}
/**
* This function is the ethernetif_input task, it is processed 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
*/
void ethernetif_input( void * pvParameters )
{
struct pbuf *p;
for( ;; )
{
if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE)
{
p = low_level_input( s_pxNetIf );
if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf))
{
pbuf_free(p);
p=NULL;
}
}
}
}
#endif
/* Refer to eCos eth_drv_recv to do similarly in ethernetif_input */
void ethernetif_recv(struct netif *netif, int total_len)
{
#if CONFIG_WLAN
struct eth_drv_sg sg_list[MAX_ETH_DRV_SG];
struct pbuf *p, *q;
int sg_len = 0;
if(!rltk_wlan_running(netif_get_idx(netif)))
return;
if ((total_len > MAX_ETH_MSG) || (total_len < 0))
total_len = MAX_ETH_MSG;
// Allocate buffer to store received packet
p = pbuf_alloc(PBUF_RAW, total_len, PBUF_POOL);
if (p == NULL) {
printf("\n\rCannot allocate pbuf to receive packet");
return;
}
// Create scatter list
for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) {
sg_list[sg_len].buf = (unsigned int) q->payload;
sg_list[sg_len++].len = q->len;
}
// Copy received packet to scatter list from wrapper rx skb
//printf("\n\rwlan:%c: Recv sg_len: %d, tot_len:%d", netif->name[1],sg_len, total_len);
rltk_wlan_recv(netif_get_idx(netif), sg_list, sg_len);
// Pass received packet to the interface
if (ERR_OK != netif->input(p, netif))
pbuf_free(p);
#endif
}
/**
* 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));
#if !CONFIG_WLAN
/* ethernet */
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
#else
/* wlan interface*/
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
if(netif->name[1] == '0')
netif->hostname = "lwip0";
else if(netif->name[1] == '1')
netif->hostname = "lwip1";
#endif /* LWIP_NETIF_HOSTNAME */
#endif // WLAN
netif->output = etharp_output;
netif->linkoutput = low_level_output;
/* initialize the hardware */
low_level_init(netif);
etharp_init();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
return ERR_OK;
}
static void arp_timer(void *arg)
{
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
}
/*
* For FreeRTOS tickless
*/
int lwip_tickless_used = 0;
int arp_timeout_exist(void)
{
struct sys_timeouts *timeouts;
struct sys_timeo *t;
timeouts = sys_arch_timeouts();
for(t = timeouts->next; t != NULL;t = t->next)
if(t->h == arp_timer)
return 1;
return 0;
}
//Called by rltk_wlan_PRE_SLEEP_PROCESSING()
void lwip_PRE_SLEEP_PROCESSING(void)
{
if(arp_timeout_exist()) {
tcpip_untimeout(arp_timer, NULL);
}
lwip_tickless_used = 1;
}
//Called in ips_leave() path, support tickless when wifi power wakeup due to ioctl or deinit
void lwip_POST_SLEEP_PROCESSING(void)
{
if(lwip_tickless_used) {
tcpip_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
}
}

View file

@ -1,23 +0,0 @@
#ifndef __ETHERNETIF_H__
#define __ETHERNETIF_H__
#include "lwip/err.h"
#include "lwip/netif.h"
//----- ------------------------------------------------------------------
// Ethernet Buffer
//----- ------------------------------------------------------------------
struct eth_drv_sg {
unsigned int buf;
unsigned int len;
};
#define MAX_ETH_DRV_SG 32
#define MAX_ETH_MSG 1540
void ethernetif_recv(struct netif *netif, int total_len);
err_t ethernetif_init(struct netif *netif);
void lwip_PRE_SLEEP_PROCESSING(void);
void lwip_POST_SLEEP_PROCESSING(void);
#endif

View file

@ -1,515 +0,0 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* lwIP includes. */
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/stats.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "lwip/lwip_timers.h"
xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;
struct timeoutlist
{
struct sys_timeouts timeouts;
xTaskHandle pid;
};
/* This is the number of threads that can be started with sys_thread_new() */
#define SYS_THREAD_MAX 6
static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX];
static u16_t s_nextthread = 0;
/*-----------------------------------------------------------------------------------*/
// Creates an empty mailbox.
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
{
(void ) size;
*mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) );
#if SYS_STATS
++lwip_stats.sys.mbox.used;
if (lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) {
lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
}
#endif /* SYS_STATS */
if (*mbox == NULL)
return ERR_MEM;
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
Deallocates a mailbox. If there are messages still present in the
mailbox when the mailbox is deallocated, it is an indication of a
programming error in lwIP and the developer should be notified.
*/
void sys_mbox_free(sys_mbox_t *mbox)
{
if( uxQueueMessagesWaiting( *mbox ) )
{
/* Line for breakpoint. Should never break here! */
portNOP();
#if SYS_STATS
lwip_stats.sys.mbox.err++;
#endif /* SYS_STATS */
// TODO notify the user of failure.
}
vQueueDelete( *mbox );
#if SYS_STATS
--lwip_stats.sys.mbox.used;
#endif /* SYS_STATS */
}
/*-----------------------------------------------------------------------------------*/
// Posts the "msg" to the mailbox.
void sys_mbox_post(sys_mbox_t *mbox, void *data)
{
while ( xQueueSendToBack(*mbox, &data, portMAX_DELAY ) != pdTRUE ){}
}
/*-----------------------------------------------------------------------------------*/
// Try to post the "msg" to the mailbox.
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
err_t result;
if ( xQueueSend( *mbox, &msg, 0 ) == pdPASS )
{
result = ERR_OK;
}
else {
// could not post, queue must be full
result = ERR_MEM;
#if SYS_STATS
lwip_stats.sys.mbox.err++;
#endif /* SYS_STATS */
}
return result;
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread until a message arrives in the mailbox, but does
not block the thread longer than "timeout" milliseconds (similar to
the sys_arch_sem_wait() function). The "msg" argument is a result
parameter that is set by the function (i.e., by doing "*msg =
ptr"). The "msg" parameter maybe NULL to indicate that the message
should be dropped.
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.
Note that a function with a similar name, sys_mbox_fetch(), is
implemented by lwIP.
*/
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
{
void *dummyptr;
portTickType StartTime, EndTime, Elapsed;
StartTime = xTaskGetTickCount();
if ( msg == NULL )
{
msg = &dummyptr;
}
if ( timeout != 0 )
{
if ( pdTRUE == xQueueReceive( *mbox, &(*msg), timeout / portTICK_RATE_MS ) )
{
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
return ( Elapsed );
}
else // timed out blocking for message
{
*msg = NULL;
return SYS_ARCH_TIMEOUT;
}
}
else // block forever for a message.
{
while( pdTRUE != xQueueReceive( *mbox, &(*msg), portMAX_DELAY ) ){} // time is arbitrary
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
return ( Elapsed ); // return time blocked TODO test
}
}
/*-----------------------------------------------------------------------------------*/
/*
Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll
return with SYS_MBOX_EMPTY. On success, 0 is returned.
*/
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
void *dummyptr;
if ( msg == NULL )
{
msg = &dummyptr;
}
if ( pdTRUE == xQueueReceive( *mbox, &(*msg), 0 ) )
{
return ERR_OK;
}
else
{
return SYS_MBOX_EMPTY;
}
}
/*----------------------------------------------------------------------------------*/
int sys_mbox_valid(sys_mbox_t *mbox)
{
if (*mbox == SYS_MBOX_NULL)
return 0;
else
return 1;
}
/*-----------------------------------------------------------------------------------*/
void sys_mbox_set_invalid(sys_mbox_t *mbox)
{
*mbox = SYS_MBOX_NULL;
}
/*-----------------------------------------------------------------------------------*/
// Creates a new semaphore. The "count" argument specifies
// the initial state of the semaphore.
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
{
vSemaphoreCreateBinary(*sem );
if(*sem == NULL)
{
#if SYS_STATS
++lwip_stats.sys.sem.err;
#endif /* SYS_STATS */
return ERR_MEM;
}
if(count == 0) // Means it can't be taken
{
xSemaphoreTake(*sem,1);
}
#if SYS_STATS
++lwip_stats.sys.sem.used;
if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) {
lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
}
#endif /* SYS_STATS */
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread while waiting for the semaphore to be
signaled. If the "timeout" argument is non-zero, the thread should
only be blocked for the specified time (measured in
milliseconds).
If the timeout argument is non-zero, the return value is the number of
milliseconds spent waiting for the semaphore to be signaled. If the
semaphore wasn't signaled within the specified time, the return value is
SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
(i.e., it was already signaled), the function may return zero.
Notice that lwIP implements a function with a similar name,
sys_sem_wait(), that uses the sys_arch_sem_wait() function.
*/
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
{
portTickType StartTime, EndTime, Elapsed;
StartTime = xTaskGetTickCount();
if( timeout != 0)
{
if( xSemaphoreTake( *sem, timeout / portTICK_RATE_MS ) == pdTRUE )
{
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
return (Elapsed); // return time blocked TODO test
}
else
{
return SYS_ARCH_TIMEOUT;
}
}
else // must block without a timeout
{
while( xSemaphoreTake(*sem, portMAX_DELAY) != pdTRUE){}
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_RATE_MS;
return ( Elapsed ); // return time blocked
}
}
/*-----------------------------------------------------------------------------------*/
// Signals a semaphore
void sys_sem_signal(sys_sem_t *sem)
{
xSemaphoreGive(*sem);
}
/*-----------------------------------------------------------------------------------*/
// Deallocates a semaphore
void sys_sem_free(sys_sem_t *sem)
{
#if SYS_STATS
--lwip_stats.sys.sem.used;
#endif /* SYS_STATS */
vQueueDelete(*sem);
}
/*-----------------------------------------------------------------------------------*/
int sys_sem_valid(sys_sem_t *sem)
{
if (*sem == SYS_SEM_NULL)
return 0;
else
return 1;
}
/*-----------------------------------------------------------------------------------*/
void sys_sem_set_invalid(sys_sem_t *sem)
{
*sem = SYS_SEM_NULL;
}
/*-----------------------------------------------------------------------------------*/
// Initialize sys arch
void sys_init(void)
{
int i;
// Initialize the the per-thread sys_timeouts structures
// make sure there are no valid pids in the list
for(i = 0; i < SYS_THREAD_MAX; i++)
{
s_timeoutlist[i].pid = 0;
s_timeoutlist[i].timeouts.next = NULL;
}
// keep track of how many threads have been created
s_nextthread = 0;
}
/*
Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
each thread has a list of timeouts which is represented as a linked
list of sys_timeout structures. The sys_timeouts structure holds a
pointer to a linked list of timeouts. This function is called by
the lwIP timeout scheduler and must not return a NULL value.
In a single threaded sys_arch implementation, this function will
simply return a pointer to a global sys_timeouts variable stored in
the sys_arch module.
*/
struct sys_timeouts* sys_arch_timeouts(void)
{
int i;
xTaskHandle pid;
struct timeoutlist *tl;
pid = xTaskGetCurrentTaskHandle();
for(i = 0; i < s_nextthread; i++)
{
tl = &(s_timeoutlist[i]);
if(tl->pid == pid)
{
return &(tl->timeouts);
}
}
// Error
return NULL;
}
/*-----------------------------------------------------------------------------------*/
/* Mutexes*/
/*-----------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/
#if LWIP_COMPAT_MUTEX == 0
/* Create a new mutex*/
err_t sys_mutex_new(sys_mutex_t *mutex) {
*mutex = xSemaphoreCreateMutex();
if(*mutex == NULL)
{
#if SYS_STATS
++lwip_stats.sys.mutex.err;
#endif /* SYS_STATS */
return ERR_MEM;
}
#if SYS_STATS
++lwip_stats.sys.mutex.used;
if (lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used) {
lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used;
}
#endif /* SYS_STATS */
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/* Deallocate a mutex*/
void sys_mutex_free(sys_mutex_t *mutex)
{
#if SYS_STATS
--lwip_stats.sys.mutex.used;
#endif /* SYS_STATS */
vQueueDelete(*mutex);
}
/*-----------------------------------------------------------------------------------*/
/* Lock a mutex*/
void sys_mutex_lock(sys_mutex_t *mutex)
{
sys_arch_sem_wait(*mutex, 0);
}
/*-----------------------------------------------------------------------------------*/
/* Unlock a mutex*/
void sys_mutex_unlock(sys_mutex_t *mutex)
{
xSemaphoreGive(*mutex);
}
#endif /*LWIP_COMPAT_MUTEX*/
/*-----------------------------------------------------------------------------------*/
// TODO
/*-----------------------------------------------------------------------------------*/
/*
Starts a new thread with priority "prio" that will begin its execution in the
function "thread()". The "arg" argument will be passed as an argument to the
thread() function. The id of the new thread is returned. Both the id and
the priority are system dependent.
*/
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio)
{
xTaskHandle CreatedTask;
int result;
if ( s_nextthread < SYS_THREAD_MAX )
{
vPortEnterCritical();
result = xTaskCreate( thread, ( signed portCHAR * ) name, stacksize, arg, prio, &CreatedTask );
// For each task created, store the task handle (pid) in the timers array.
// This scheme doesn't allow for threads to be deleted
s_timeoutlist[s_nextthread++].pid = CreatedTask;
vPortExitCritical();
if(result == pdPASS)
{
return CreatedTask;
}
else
{
return NULL;
}
}
else
{
return NULL;
}
}
/*
This optional function does a "fast" critical region protection and returns
the previous protection level. This function is only called during very short
critical regions. An embedded system which supports ISR-based drivers might
want to implement this function by disabling interrupts. Task-based systems
might want to implement this by using a mutex or disabling tasking. This
function should support recursive calls from the same task or interrupt. In
other words, sys_arch_protect() could be called while already protected. In
that case the return value indicates that it is already protected.
sys_arch_protect() is only required if your port is supporting an operating
system.
*/
sys_prot_t sys_arch_protect(void)
{
vPortEnterCritical();
return 1;
}
/*
This optional function does a "fast" set of critical region protection to the
value specified by pval. See the documentation for sys_arch_protect() for
more information. This function is only required if your port is supporting
an operating system.
*/
void sys_arch_unprotect(sys_prot_t pval)
{
( void ) pval;
vPortExitCritical();
}
/*
* Prints an assertion messages and aborts execution.
*/
void sys_assert( const char *msg )
{
( void ) msg;
/*FSL:only needed for debugging
printf(msg);
printf("\n\r");
*/
vPortEnterCritical( );
for(;;)
;
}

View file

@ -1,66 +0,0 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __SYS_RTXC_H__
#define __SYS_RTXC_H__
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#define SYS_MBOX_NULL (xQueueHandle)0
#define SYS_SEM_NULL (xSemaphoreHandle)0
#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
typedef xSemaphoreHandle sys_sem_t;
typedef xQueueHandle sys_mbox_t;
typedef xTaskHandle sys_thread_t;
typedef struct _sys_arch_state_t
{
// Task creation data.
char cTaskName[configMAX_TASK_NAME_LEN];
unsigned short nStackDepth;
unsigned short nTaskCount;
} sys_arch_state_t;
//extern sys_arch_state_t s_sys_arch_state;
//void sys_set_default_state();
//void sys_set_state(signed char *pTaskName, unsigned short nStackSize);
/* Message queue constants. */
#define archMESG_QUEUE_LENGTH ( 6 )
#endif /* __SYS_RTXC_H__ */

View file

@ -1,366 +0,0 @@
/**
* @file
* Ethernet Interface for standalone applications (without RTOS) - works only for
* ethernet polling mode (polling for ethernet frame reception)
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#include "lwip/mem.h"
#include "netif/etharp.h"
#include "ethernetif.h"
#include "stm32f2x7_eth.h"
#include "main.h"
#include <string.h>
/* Network interface name */
#define IFNAME0 's'
#define IFNAME1 't'
/* Ethernet Rx & Tx DMA Descriptors */
extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
/* Ethernet Driver Receive buffers */
extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
/* Ethernet Driver Transmit buffers */
extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
/* Global pointers to track current transmit and receive descriptors */
extern ETH_DMADESCTypeDef *DMATxDescToSet;
extern ETH_DMADESCTypeDef *DMARxDescToGet;
/* Global pointer for last received frame infos */
extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos;
/**
* 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)
{
#ifdef CHECKSUM_BY_HARDWARE
int i;
#endif
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[0] = MAC_ADDR0;
netif->hwaddr[1] = MAC_ADDR1;
netif->hwaddr[2] = MAC_ADDR2;
netif->hwaddr[3] = MAC_ADDR3;
netif->hwaddr[4] = MAC_ADDR4;
netif->hwaddr[5] = MAC_ADDR5;
/* initialize MAC address in ethernet MAC */
ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr);
/* 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;
/* Initialize Tx Descriptors list: Chain Mode */
ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
/* Initialize Rx Descriptors list: Chain Mode */
ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
#ifdef CHECKSUM_BY_HARDWARE
/* Enable the TCP, UDP and ICMP checksum insertion for the Tx frames */
for(i=0; i<ETH_TXBUFNB; i++)
{
ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
}
#endif
/* Note: TCP, UDP, ICMP checksum checking for received frame are enabled in DMA config */
/* Enable MAC and DMA transmission and reception */
ETH_Start();
}
/**
* 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 availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
err_t errval;
struct pbuf *q;
u8 *buffer = (u8 *)(DMATxDescToSet->Buffer1Addr);
__IO ETH_DMADESCTypeDef *DmaTxDesc;
uint16_t framelength = 0;
uint32_t bufferoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t payloadoffset = 0;
DmaTxDesc = DMATxDescToSet;
bufferoffset = 0;
/* copy frame from pbufs to driver buffers */
for(q = p; q != NULL; q = q->next)
{
/* Is this buffer available? If not, goto error */
if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
{
errval = ERR_BUF;
goto error;
}
/* Get bytes in current lwIP buffer */
byteslefttocopy = q->len;
payloadoffset = 0;
/* Check if the length of data to copy is bigger than Tx buffer size*/
while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE )
{
/* Copy data to Tx buffer*/
memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) );
/* Point to next descriptor */
DmaTxDesc = (ETH_DMADESCTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
/* Check if the buffer is available */
if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
{
errval = ERR_USE;
goto error;
}
buffer = (u8 *)(DmaTxDesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);
framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}
/* Copy the remaining bytes */
memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), byteslefttocopy );
bufferoffset = bufferoffset + byteslefttocopy;
framelength = framelength + byteslefttocopy;
}
/* Note: padding and CRC for transmitted frame
are automatically inserted by DMA */
/* Prepare transmit descriptors to give to DMA*/
ETH_Prepare_Transmit_Descriptors(framelength);
errval = ERR_OK;
error:
/* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
if ((ETH->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
{
/* Clear TUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_TUS;
/* Resume DMA transmission*/
ETH->DMATPDR = 0;
}
return errval;
}
/**
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this ethernetif
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf * low_level_input(struct netif *netif)
{
struct pbuf *p, *q;
uint32_t len;
FrameTypeDef frame;
u8 *buffer;
__IO ETH_DMADESCTypeDef *DMARxDesc;
uint32_t bufferoffset = 0;
uint32_t payloadoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t i=0;
/* get received frame */
frame = ETH_Get_Received_Frame();
/* Obtain the size of the packet and put it into the "len" variable. */
len = frame.length;
buffer = (u8 *)frame.buffer;
/* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p != NULL)
{
DMARxDesc = frame.descriptor;
bufferoffset = 0;
for(q = p; q != NULL; q = q->next)
{
byteslefttocopy = q->len;
payloadoffset = 0;
/* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE )
{
/* Copy data to pbuf*/
memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
/* Point to next descriptor */
DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr);
buffer = (unsigned char *)(DMARxDesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}
/* Copy remaining data in pbuf */
memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), byteslefttocopy);
bufferoffset = bufferoffset + byteslefttocopy;
}
}
/* Release descriptors to DMA */
DMARxDesc =frame.descriptor;
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
{
DMARxDesc->Status = ETH_DMARxDesc_OWN;
DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr);
}
/* Clear Segment_Count */
DMA_RX_FRAME_infos->Seg_Count =0;
/* When Rx Buffer unavailable flag is set: clear it and resume reception */
if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
{
/* Clear RBUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_RBUS;
/* Resume DMA reception */
ETH->DMARPDR = 0;
}
return p;
}
/**
* 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
*/
err_t ethernetif_input(struct netif *netif)
{
err_t err;
struct pbuf *p;
/* move received packet into a new pbuf */
p = low_level_input(netif);
/* no packet could be read, silently ignore this */
if (p == NULL) return ERR_MEM;
/* entry point to the LwIP stack */
err = netif->input(p, netif);
if (err != ERR_OK)
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
}
return err;
}
/**
* 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));
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
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...) */
netif->output = etharp_output;
netif->linkoutput = low_level_output;
/* initialize the hardware */
low_level_init(netif);
return ERR_OK;
}

View file

@ -1,11 +0,0 @@
#ifndef __ETHERNETIF_H__
#define __ETHERNETIF_H__
#include "lwip/err.h"
#include "lwip/netif.h"
err_t ethernetif_init(struct netif *netif);
err_t ethernetif_input(struct netif *netif);
#endif

View file

@ -81,6 +81,7 @@
#include "lwip/autoip.h" #include "lwip/autoip.h"
#include "lwip/dns.h" #include "lwip/dns.h"
#include "netif/etharp.h" #include "netif/etharp.h"
#include "lwip/igmp.h"
#include <string.h> #include <string.h>
@ -343,11 +344,20 @@ dhcp_coarse_tmr()
while (netif != NULL) { while (netif != NULL) {
/* only act on DHCP configured interfaces */ /* only act on DHCP configured interfaces */
if (netif->dhcp != NULL) { if (netif->dhcp != NULL) {
/* Realtek add */
/* Not check t0/t1/t2 when dhcp state is DHCP_OFF */
if(netif->dhcp->state == DHCP_OFF){
netif = netif->next;
continue;
}
/* Realtek add end */
/* timer is active (non zero), and triggers (zeroes) now? */ /* timer is active (non zero), and triggers (zeroes) now? */
if (++netif->dhcp->lease_used == netif->dhcp->t0_timeout) { if (++netif->dhcp->lease_used == netif->dhcp->t0_timeout) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t0 timeout\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t0 timeout\n"));
/* this clients' lease time has expired */ /* this clients' lease time has expired */
igmp_report_groups_leave(netif); // not remove group to make able to report group when dhcp bind
dhcp_release(netif); dhcp_release(netif);
netif->dhcp->seconds_elapsed = sys_now();
dhcp_discover(netif); dhcp_discover(netif);
}else if (netif->dhcp->t2_rebind_time-- == 1) { }else if (netif->dhcp->t2_rebind_time-- == 1) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));
@ -480,6 +490,7 @@ dhcp_t1_timeout(struct netif *netif)
("dhcp_t1_timeout(): must renew\n")); ("dhcp_t1_timeout(): must renew\n"));
/* This slightly different to RFC2131: DHCPREQUEST will be sent from state /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
DHCP_RENEWING, not DHCP_BOUND */ DHCP_RENEWING, not DHCP_BOUND */
dhcp->seconds_elapsed = sys_now();
dhcp_renew(netif); dhcp_renew(netif);
} }
} }
@ -682,6 +693,11 @@ dhcp_start(struct netif *netif)
LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL ); LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL );
} }
#if DHCP_CREATE_RAND_XID && defined(LWIP_SRAND)
/* For each system startup, fill in a random seed with different system ticks. */
LWIP_SRAND();
#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_SRAND) */
/* clear data structure */ /* clear data structure */
memset(dhcp, 0, sizeof(struct dhcp)); memset(dhcp, 0, sizeof(struct dhcp));
/* dhcp_set_state(&dhcp, DHCP_OFF); */ /* dhcp_set_state(&dhcp, DHCP_OFF); */
@ -692,6 +708,7 @@ dhcp_start(struct netif *netif)
return ERR_MEM; return ERR_MEM;
} }
ip_set_option(dhcp->pcb, SOF_BROADCAST); ip_set_option(dhcp->pcb, SOF_BROADCAST);
ip_set_option(dhcp->pcb, SOF_REUSEADDR);
/* set up local and remote port for the pcb */ /* set up local and remote port for the pcb */
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
@ -699,6 +716,7 @@ dhcp_start(struct netif *netif)
udp_recv(dhcp->pcb, dhcp_recv, netif); udp_recv(dhcp->pcb, dhcp_recv, netif);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
/* (re)start the DHCP negotiation */ /* (re)start the DHCP negotiation */
dhcp->seconds_elapsed = sys_now();
result = dhcp_discover(netif); result = dhcp_discover(netif);
if (result != ERR_OK) { if (result != ERR_OK) {
/* free resources allocated above */ /* free resources allocated above */
@ -742,6 +760,7 @@ dhcp_inform(struct netif *netif)
} }
dhcp.pcb = pcb; dhcp.pcb = pcb;
ip_set_option(dhcp.pcb, SOF_BROADCAST); ip_set_option(dhcp.pcb, SOF_BROADCAST);
ip_set_option(dhcp.pcb, SOF_REUSEADDR);
udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));
} }
@ -853,6 +872,9 @@ dhcp_decline(struct netif *netif)
dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&dhcp->server_ip_addr)));
dhcp_option_trailer(dhcp); dhcp_option_trailer(dhcp);
/* resize pbuf to reflect true size of options */ /* resize pbuf to reflect true size of options */
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
@ -1182,6 +1204,21 @@ dhcp_reboot(struct netif *netif)
return result; return result;
} }
/** check if DHCP supplied netif->ip_addr
*
* @param netif the netif to check
* @return 1 if DHCP supplied netif->ip_addr (states BOUND or RENEWING),
* 0 otherwise
*/
u8_t
dhcp_supplied_address(const struct netif *netif)
{
if ((netif != NULL) && (netif->dhcp != NULL)) {
struct dhcp* dhcp = netif->dhcp;
return (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING);
}
return 0;
}
/** /**
* Release a DHCP lease. * Release a DHCP lease.
@ -1194,8 +1231,15 @@ dhcp_release(struct netif *netif)
struct dhcp *dhcp = netif->dhcp; struct dhcp *dhcp = netif->dhcp;
err_t result; err_t result;
u16_t msecs; u16_t msecs;
ip_addr_t server_ip_addr;
u8_t is_dhcp_supplied_address;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n"));
if (dhcp == NULL) {
return ERR_ARG;
}
ip_addr_copy(server_ip_addr, dhcp->server_ip_addr);
is_dhcp_supplied_address = dhcp_supplied_address(netif);
/* idle DHCP client */ /* idle DHCP client */
dhcp_set_state(dhcp, DHCP_OFF); dhcp_set_state(dhcp, DHCP_OFF);
/* clean old DHCP offer */ /* clean old DHCP offer */
@ -1207,15 +1251,24 @@ dhcp_release(struct netif *netif)
ip_addr_set_zero(&dhcp->offered_si_addr); ip_addr_set_zero(&dhcp->offered_si_addr);
#endif /* LWIP_DHCP_BOOTP_FILE */ #endif /* LWIP_DHCP_BOOTP_FILE */
dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
dhcp->t1_renew_time = dhcp->t2_rebind_time = dhcp->lease_used = dhcp->t0_timeout = 0;
if (!is_dhcp_supplied_address) {
/* don't issue release message when address is not dhcp-assigned */
return ERR_OK;
}
/* create and initialize the DHCP message header */ /* create and initialize the DHCP message header */
result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE); result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE);
if (result == ERR_OK) { if (result == ERR_OK) {
dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&server_ip_addr)));
dhcp_option_trailer(dhcp); dhcp_option_trailer(dhcp);
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); udp_sendto_if(dhcp->pcb, dhcp->p_out, &server_ip_addr, DHCP_SERVER_PORT, netif);
dhcp_delete_msg(dhcp); dhcp_delete_msg(dhcp);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n"));
} else { } else {
@ -1751,6 +1804,8 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type)
LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg", LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg",
(dhcp->p_out->len >= sizeof(struct dhcp_msg))); (dhcp->p_out->len >= sizeof(struct dhcp_msg)));
/* DHCP_REQUEST should reuse 'xid' from DHCPOFFER */
if (message_type != DHCP_REQUEST) {
/* reuse transaction identifier in retransmissions */ /* reuse transaction identifier in retransmissions */
if (dhcp->tries == 0) { if (dhcp->tries == 0) {
#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) #if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
@ -1760,6 +1815,7 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type)
#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ #endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
} }
dhcp->xid = xid; dhcp->xid = xid;
}
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
("transaction id xid(%"X32_F")\n", xid)); ("transaction id xid(%"X32_F")\n", xid));
@ -1771,13 +1827,17 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type)
dhcp->msg_out->hlen = netif->hwaddr_len; dhcp->msg_out->hlen = netif->hwaddr_len;
dhcp->msg_out->hops = 0; dhcp->msg_out->hops = 0;
dhcp->msg_out->xid = htonl(dhcp->xid); dhcp->msg_out->xid = htonl(dhcp->xid);
if ((message_type == DHCP_DISCOVER) || (message_type == DHCP_REQUEST)) {
dhcp->msg_out->secs = (uint16_t)((sys_now() - dhcp->seconds_elapsed) / configTICK_RATE_HZ);
} else {
dhcp->msg_out->secs = 0; dhcp->msg_out->secs = 0;
}
/* we don't need the broadcast flag since we can receive unicast traffic /* we don't need the broadcast flag since we can receive unicast traffic
before being fully configured! */ before being fully configured! */
dhcp->msg_out->flags = 0; dhcp->msg_out->flags = 0;
ip_addr_set_zero(&dhcp->msg_out->ciaddr); ip_addr_set_zero(&dhcp->msg_out->ciaddr);
/* set ciaddr to netif->ip_addr based on message_type and state */ /* set ciaddr to netif->ip_addr based on message_type and state */
if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || (message_type == DHCP_RELEASE) ||
((message_type == DHCP_REQUEST) && /* DHCP_BOUND not used for sending! */ ((message_type == DHCP_REQUEST) && /* DHCP_BOUND not used for sending! */
((dhcp->state==DHCP_RENEWING) || dhcp->state==DHCP_REBINDING))) { ((dhcp->state==DHCP_RENEWING) || dhcp->state==DHCP_REBINDING))) {
ip_addr_copy(dhcp->msg_out->ciaddr, netif->ip_addr); ip_addr_copy(dhcp->msg_out->ciaddr, netif->ip_addr);

File diff suppressed because it is too large Load diff

View file

@ -57,6 +57,9 @@
#include "lwip/lwip_timers.h" #include "lwip/lwip_timers.h"
#include "netif/etharp.h" #include "netif/etharp.h"
#include "lwip/api.h" #include "lwip/api.h"
#if IP_NAPT
#include "lwip/lwip_napt.h"
#endif
/* Compile-time sanity checks for configuration errors. /* Compile-time sanity checks for configuration errors.
* These can be done independently of LWIP_DEBUG, without penalty. * These can be done independently of LWIP_DEBUG, without penalty.
@ -329,4 +332,8 @@ lwip_init(void)
#if LWIP_TIMERS #if LWIP_TIMERS
sys_timeouts_init(); sys_timeouts_init();
#endif /* LWIP_TIMERS */ #endif /* LWIP_TIMERS */
#if IP_NAPT && !IP_NAPT_DYNAMIC
ip_napt_init(IP_NAPT_MAX, IP_PORTMAP_MAX);
#endif /* IP_NAPT */
} }

View file

@ -271,13 +271,27 @@ igmp_report_groups(struct netif *netif)
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", netif)); LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", netif));
while (group != NULL) { while (group != NULL) {
if (group->netif == netif) { if ((group->netif == netif) && (!ip_addr_cmp(&group->group_address, &allsystems))) {
igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR); igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
} }
group = group->next; group = group->next;
} }
} }
/* Realtek added to only send igmp leave, but not remove group */
void
igmp_report_groups_leave(struct netif *netif)
{
struct igmp_group *group = igmp_group_list;
while (group != NULL) {
if ((group->netif == netif) && (!ip_addr_cmp(&group->group_address, &allsystems)) && (group->last_reporter_flag)) {
igmp_send(group, IGMP_LEAVE_GROUP);
}
group = group->next;
}
}
/** /**
* Search for a group in the global igmp_group_list * Search for a group in the global igmp_group_list
* *

View file

@ -223,7 +223,7 @@ ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed)
/* @todo Can't we simply remove the last datagram in the /* @todo Can't we simply remove the last datagram in the
* linked list behind reassdatagrams? * linked list behind reassdatagrams?
*/ */
struct ip_reassdata *r, *oldest, *prev; struct ip_reassdata *r, *oldest, *prev, *oldest_prev;
int pbufs_freed = 0, pbufs_freed_current; int pbufs_freed = 0, pbufs_freed_current;
int other_datagrams; int other_datagrams;
@ -232,6 +232,7 @@ ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed)
do { do {
oldest = NULL; oldest = NULL;
prev = NULL; prev = NULL;
oldest_prev = NULL;
other_datagrams = 0; other_datagrams = 0;
r = reassdatagrams; r = reassdatagrams;
while (r != NULL) { while (r != NULL) {
@ -240,9 +241,11 @@ ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed)
other_datagrams++; other_datagrams++;
if (oldest == NULL) { if (oldest == NULL) {
oldest = r; oldest = r;
oldest_prev = prev;
} else if (r->timer <= oldest->timer) { } else if (r->timer <= oldest->timer) {
/* older than the previous oldest */ /* older than the previous oldest */
oldest = r; oldest = r;
oldest_prev = prev;
} }
} }
if (r->next != NULL) { if (r->next != NULL) {
@ -251,7 +254,7 @@ ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed)
r = r->next; r = r->next;
} }
if (oldest != NULL) { if (oldest != NULL) {
pbufs_freed_current = ip_reass_free_complete_datagram(oldest, prev); pbufs_freed_current = ip_reass_free_complete_datagram(oldest, oldest_prev);
pbufs_freed += pbufs_freed_current; pbufs_freed += pbufs_freed_current;
} }
} while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1)); } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1));

View file

@ -62,7 +62,7 @@
/** The one and only timeout list */ /** The one and only timeout list */
static struct sys_timeo *next_timeout; static struct sys_timeo *next_timeout;
#if NO_SYS #if NO_SYS || CONFIG_DYNAMIC_TICKLESS
static u32_t timeouts_last_time; static u32_t timeouts_last_time;
#endif /* NO_SYS */ #endif /* NO_SYS */
@ -242,7 +242,7 @@ void sys_timeouts_init(void)
sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
#endif /* LWIP_DNS */ #endif /* LWIP_DNS */
#if NO_SYS #if NO_SYS || CONFIG_DYNAMIC_TICKLESS
/* Initialise timestamp for sys_check_timeouts */ /* Initialise timestamp for sys_check_timeouts */
timeouts_last_time = sys_now(); timeouts_last_time = sys_now();
#endif #endif
@ -437,6 +437,53 @@ sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
time_needed = SYS_ARCH_TIMEOUT; time_needed = SYS_ARCH_TIMEOUT;
} }
#if CONFIG_DYNAMIC_TICKLESS
if (time_needed == SYS_ARCH_TIMEOUT) {
/* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
could be fetched. We should now call the timeout handler and
deallocate the memory allocated for the timeout. */
u8_t had_one;
u32_t now;
u32_t diff;
now = sys_now();
/* this cares for wraparounds */
diff = now - timeouts_last_time;
do
{
had_one = 0;
tmptimeout = next_timeout;
if (tmptimeout && (tmptimeout->time <= diff)) {
/* timeout has expired */
had_one = 1;
timeouts_last_time = now;
diff -= tmptimeout->time;
next_timeout = tmptimeout->next;
handler = tmptimeout->h;
arg = tmptimeout->arg;
#if LWIP_DEBUG_TIMERNAMES
if (handler != NULL) {
LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n",
tmptimeout->handler_name, arg));
}
#endif /* LWIP_DEBUG_TIMERNAMES */
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
if (handler != NULL) {
LOCK_TCPIP_CORE();
handler(arg);
UNLOCK_TCPIP_CORE();
}
}
/* repeat until all expired timers have been called */
}while(had_one);
LWIP_TCPIP_THREAD_ALIVE();
/* We try again to fetch a message from the mbox. */
goto again;
}
#else
if (time_needed == SYS_ARCH_TIMEOUT) { if (time_needed == SYS_ARCH_TIMEOUT) {
/* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
could be fetched. We should now call the timeout handler and could be fetched. We should now call the timeout handler and
@ -463,7 +510,9 @@ sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
/* We try again to fetch a message from the mbox. */ /* We try again to fetch a message from the mbox. */
goto again; goto again;
} else { }
#endif
else {
/* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
occured. The time variable is set to the number of occured. The time variable is set to the number of
milliseconds we waited for the message. */ milliseconds we waited for the message. */

View file

@ -274,6 +274,7 @@ void
mem_init(void) mem_init(void)
{ {
struct mem *mem; struct mem *mem;
LWIP_ASSERT("Sanity check alignment", LWIP_ASSERT("Sanity check alignment",
(SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0); (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0);

View file

@ -1012,6 +1012,8 @@ tcp_slowtmr_start:
++pcb_remove; ++pcb_remove;
} }
/* If the PCB should be removed, do it. */ /* If the PCB should be removed, do it. */
if (pcb_remove) { if (pcb_remove) {
struct tcp_pcb *pcb2; struct tcp_pcb *pcb2;

View file

@ -96,6 +96,8 @@ void igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest);
err_t igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); err_t igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr);
err_t igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); err_t igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr);
void igmp_tmr(void); void igmp_tmr(void);
void igmp_report_groups_leave(struct netif *netif);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -214,6 +214,12 @@ void ip_debug_print(struct pbuf *p);
#define ip_debug_print(p) #define ip_debug_print(p)
#endif /* IP_DEBUG */ #endif /* IP_DEBUG */
#if NAPT_DEBUG
void napt_debug_print()ICACHE_FLASH_ATTR;
#else
#define napt_debug_print(p)
#endif /* NAPT_DEBUG */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -75,8 +75,7 @@
LWIP_PLATFORM_ASSERT(message); handler;}} while(0) LWIP_PLATFORM_ASSERT(message); handler;}} while(0)
#endif /* LWIP_ERROR */ #endif /* LWIP_ERROR */
#if LWIP_DEBUG #if LWIP_DEBUG //#ifdef LWIP_DEBUG
//#ifdef LWIP_DEBUG
/** print debug message only if debug message type is enabled... /** print debug message only if debug message type is enabled...
* AND is of correct type AND is at least LWIP_DBG_LEVEL * AND is of correct type AND is at least LWIP_DBG_LEVEL
*/ */

View file

@ -68,6 +68,7 @@ struct dhcp
ip_addr_t offered_si_addr; ip_addr_t offered_si_addr;
char boot_file_name[DHCP_FILE_LEN]; char boot_file_name[DHCP_FILE_LEN];
#endif /* LWIP_DHCP_BOOTPFILE */ #endif /* LWIP_DHCP_BOOTPFILE */
u32_t seconds_elapsed;
}; };
/* MUST be compiled with "pack structs" or equivalent! */ /* MUST be compiled with "pack structs" or equivalent! */

View file

@ -70,45 +70,6 @@ extern "C" {
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ #define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ #define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
/* DNS protocol flags */
#define DNS_FLAG1_RESPONSE 0x80
#define DNS_FLAG1_OPCODE_STATUS 0x10
#define DNS_FLAG1_OPCODE_INVERSE 0x08
#define DNS_FLAG1_OPCODE_STANDARD 0x00
#define DNS_FLAG1_AUTHORATIVE 0x04
#define DNS_FLAG1_TRUNC 0x02
#define DNS_FLAG1_RD 0x01
#define DNS_FLAG2_RA 0x80
#define DNS_FLAG2_ERR_MASK 0x0f
#define DNS_FLAG2_ERR_NONE 0x00
#define DNS_FLAG2_ERR_NAME 0x03
/* DNS protocol states */
#define DNS_STATE_UNUSED 0
#define DNS_STATE_NEW 1
#define DNS_STATE_ASKING 2
#define DNS_STATE_DONE 3
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** DNS message header */
struct dns_hdr {
PACK_STRUCT_FIELD(u16_t id);
PACK_STRUCT_FIELD(u8_t flags1);
PACK_STRUCT_FIELD(u8_t flags2);
PACK_STRUCT_FIELD(u16_t numquestions);
PACK_STRUCT_FIELD(u16_t numanswers);
PACK_STRUCT_FIELD(u16_t numauthrr);
PACK_STRUCT_FIELD(u16_t numextrarr);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_DNS_HDR 12
/* The size used for the next line is rather a hack, but it prevents including socket.h in all files /* The size used for the next line is rather a hack, but it prevents including socket.h in all files
that include memp.h, and that would possibly break portability (since socket.h defines some types that include memp.h, and that would possibly break portability (since socket.h defines some types
and constants possibly already define by the OS). and constants possibly already define by the OS).
@ -148,6 +109,7 @@ void dns_setserver(u8_t numdns, ip_addr_t *dnsserver);
ip_addr_t dns_getserver(u8_t numdns); ip_addr_t dns_getserver(u8_t numdns);
err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr,
dns_found_callback found, void *callback_arg); dns_found_callback found, void *callback_arg);
void dns_reset_ttl();
#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC #if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC
int dns_local_removehost(const char *hostname, const ip_addr_t *addr); int dns_local_removehost(const char *hostname, const ip_addr_t *addr);

View file

@ -0,0 +1,115 @@
#ifndef __LWIP_NAPT_H__
#define __LWIP_NAPT_H__
#include "lwip/opt.h"
#ifdef __cplusplus
extern "C" {
#endif
#if IP_FORWARD
#if IP_NAPT
/* Default size of the tables used for NAPT */
#define IP_NAPT_MAX 512
#define IP_PORTMAP_MAX 32
/* Timeouts in sec for the various protocol types */
#define IP_NAPT_TIMEOUT_MS_TCP (30*60*1000)
#define IP_NAPT_TIMEOUT_MS_TCP_DISCON (20*1000)
#define IP_NAPT_TIMEOUT_MS_UDP (2*1000)
#define IP_NAPT_TIMEOUT_MS_ICMP (2*1000)
#define IP_NAPT_PORT_RANGE_START 49152
#define IP_NAPT_PORT_RANGE_END 61439
struct napt_table {
u32_t last;
u32_t src;
u32_t dest;
u16_t sport;
u16_t dport;
u16_t mport;
u8_t proto;
u8_t fin1 : 1;
u8_t fin2 : 1;
u8_t finack1 : 1;
u8_t finack2 : 1;
u8_t synack : 1;
u8_t rst : 1;
u16_t next, prev;
};
struct portmap_table {
u32_t maddr;
u32_t daddr;
u16_t mport;
u16_t dport;
u8_t proto;
u8 valid;
};
extern struct portmap_table *ip_portmap_table;
/**
* Allocates and initializes the NAPT tables.
*
* @param max_nat max number of enties in the NAPT table (use IP_NAPT_MAX if in doubt)
* @param max_portmap max number of enties in the NAPT table (use IP_PORTMAP_MAX if in doubt)
*/
void
ip_napt_init(uint16_t max_nat, uint8_t max_portmap);
/**
* Enable/Disable NAPT for a specified interface.
*
* @param addr ip address of the interface
* @param enable non-zero to enable NAPT, or 0 to disable.
*/
void
ip_napt_enable(u32_t addr, int enable);
/**
* Enable/Disable NAPT for a specified interface.
*
* @param netif number of the interface
* @param enable non-zero to enable NAPT, or 0 to disable.
*/
void
ip_napt_enable_no(u8_t number, int enable);
/**
* Register port mapping on the external interface to internal interface.
* When the same port mapping is registered again, the old mapping is overwritten.
* In this implementation, only 1 unique port mapping can be defined for each target address/port.
*
* @param proto target protocol
* @param maddr ip address of the external interface
* @param mport mapped port on the external interface, in host byte order.
* @param daddr destination ip address
* @param dport destination port, in host byte order.
*/
u8_t
ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport);
/**
* Unregister port mapping on the external interface to internal interface.
*
* @param proto target protocol
* @param maddr ip address of the external interface
*/
u8_t
ip_portmap_remove(u8_t proto, u16_t mport);
#endif /* IP_NAPT */
#endif /* IP_FORWARD */
#ifdef __cplusplus
}
#endif
#endif /* __LWIP_NAPT_H__ */

View file

@ -230,6 +230,9 @@ struct netif {
u16_t loop_cnt_current; u16_t loop_cnt_current;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */ #endif /* LWIP_LOOPBACK_MAX_PBUFS */
#endif /* ENABLE_LOOPBACK */ #endif /* ENABLE_LOOPBACK */
#if IP_NAPT
u8_t napt;
#endif
}; };
#if LWIP_SNMP #if LWIP_SNMP

View file

@ -508,6 +508,14 @@
#define IP_FORWARD 0 #define IP_FORWARD 0
#endif #endif
/**
* IP_NAPT==1: Enables the ability to do Network Address Port Translation (NAPT)
* on forwarded packets. This only makes sense with IP_FORWARD==1.
*/
#ifndef IP_NAPT
#define IP_NAPT 0
#endif
/** /**
* IP_OPTIONS_ALLOWED: Defines the behavior for IP options. * IP_OPTIONS_ALLOWED: Defines the behavior for IP options.
* IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped.
@ -1297,7 +1305,7 @@
* PPP_THREAD_NAME: The name assigned to the pppInputThread. * PPP_THREAD_NAME: The name assigned to the pppInputThread.
*/ */
#ifndef PPP_THREAD_NAME #ifndef PPP_THREAD_NAME
#define PPP_THREAD_NAME "pppInputThread" #define PPP_THREAD_NAME "pppIThrd"
#endif #endif
/** /**
@ -2131,4 +2139,5 @@
#define DNS_DEBUG LWIP_DBG_OFF #define DNS_DEBUG LWIP_DBG_OFF
#endif #endif
#endif /* __LWIP_OPT_H__ */ #endif /* __LWIP_OPT_H__ */

View file

@ -363,7 +363,6 @@ int lwip_last_err_socket(int s); // errno
#define select(a,b,c,d,e) lwip_select(a,b,c,d,e) #define select(a,b,c,d,e) lwip_select(a,b,c,d,e)
#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c) #define ioctlsocket(a,b,c) lwip_ioctl(a,b,c)
#if LWIP_POSIX_SOCKETS_IO_NAMES #if LWIP_POSIX_SOCKETS_IO_NAMES
#define read(a,b,c) lwip_read(a,b,c) #define read(a,b,c) lwip_read(a,b,c)
#define write(a,b,c) lwip_write(a,b,c) #define write(a,b,c) lwip_write(a,b,c)

View file

@ -140,6 +140,12 @@ PACK_STRUCT_END
#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */ #define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */
#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */ #define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */
#define ETHTYPE_RARP 0x8035U
#define RARP_REQUEST 3
#define RARP_REPLY 4
void rarp_retrieve_hook_callback(void (*callback)(u8_t *, u8_t *));
/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables /** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables
* or known to be 32-bit aligned within the protocol header. */ * or known to be 32-bit aligned within the protocol header. */
#ifndef ETHADDR32_COPY #ifndef ETHADDR32_COPY

View file

@ -844,6 +844,72 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
pbuf_free(p); pbuf_free(p);
} }
static void (*rarp_retrieve_cb)(u8_t *, u8_t *) = NULL;
void rarp_retrieve_hook_callback(void (*callback)(u8_t *, u8_t *)) {
rarp_retrieve_cb = callback;
}
static void
etharp_rarp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
{
struct etharp_hdr *hdr;
struct eth_hdr *ethhdr;
#if LWIP_AUTOIP
const u8_t * ethdst_hwaddr;
#endif /* LWIP_AUTOIP */
LWIP_ERROR("netif != NULL", (netif != NULL), return;);
/* drop short ARP packets: we have to check for p->len instead of p->tot_len here
since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */
if (p->len < SIZEOF_ETHARP_PACKET) {
ETHARP_STATS_INC(etharp.lenerr);
ETHARP_STATS_INC(etharp.drop);
pbuf_free(p);
return;
}
ethhdr = (struct eth_hdr *)p->payload;
hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
/* RFC 826 "Packet Reception": */
if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) ||
(hdr->hwlen != ETHARP_HWADDR_LEN) ||
(hdr->protolen != sizeof(ip_addr_t)) ||
(hdr->proto != PP_HTONS(ETHTYPE_IP))) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen));
ETHARP_STATS_INC(etharp.proterr);
ETHARP_STATS_INC(etharp.drop);
pbuf_free(p);
return;
}
ETHARP_STATS_INC(etharp.recv);
switch (hdr->opcode) {
/* RARP request? */
case PP_HTONS(RARP_REQUEST):
LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_rarp_input: incoming RARP request\n"));
break;
case PP_HTONS(RARP_REPLY):
if(rarp_retrieve_cb != NULL)
rarp_retrieve_cb((u8_t *)&hdr->dipaddr, (u8_t *)&hdr->dhwaddr.addr);
break;
default:
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_rarp_input: RARP unknown opcode type %"S16_F"\n", htons(hdr->opcode)));
ETHARP_STATS_INC(etharp.err);
break;
}
/* free ARP packet */
pbuf_free(p);
}
/** Just a small helper function that sends a pbuf to an ethernet address /** Just a small helper function that sends a pbuf to an ethernet address
* in the arp_table specified by the index 'arp_idx'. * in the arp_table specified by the index 'arp_idx'.
*/ */
@ -1243,6 +1309,9 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
hdr->hwlen = ETHARP_HWADDR_LEN; hdr->hwlen = ETHARP_HWADDR_LEN;
hdr->protolen = sizeof(ip_addr_t); hdr->protolen = sizeof(ip_addr_t);
if((opcode == RARP_REQUEST) | (opcode == RARP_REPLY))
ethhdr->type = PP_HTONS(ETHTYPE_RARP);
else
ethhdr->type = PP_HTONS(ETHTYPE_ARP); ethhdr->type = PP_HTONS(ETHTYPE_ARP);
/* send ARP query */ /* send ARP query */
result = netif->linkoutput(netif, p); result = netif->linkoutput(netif, p);
@ -1380,6 +1449,14 @@ ethernet_input(struct pbuf *p, struct netif *netif)
/* pass p to ARP module */ /* pass p to ARP module */
etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p); etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p);
break; break;
case PP_HTONS(ETHTYPE_RARP):
if (!(netif->flags & NETIF_FLAG_ETHARP)) {
goto free_and_return;
}
/* pass p to RARP module */
etharp_rarp_input(netif, (struct eth_addr*)(netif->hwaddr), p);
break;
#endif /* LWIP_ARP */ #endif /* LWIP_ARP */
#if PPPOE_SUPPORT #if PPPOE_SUPPORT
case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */ case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */

View file

@ -53,7 +53,10 @@ typedef enum _SHA2_TYPE_ {
extern int rtl_cryptoEngine_init(void); extern int rtl_cryptoEngine_init(void);
extern void rtl_cryptoEngine_info(void); extern void rtl_cryptoEngine_info(void);
extern _LONG_CALL_ int __rtl_cryptoEngine_exit_v1_00(void);
extern int init_status;
#define rtl_cryptoEngine_deinit __rtl_cryptoEngine_exit_v1_00
// //
// Authentication // Authentication

View file

@ -37,6 +37,7 @@ endif
PICK = $(TOOLS_PATH)pick$(EXE) PICK = $(TOOLS_PATH)pick$(EXE)
PADDING = $(TOOLS_PATH)padding$(EXE) PADDING = $(TOOLS_PATH)padding$(EXE)
CHCKSUM = $(TOOLS_PATH)checksum$(EXE) CHCKSUM = $(TOOLS_PATH)checksum$(EXE)
IMAGETOOL = $(TOOLS_PATH)rtlaimage$(EXE)
# openocd tools # openocd tools
OPENOCD = $(OPENOCD_PATH)openocd.exe OPENOCD = $(OPENOCD_PATH)openocd.exe
@ -72,11 +73,9 @@ NMAPFILE = $(OBJ_DIR)/$(TARGET).nmap
RAM1_IMAGE ?= $(BIN_DIR)/ram_1.bin RAM1_IMAGE ?= $(BIN_DIR)/ram_1.bin
RAM1P_IMAGE ?= $(BIN_DIR)/ram_1.p.bin RAM1P_IMAGE ?= $(BIN_DIR)/ram_1.p.bin
RAM1R_IMAGE ?= $(BIN_DIR)/ram_1.r.bin
RAM2_IMAGE = $(BIN_DIR)/ram_2.bin RAM2_IMAGE = $(BIN_DIR)/ram_2.bin
RAM2P_IMAGE = $(BIN_DIR)/ram_2.p.bin RAM2P_IMAGE = $(BIN_DIR)/ram_2.p.bin
RAM2NS_IMAGE = $(BIN_DIR)/ram_2.ns.bin
RAM3_IMAGE = $(BIN_DIR)/sdram.bin RAM3_IMAGE = $(BIN_DIR)/sdram.bin
RAM3P_IMAGE = $(BIN_DIR)/sdram.p.bin RAM3P_IMAGE = $(BIN_DIR)/sdram.p.bin
@ -89,18 +88,28 @@ OTA_IMAGE = $(BIN_DIR)/ota.bin
mp: FLASH_IMAGE = $(BIN_DIR)/ram_all_mp.bin mp: FLASH_IMAGE = $(BIN_DIR)/ram_all_mp.bin
mp: OTA_IMAGE = $(BIN_DIR)/ota_mp.bin mp: OTA_IMAGE = $(BIN_DIR)/ota_mp.bin
TST_IMAGE = $(BIN_DIR)/ram_2.bin
.PHONY: genbin1 genbin23 flashburn reset test readfullflash flashboot flashwebfs flash_OTA runram runsdram .PHONY: genbin flashburn reset test readfullflash flashboot flashwebfs flash_OTA runram runsdram
.NOTPARALLEL: all mp genbin1 genbin23 flashburn reset test readfullflash _endgenbin flashwebfs flash_OTA .NOTPARALLEL: all mp genbin1 genbin23 flashburn reset test readfullflash _endgenbin flashwebfs flash_OTA
all: $(ELFFILE) $(OTA_IMAGE) $(FLASH_IMAGE) _endgenbin all: $(ELFFILE) $(FLASH_IMAGE) _endgenbin
mp: $(ELFFILE) $(OTA_IMAGE) $(FLASH_IMAGE) _endgenbin mp: $(ELFFILE) $(FLASH_IMAGE) _endgenbin
genbin1: $(ELFFILE) $(RAM1P_IMAGE) genbin: $(ELFFILE) $(FLASH_IMAGE) _endgenbin
genbin23: $(ELFFILE) $(OTA_IMAGE) $(FLASH_IMAGE) _endgenbin $(ELFFILE):
$(error Falsher: file $@ not found)
$(NMAPFILE): $(ELFFILE)
@echo "==========================================================="
@echo "Build names map file"
@echo $@
@$(NM) $< | sort > $@
# @echo "==========================================================="
$(FLASH_IMAGE):$(ELFFILE)
@echo "==========================================================="
$(IMAGETOOL) -a -r -o $(BIN_DIR)/ $(ELFFILE)
_endgenbin: _endgenbin:
@echo "-----------------------------------------------------------" @echo "-----------------------------------------------------------"
@ -233,14 +242,14 @@ reset:
runram: runram:
@$(OPENOCD) -f interface/$(FLASHER).cfg -c 'transport select swd' -c 'adapter_khz 1000' \ @$(OPENOCD) -f interface/$(FLASHER).cfg -c 'transport select swd' -c 'adapter_khz 1000' \
-f $(FLASHER_PATH)rtl8710.ocd -c 'init' -c 'reset halt' -c 'adapter_khz $(FLASHER_SPEED)' \ -f $(FLASHER_PATH)rtl8710.ocd -c 'init' -c 'reset halt' -c 'adapter_khz $(FLASHER_SPEED)' \
-c 'load_image $(RAM1R_IMAGE) 0x10000bc8 bin' \ -c 'load_image $(RAM1_IMAGE) 0x10000bc8 bin' \
-c 'load_image $(RAM2_IMAGE) 0x10006000 bin' \ -c 'load_image $(RAM2_IMAGE) 0x10006000 bin' \
-c 'mww 0x40000210 0x20111157' -c 'rtl8710_reboot' -c shutdown -c 'mww 0x40000210 0x20111157' -c 'rtl8710_reboot' -c shutdown
runsdram: runsdram:
@$(OPENOCD) -f interface/$(FLASHER).cfg -c 'transport select swd' -c 'adapter_khz 1000' \ @$(OPENOCD) -f interface/$(FLASHER).cfg -c 'transport select swd' -c 'adapter_khz 1000' \
-f $(FLASHER_PATH)rtl8710.ocd -c 'init' -c 'reset halt' -c 'adapter_khz $(FLASHER_SPEED)' \ -f $(FLASHER_PATH)rtl8710.ocd -c 'init' -c 'reset halt' -c 'adapter_khz $(FLASHER_SPEED)' \
-c 'load_image $(RAM1R_IMAGE) 0x10000bc8 bin' \ -c 'load_image $(RAM1_IMAGE) 0x10000bc8 bin' \
-c 'load_image $(RAM2_IMAGE) 0x10006000 bin' \ -c 'load_image $(RAM2_IMAGE) 0x10006000 bin' \
-c 'boot_load_srdam $(RAM3_IMAGE) 0x30000000' \ -c 'boot_load_srdam $(RAM3_IMAGE) 0x30000000' \
-c shutdown -c shutdown
@ -248,120 +257,6 @@ runsdram:
endif endif
endif endif
$(NMAPFILE): $(ELFFILE)
@echo "==========================================================="
@echo "Build names map file"
@echo $@
@$(NM) $< | sort > $@
# @echo "==========================================================="
$(FLASH_IMAGE): $(RAM1P_IMAGE) $(RAM2P_IMAGE) $(RAM3P_IMAGE)
@echo "==========================================================="
@echo "Make Flash image ($(FLASH_IMAGE))"
# @echo "==========================================================="
@mkdir -p $(BIN_DIR)
@rm -f $(FLASH_IMAGE)
@cat $(RAM1P_IMAGE) > $(FLASH_IMAGE)
# @chmod 777 $(FLASH_IMAGE)
ifdef PADDINGSIZE
@$(PADDING) $(PADDINGSIZE) 0xFF $(FLASH_IMAGE)
endif
@cat $(RAM2P_IMAGE) >> $(FLASH_IMAGE)
@cat $(RAM3P_IMAGE) >> $(FLASH_IMAGE)
# @echo "Image ($(FLASH_IMAGE)) size $(shell printf '%d\n' $$(( $$(stat --printf="%s" $(FLASH_IMAGE)) )) ) bytes"
# @echo "==========================================================="
# @rm $(BIN_DIR)/ram_*.p.bin
$(OTA_IMAGE): $(RAM2NS_IMAGE) $(RAM3_IMAGE)
@echo "==========================================================="
@echo "Make OTA image ($(OTA_IMAGE))"
@rm -f $(OTA_IMAGE)
@cat $(RAM2NS_IMAGE) > $(OTA_IMAGE)
@cat $(RAM3P_IMAGE) >> $(OTA_IMAGE)
# @chmod 777 $(OTA_IMAGE)
@$(CHCKSUM) $(OTA_IMAGE) || true
# @echo "==========================================================="
$(RAM1P_IMAGE): $(ELFFILE) $(NMAPFILE)
@echo "==========================================================="
@echo "Create image1r ($(RAM1R_IMAGE))"
# @echo "===========================================================" .bootloader
ifdef COMPILED_BOOT
@mkdir -p $(BIN_DIR)
@rm -f $(RAM1_IMAGE) $(RAM1R_IMAGE)
ifdef COMPILED_BOOT_BIN
@$(eval RAM1_START_ADDR := $(shell grep _binary_build_bin_ram_1_r_bin_start $(NMAPFILE) | awk '{print $$1}'))
@$(eval RAM1_END_ADDR := $(shell grep _binary_build_bin_ram_1_r_bin_end $(NMAPFILE) | awk '{print $$1}'))
else
@$(eval RAM1_START_ADDR := $(shell grep __ram_image1_text_start__ $(NMAPFILE) | awk '{print $$1}'))
@$(eval RAM1_END_ADDR := $(shell grep __ram_image1_text_end__ $(NMAPFILE) | awk '{print $$1}'))
endif
$(if $(RAM1_START_ADDR),,$(error "Not found __ram_image1_text_start__!"))
$(if $(RAM1_END_ADDR),,$(error "Not found __ram_image1_text_end__!"))
ifeq ($(RAM1_START_ADDR),$(RAM1_END_ADDR))
ifdef COMPILED_BOOT_BIN
$(OBJCOPY) --change-section-address .boot.head=0x10000ba8 -j .boot.head -j .bootloader -Obinary $(ELFFILE) $(RAM1P_IMAGE)
else
# $(OBJCOPY) -j .rom_ram -Obinary $(ELFFILE) $(RAM_IMAGE)
$(OBJCOPY) -j .ram.start.table -j .ram_image1.text -Obinary $(ELFFILE) $(RAM1R_IMAGE)
$(PICK) 0x$(RAM1_START_ADDR) 0x$(RAM1_END_ADDR) $(RAM1R_IMAGE) $(RAM1P_IMAGE) head+reset_offset 0x0B000
endif
else
$(error "BOOT-image size = 0")
# $(error Flasher: COMPILE_BOOT = No)
endif
else
@if [ -s $(RAM1R_IMAGE) ]; then echo "Use external $(RAM1R_IMAGE)!"; fi
endif
$(RAM2P_IMAGE): $(ELFFILE) $(NMAPFILE)
@echo "==========================================================="
@echo "Create image2p ($(RAM2P_IMAGE))"
# @echo "==========================================================="
@mkdir -p $(BIN_DIR)
@rm -f $(RAM2_IMAGE) $(RAM2P_IMAGE)
@$(eval RAM2_START_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _start__ | awk '{print $$1}'))
@$(eval RAM2_END_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _end__ | awk '{print $$1}'))
$(if $(RAM2_START_ADDR),,$(error "Not found __ram_image2_text_start__!"))
$(if $(RAM2_END_ADDR),,$(error "Not found __ram_image2_text_end__!"))
@$(OBJCOPY) -j .image2.start.table -j .ram_image2.text -j .ram_image2.rodata -j .ram.data -Obinary $(ELFFILE) $(RAM2_IMAGE)
@$(PICK) 0x$(RAM2_START_ADDR) 0x$(RAM2_END_ADDR) $(RAM2_IMAGE) $(RAM2P_IMAGE) body+reset_offset+sig
$(RAM2NS_IMAGE):$(ELFFILE) $(NMAPFILE)
@echo "==========================================================="
@echo "Create image2ns ($(RAM2NS_IMAGE))"
# @echo "==========================================================="
mkdir -p $(BIN_DIR)
rm -f $(RAM2_IMAGE) $(RAM2NS_IMAGE)
$(eval RAM2_START_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _start__ | awk '{print $$1}'))
$(eval RAM2_END_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _end__ | awk '{print $$1}'))
$(if $(RAM2_START_ADDR),,$(error "Not found __ram_image2_text_start__!"))
$(if $(RAM2_END_ADDR),,$(error "Not found __ram_image2_text_end__!"))
$(OBJCOPY) -j .image2.start.table -j .ram_image2.text -j .ram_image2.rodata -j .ram.data -Obinary $(ELFFILE) $(RAM2_IMAGE)
$(PICK) 0x$(RAM2_START_ADDR) 0x$(RAM2_END_ADDR) $(RAM2_IMAGE) $(RAM2NS_IMAGE) body+reset_offset
$(RAM3_IMAGE): $(ELFFILE) $(NMAPFILE)
@echo "==========================================================="
@echo "Create image3 (SDRAM, $(RAM3P_IMAGE))"
# @echo "==========================================================="
@mkdir -p $(BIN_DIR)
@rm -f $(RAM3_IMAGE) $(RAM3P_IMAGE)
@$(eval RAM3_START_ADDR = $(shell grep __sdram_data_ $(NMAPFILE) | grep _start__ | awk '{print $$1}'))
@$(eval RAM3_END_ADDR = $(shell grep __sdram_data_ $(NMAPFILE) | grep _end__ | awk '{print $$1}'))
$(if $(RAM3_START_ADDR),,$(error "Not found __sdram_data_start__!"))
$(if $(RAM3_END_ADDR),,$(error "Not found __sdram_data_end__!"))
#ifneq ($(RAM3_START_ADDR),$(RAM3_END_ADDR))
@echo $(RAM3_START_ADDR) $(RAM3_END_ADDR)
@$(OBJCOPY) -j .image3 -j .sdr_text -j .sdr_rodata -j .sdr_data -Obinary $(ELFFILE) $(RAM3_IMAGE)
$(PICK) 0x$(RAM3_START_ADDR) 0x$(RAM3_END_ADDR) $(RAM3_IMAGE) $(RAM3P_IMAGE) body+reset_offset
#else
# @rm -f $(RAM3_IMAGE) $(RAM3P_IMAGE)
# @echo "SDRAM not used (size = 0)"
#endif
$(ELFFILE):
$(error Falsher: file $@ not found)
clean: clean:
@rm -f $(BIN_DIR)/*.bin @rm -f $(BIN_DIR)/*.bin

View file

@ -1,7 +1,7 @@
#============================================= #=============================================
# SDK CONFIG # SDK CONFIG
#============================================= #=============================================
#USE_SDRAM = 1 USE_SDRAM = 1
WEB_INA219_DRV = 1 WEB_INA219_DRV = 1
#WEB_MLX90614_DRV = 1 #WEB_MLX90614_DRV = 1
#WEB_ADC_DRV = 1 #WEB_ADC_DRV = 1
@ -29,6 +29,7 @@ endif
RTOSDIR=freertos_v9.0.0 RTOSDIR=freertos_v9.0.0
LWIPDIR=lwip_v1.4.1 LWIPDIR=lwip_v1.4.1
ifdef USE_UVC ifdef USE_UVC
USE_SDRAM = 1 USE_SDRAM = 1
USE_GCC_LIB = 1 USE_GCC_LIB = 1
@ -46,6 +47,7 @@ ADD_SRC_C += project/src/user/user_start.c
# components # components
DRAM_C += project/src/console/atcmd_user.c DRAM_C += project/src/console/atcmd_user.c
DRAM_C += project/src/console/wifi_console.c DRAM_C += project/src/console/wifi_console.c
#ADD_SRC_C += project/src/console/acl_tst.c
#DRAM_C += project/src/console/wlan_tst.c #DRAM_C += project/src/console/wlan_tst.c
#ADD_SRC_C += project/src/console/pwm_tst.c #ADD_SRC_C += project/src/console/pwm_tst.c
#ADD_SRC_C += project/src/WS2812/ws2812_tst.c #ADD_SRC_C += project/src/WS2812/ws2812_tst.c

View file

@ -27,6 +27,27 @@
#include <platform/platform_stdlib.h> #include <platform/platform_stdlib.h>
#include "platform_opts.h" #include "platform_opts.h"
////////////////////////////
#ifdef CONFIG_SDR_EN
#define WIFI_LOGO_CERTIFICATION_CONFIG 1 // for ping 10k test buffer setting
#else
#define WIFI_LOGO_CERTIFICATION_CONFIG 0
#endif
/*LWIP_UART_ADAPTER==1: Enable LWIP_UART_ADAPTER when CONFIG_GAGENT is enabled,
because some GAGENT functions denpond on the following macro definitions.*/
#define LWIP_UART_ADAPTER 0
/**
* IP_FORWARD==1: Enables the ability to forward IP packets across network
* interfaces. If you are going to run lwIP on a device with only one network
* interface, define this to 0.
*/
#define IP_FORWARD 1
#define IP_NAPT 1
////////////////////////////
/** /**
* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first
* local TCP/UDP pcb (default==0). This can prevent creating predictable port * local TCP/UDP pcb (default==0). This can prevent creating predictable port
@ -34,13 +55,13 @@
*/ */
#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1 #define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1
#define WIFI_LOGO_CERTIFICATION_CONFIG 1 //for ping 10k test buffer setting
/** /**
* MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library
* instead of the lwip internal allocator. Can save code size if you * instead of the lwip internal allocator. Can save code size if you
* already use it. * already use it.
*/ */
#define MEM_LIBC_MALLOC 1 #define MEM_LIBC_MALLOC 1
/** /**
* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. * 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 * Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution
@ -48,6 +69,29 @@
*/ */
#define MEMP_MEM_MALLOC 1 #define MEMP_MEM_MALLOC 1
/**
* LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname
* field.
*/
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETIF_HOSTNAME_SIZE 16
/**
* netif0: DEF_HOSTNAME "0", netif1: DEF_HOSTNAME "1", ..
*/
#define DEF_HOSTNAME "rtl871x"
/**
* LWIP_AUTOIP==1: Enable AUTOIP module.
*/
#define LWIP_AUTOIP 0 // Realtek modified (0->1)
/** 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 */
#if defined(_SYS__TIMEVAL_H_)
#define LWIP_TIMEVAL_PRIVATE 0
#endif
////////////////
/** /**
* SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
* critical regions during buffer allocation, deallocation and memory * critical regions during buffer allocation, deallocation and memory
@ -64,23 +108,16 @@
#define IP_FRAG 1 #define IP_FRAG 1
#define ARP_QUEUEING 0 #define ARP_QUEUEING 0
/**
* LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname
* field.
*/
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETIF_HOSTNAME_SIZE 16
/**
* netif0: DEF_HOSTNAME "0", netif1: DEF_HOSTNAME "1", ..
*/
#define DEF_HOSTNAME "rtl871x"
/** /**
* NO_SYS==1: Provides VERY minimal functionality. Otherwise, * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
* use lwIP facilities. * use lwIP facilities.
*/ */
#define NO_SYS 0 #define NO_SYS 0
#ifndef CONFIG_DYNAMIC_TICKLESS
#define CONFIG_DYNAMIC_TICKLESS 0
#endif
/* ---------- Memory options ---------- */ /* ---------- Memory options ---------- */
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which /* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2 lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
@ -90,9 +127,9 @@
/* MEM_SIZE: the size of the heap memory. If the application will send /* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */ a lot of data that needs to be copied, this should be set high. */
#if WIFI_LOGO_CERTIFICATION_CONFIG #if WIFI_LOGO_CERTIFICATION_CONFIG
#define MEM_SIZE (10*1024) //for ping 10k test #define MEM_SIZE (16*1024) //for ping 10k test
#else #else
#define MEM_SIZE (5*1024) #define MEM_SIZE (6*1024)
#endif #endif
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application /* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
@ -155,18 +192,17 @@ a lot of data that needs to be copied, this should be set high. */
#define TCP_SND_QUEUELEN (4*TCP_SND_BUF/TCP_MSS) #define TCP_SND_QUEUELEN (4*TCP_SND_BUF/TCP_MSS)
/* TCP receive window. */ /* TCP receive window. */
#define TCP_WND (4*TCP_MSS) // (2*TCP_MSS) #if WIFI_LOGO_CERTIFICATION_CONFIG
#define TCP_WND (4*TCP_MSS)
#else
#define TCP_WND (2*TCP_MSS)
#endif
/* ---------- ICMP options ---------- */ /* ---------- ICMP options ---------- */
#define LWIP_ICMP 1 #define LWIP_ICMP 1
/* ---------- ARP options ----------- */ /* ---------- ARP options ----------- */
#define LWIP_ARP 1 #define LWIP_ARP 1
/**
* LWIP_AUTOIP==1: Enable AUTOIP module.
*/
#define LWIP_AUTOIP 0 //Realtek modified (0->1)
/* ---------- DHCP options ---------- */ /* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of /* Define LWIP_DHCP to 1 if you want DHCP configuration of
@ -185,28 +221,29 @@ a lot of data that needs to be copied, this should be set high. */
/* Support Multicast */ /* Support Multicast */
#define LWIP_IGMP 1 #define LWIP_IGMP 1
extern _LONG_CALL_ u32 Rand(void);
extern __attribute__ ((long_call)) unsigned int Rand(void); #define LWIP_RAND() Rand() // srand(sys_now())
#define LWIP_RAND() Rand()
/* Support TCP Keepalive */ /* Support TCP Keepalive */
#define LWIP_TCP_KEEPALIVE 1 #define LWIP_TCP_KEEPALIVE 1
/*LWIP_UART_ADAPTER==1: Enable LWIP_UART_ADAPTER when CONFIG_GAGENT is enabled,
because some GAGENT functions denpond on the following macro definitions.*/
#if CONFIG_EXAMPLE_UART_ADAPTER
#define LWIP_UART_ADAPTER 1
#else
#define LWIP_UART_ADAPTER 0
#endif
#if LWIP_UART_ADAPTER #if LWIP_UART_ADAPTER || CONFIG_ETHERNET || CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD
/**
* LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and
* SO_SNDTIMEO processing.
*/
#undef LWIP_SO_SNDTIMEO #undef LWIP_SO_SNDTIMEO
#define LWIP_SO_SNDTIMEO 1 #define LWIP_SO_SNDTIMEO 1
#undef SO_REUSE #undef SO_REUSE
#define SO_REUSE 1 #define SO_REUSE 1
/**
* MEMP_NUM_NETCONN: the number of struct netconns.
* (only needed if you use the sequential API, like api_lib.c)
*/
#undef MEMP_NUM_NETCONN #undef MEMP_NUM_NETCONN
#define MEMP_NUM_NETCONN 10 #define MEMP_NUM_NETCONN 10
@ -218,15 +255,7 @@ extern __attribute__ ((long_call)) unsigned int Rand(void);
#define TCP_KEEPCNT_DEFAULT 10U #define TCP_KEEPCNT_DEFAULT 10U
#endif #endif
#if CONFIG_EXAMPLE_UART_ATCMD #if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD
#undef LWIP_SO_SNDTIMEO
#define LWIP_SO_SNDTIMEO 1
#undef SO_REUSE
#define SO_REUSE 1
#undef MEMP_NUM_NETCONN
#define MEMP_NUM_NETCONN 10
#undef MEMP_NUM_TCP_PCB #undef MEMP_NUM_TCP_PCB
#define MEMP_NUM_TCP_PCB (MEMP_NUM_NETCONN) #define MEMP_NUM_TCP_PCB (MEMP_NUM_NETCONN)
@ -234,18 +263,21 @@ extern __attribute__ ((long_call)) unsigned int Rand(void);
#undef MEMP_NUM_UDP_PCB #undef MEMP_NUM_UDP_PCB
#define MEMP_NUM_UDP_PCB (MEMP_NUM_NETCONN) #define MEMP_NUM_UDP_PCB (MEMP_NUM_NETCONN)
#undef TCP_WND
#define TCP_WND (4*TCP_MSS)
#define TCP_KEEPIDLE_DEFAULT 10000UL
#define TCP_KEEPINTVL_DEFAULT 1000UL
#define TCP_KEEPCNT_DEFAULT 10U
#define ERRNO 1 #define ERRNO 1
#endif #endif
/* ---------- Statistics options ---------- */ /*
--------------------------------------
--------- Statistics options ---------
--------------------------------------
*/
/*
* LWIP_STATS==1: Enable statistics collection in lwip_stats.
*/
#define LWIP_STATS 0 #define LWIP_STATS 0
#define LWIP_PROVIDE_ERRNO 1 #define LWIP_PROVIDE_ERRNO 1
@ -255,15 +287,6 @@ extern __attribute__ ((long_call)) unsigned int Rand(void);
-------------------------------------- --------------------------------------
*/ */
/*
The STM32F2x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
- To use this feature let the following define uncommented.
- To disable it and process by CPU comment the the checksum.
*/
//Do checksum by lwip - WLAN nic does not support Checksum offload
//#define CHECKSUM_BY_HARDWARE
#ifdef CHECKSUM_BY_HARDWARE #ifdef CHECKSUM_BY_HARDWARE
/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 0 #define CHECKSUM_GEN_IP 0
@ -321,6 +344,7 @@ The STM32F2x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums
#define LWIP_DEBUG 0 #define LWIP_DEBUG 0
/* /*
--------------------------------- ---------------------------------
---------- OS options ---------- ---------- OS options ----------
@ -376,11 +400,10 @@ The STM32F2x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums
*/ */
#define TCPIP_THREAD_PRIO (configMAX_PRIORITIES - 2) #define TCPIP_THREAD_PRIO (configMAX_PRIORITIES - 2)
/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided /* Added by Realtek */
* by your system, set this to 0 and include <sys/time.h> in cc.h */ #ifndef DNS_IGNORE_REPLY_ERR
#if defined(_SYS__TIMEVAL_H_) #define DNS_IGNORE_REPLY_ERR 1
#define LWIP_TIMEVAL_PRIVATE 0 #endif /* DNS_IGNORE_REPLY_ERR */
#endif
#endif /* __LWIPOPTS_H__ */ #endif /* __LWIPOPTS_H__ */

View file

@ -377,6 +377,7 @@ LOCAL void fATSP(int argc, char *argv[])
}; };
printf("WakeLock Status %d\n", pmu_get_wakelock_status()); printf("WakeLock Status %d\n", pmu_get_wakelock_status());
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_at[] = { MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_at[] = {

View file

@ -74,7 +74,7 @@ int main(void)
WDGStart(); WDGStart();
#endif #endif
#if (defined(CONFIG_CRYPTO_STARTUP) && (CONFIG_CRYPTO_STARTUP)) #if 0 // (defined(CONFIG_CRYPTO_STARTUP) && (CONFIG_CRYPTO_STARTUP))
if(rtl_cryptoEngine_init() != 0 ) { if(rtl_cryptoEngine_init() != 0 ) {
DBG_8195A("Crypto engine init failed!\n"); DBG_8195A("Crypto engine init failed!\n");
} }

View file

@ -11,6 +11,7 @@
#include "freertos_pmu.h" #include "freertos_pmu.h"
#include "task.h" #include "task.h"
#include "diag.h" #include "diag.h"
#include "hal_crypto.h"
#include "netbios/netbios.h" #include "netbios/netbios.h"
#include "sntp/sntp.h" #include "sntp/sntp.h"
#include "user/sys_cfg.h" #include "user/sys_cfg.h"
@ -59,12 +60,11 @@ void sys_write_cfg(void)
} }
extern void console_init(void); extern void console_init(void);
extern void HalReInitPlatformTimer(void);
void user_init_thrd(void) { void user_init_thrd(void) {
/* Read system config*/ /* Read system config*/
if(syscfg.cfg.b.pin_clear_cfg_enable if(syscfg.cfg.b.pin_clear_cfg_enable
&& 0) { // user_test_clear_pin() && 0) { // user_test_clear_pin()
wifi_cfg.load_flg = 0; wifi_cfg.load_flg = 0;
@ -82,6 +82,14 @@ void user_init_thrd(void) {
/* Load cfg, init WiFi + LwIP init, WiFi start if wifi_cfg.mode != RTW_MODE_NONE */ /* Load cfg, init WiFi + LwIP init, WiFi start if wifi_cfg.mode != RTW_MODE_NONE */
wifi_init(); wifi_init();
#if (defined(CONFIG_CRYPTO_STARTUP) && (CONFIG_CRYPTO_STARTUP))
if(rtl_cryptoEngine_init() != 0 ) {
error_printf("Crypto engine init failed!\n");
}
#else
// rtl_cryptoEngine_deinit();
#endif
#if defined(USE_NETBIOS) #if defined(USE_NETBIOS)
if(syscfg.cfg.b.netbios_ena) netbios_init(); if(syscfg.cfg.b.netbios_ena) netbios_init();
#endif #endif

View file

@ -0,0 +1,6 @@
rem pip install wheel
rem pip install pyinstaller
pyinstaller -c --onedir --onefile -n rtlaimage rtlaimage.py
copy /b dist\rtlaimage.exe ..\..\USDK\component\soc\realtek\8195a\misc\iar_utility\common\tools\rtlaimage.exe
del /Q rtlaimage.spec
rm -rf dist build

View file

@ -0,0 +1,345 @@
#!/usr/bin/env python
# (RTL8195AM/RTL8711AM/RTL8711AF/RTL8710AF) RtlImages Utility
# pvvx
from __future__ import print_function, division
from operator import attrgetter
import argparse
import os
import struct
import sys
__version__ = "17.01.18"
PYTHON2 = sys.version_info[0] < 3 # True if on pre-Python 3
HM_IS_HDRR = 1
HM_IS_HDRD = 2
HM_IS_BOOT = 4
HM_IS_OTA = 8
HM_IS_SRAM = 16
HM_IS_SDRAM = 32
# Function to return nth byte of a bitstring
# Different behaviour on Python 2 vs 3
if PYTHON2:
def byte(bitstr, index):
return ord(bitstr[index])
else:
def byte(bitstr, index):
return bitstr[index]
class FatalError(RuntimeError):
"""
Wrapper class for runtime errors that aren't caused by internal bugs, but by
xchip responses or input content.
"""
def __init__(self, message):
RuntimeError.__init__(self, message)
@staticmethod
def WithResult(message, result):
"""
Return a fatal error object that appends the hex values of
'result' as a string formatted argument.
"""
message += " (result was %s)" % hexify(result)
return FatalError(message)
class ImageSegment(object):
""" Wrapper class for a segment in an RTL image
(very similar to a section in an ELFImage also) """
def __init__(self, addr, data, file_offs = None):
self.addr = addr
# pad all ImageSegments to at least 4 bytes length
pad_mod = len(data) % 4
if pad_mod != 0:
data += b"\x00" * (4 - pad_mod)
self.data = data
self.file_offs = file_offs
def copy_with_new_addr(self, new_addr):
""" Return a new ImageSegment with same data, but mapped at
a new address. """
return ImageSegment(new_addr, self.data, 0)
def __repr__(self):
r = "len 0x%05x load 0x%08x" % (len(self.data), self.addr)
if self.file_offs is not None:
r += " file_offs 0x%08x" % (self.file_offs)
return r
class ELFSection(ImageSegment):
""" Wrapper class for a section in an ELF image, has a section
name as well as the common properties of an ImageSegment. """
def __init__(self, name, addr, data, size):
super(ELFSection, self).__init__(addr, data)
self.name = name.decode("utf-8")
self.size = size
def __repr__(self):
return "%s %s" % (self.name, super(ELFSection, self).__repr__())
class ELFFile(object):
SEC_TYPE_PROGBITS = 0x01
SEC_TYPE_STRTAB = 0x03
def __init__(self, name):
# Load sections from the ELF file
self.name = name
try:
with open(self.name, 'rb') as f:
self._read_elf_file(f)
except:
print('Error: Not open input ELF file <%s>!' % self.name)
sys.exit(-1)
def get_section(self, section_name):
for s in self.sections:
if s.name == section_name:
return s
raise ValueError("No section %s in ELF file" % section_name)
def _read_elf_file(self, f):
# read the ELF file header
LEN_FILE_HEADER = 0x34
try:
(ident,_type,machine,_version,
self.entrypoint,_phoff,shoff,_flags,
_ehsize, _phentsize,_phnum,_shentsize,
_shnum,shstrndx) = struct.unpack("<16sHHLLLLLHHHHHH", f.read(LEN_FILE_HEADER))
except struct.error as e:
raise FatalError("Failed to read a valid ELF header from %s: %s" % (self.name, e))
if byte(ident, 0) != 0x7f or ident[1:4] != b'ELF':
raise FatalError("%s has invalid ELF magic header" % self.name)
if machine != 0x28:
raise FatalError("%s does not appear to be an RTL ELF file. e_machine=%04x" % (self.name, machine))
self._read_sections(f, shoff, shstrndx, _shnum)
def _read_sections(self, f, section_header_offs, shstrndx, shnum):
LEN_SEC_HEADER = 0x28
f.seek(section_header_offs)
# print("%d sections found in ELF file" % shnum)
if shnum == 0 or shnum > 100:
raise FatalError("%d sections found in ELF file!" % shnum)
section_header = f.read(shnum *LEN_SEC_HEADER)
if len(section_header) == 0:
raise FatalError("No section header found at offset %04x in ELF file." % section_header_offs)
if len(section_header) != shnum *LEN_SEC_HEADER:
print('WARNING: Unexpected ELF section header length %04x is not mod-%02x' % (len(section_header), LEN_SEC_HEADER))
# walk through the section header and extract all sections
section_header_offsets = range(0, len(section_header), LEN_SEC_HEADER)
def read_section_header(offs):
name_offs,sec_type,_flags,lma,sec_offs,size = struct.unpack_from("<LLLLLL", section_header[offs:])
# print('read_section_header at %08x' % offs)
return (name_offs, sec_type, lma, size, sec_offs)
all_sections = [read_section_header(offs) for offs in section_header_offsets]
prog_sections = [s for s in all_sections if s[1] == ELFFile.SEC_TYPE_PROGBITS]
# search for the string table section
if not shstrndx * LEN_SEC_HEADER in section_header_offsets:
raise FatalError("ELF file has no STRTAB section at shstrndx %d" % shstrndx)
_,sec_type,_,sec_size,sec_offs = read_section_header(shstrndx * LEN_SEC_HEADER)
if sec_type != ELFFile.SEC_TYPE_STRTAB:
print('WARNING: ELF file has incorrect STRTAB section type 0x%02x' % sec_type)
f.seek(sec_offs)
string_table = f.read(sec_size)
# build the real list of ELFSections by reading the actual section names from the
# string table section, and actual data for each section from the ELF file itself
def lookup_string(offs):
raw = string_table[offs:]
return raw[:raw.index(b'\x00')]
def read_data(offs, size):
f.seek(offs)
return f.read(size)
prog_sections = [ELFSection(lookup_string(n_offs), lma, read_data(offs, size), size) for (n_offs, _type, lma, size, offs) in prog_sections if lma != 0]
self.sections = prog_sections
class xFirmwareImage(object):
def __init__(self, fname, segnames, hmode, addrl, addrh):
self.fname = fname
self.segnames = segnames
self.hm = hmode
self.addrl = addrl
self.addrh = addrh
self.addr = None
self.data = ''
self.size = 0 # size code/data only (without header)
self.imgsegs = []
def load(self, sections):
imgsegs = [s for s in sections if s.name in self.segnames]
if imgsegs:
if len(imgsegs) > 1:
sorted(imgsegs, key = attrgetter('addr'))
elif len(imgsegs[0].data) == 0: # file size == 0
self.addr = imgsegs[0].addr
# print('Segment at 0x%08x,' % self.addr, 'size 0x00000000 copy to image', self.fname)
sections.remove(imgsegs[0])
return
self.addr = imgsegs[0].addr
s = imgsegs[len(imgsegs) - 1]
self.size = s.addr + len(s.data) - self.addr
# print('Segment at 0x%08x,' % self.addr, 'size 0x%08x' % self.size, 'copy to image', self.fname)
if self.addr < self.addrl and self.addr > self.addrh:
print('Segment Address Error!')
return
if self.size:
if self.hm & HM_IS_HDRR:
self.data = struct.pack(b'<LLLL', self.size, self.addr, 0x35393138, 0x31313738)
elif self.hm & HM_IS_HDRD:
self.data = struct.pack(b'<LLLL', self.size, self.addr, 0xffffffff, 0xffffffff)
elif self.hm & HM_IS_BOOT: # boot
self.data = struct.pack(b'<LLLLLLLL', 0x96969999, 0xFC66CC3F, 0x03CC33C0, 0x6231DCE5, self.size, self.addr, 0xffff002c, 0xffffffff)
x = self.addr
for s in imgsegs:
while x < s.addr:
self.data += '\0'
x += 1
self.data += s.data
# print('Segment at 0x%08x,' % s.addr, 'size 0x%08x' % len(s.data), 'name', s.name, 'copy to image', self.fname)
x += s.size
sections.remove(s)
def save(self, outdir, flg_p):
if self.size:
# print('Segment at 0x%08x,' % self.addr, 'size 0x%08x' % self.size, 'save to', self.fname)
try:
if flg_p:
with open(outdir + self.fname + '.p.bin', "wb") as f:
f.write(self.data)
f.close()
else:
with open(outdir + self.fname + '.bin', "wb") as f:
if self.hm & (HM_IS_HDRR | HM_IS_HDRD):
f.write(self.data[16:])
elif self.hm & HM_IS_BOOT:
f.write(self.data[32:])
else:
f.write(self.data)
f.close()
except:
print('Error: Not write file <%s>!' % self.fname)
sys.exit(-1)
def save_ota(self, f, fn, chks):
if self.size:
# print('Segment at 0x%08x,' % self.addr, 'size 0x%08x' % self.size, 'save to %s' % fn)
try:
f.write(self.data)
i = 0
while i < len(self.data):
chks += byte(self.data, i)
i += 1
except:
print('Error: Not write file %s!' % fn)
sys.exit(-1)
return chks
def save_sram(self, f, fn):
if self.size:
# print('Segment at 0x%08x,' % self.addr, 'size 0x%08x' % self.size, 'save to %s' % fn)
try:
if self.hm & HM_IS_BOOT:
gap = 0x0b000
i = len(self.data)
if i > gap:
print('Error: Segment %s is big!' % self.name)
f.write(self.data)
while i < gap:
f.write('\0')
i += 1
else:
f.write(self.data)
except:
print('Error: Not write file %s!' % fn)
sys.exit(-1)
def elf2image(args):
e = ELFFile(args.elffile) # ELFSection is a subclass of ImageSegment
# print(e.sections)
image = [xFirmwareImage('ram_1', ['.ram.start.table', '.ram_image1.text', '.ram_image1.data'], HM_IS_BOOT + HM_IS_SRAM, 0x10000bc8, 0x10070000),
xFirmwareImage('ram_2', ['.image2.start.table', '.ram_image2.text', '.ram_image2.rodata', '.ram.data'], HM_IS_OTA + HM_IS_HDRR + HM_IS_SRAM, 0x10006000, 0x10070000),
xFirmwareImage('sdram', ['.sdr_text', '.sdr_rodata', '.sdr_data'], HM_IS_OTA + HM_IS_HDRD + HM_IS_SDRAM, 0x30000000, 0x30200000)]
img_sram_use = 0
img_sdram_use = 0
for s in image:
s.load(e.sections)
if s.hm & HM_IS_SRAM:
img_sram_use += s.size
elif s.hm & HM_IS_SDRAM:
img_sdram_use += s.size
for s in image:
if s.size:
print('Segment at 0x%08x,' % s.addr, 'size 0x%08x' % s.size, '(%s)' % s.fname)
s.save(args.outdir, None);
s.save(args.outdir, 1);
if args.ota:
fn = args.outdir + 'ota.bin'
try:
chks = 0
with open(fn, "wb") as f:
for s in image:
if s.hm & HM_IS_OTA:
chks = s.save_ota(f, fn, chks)
f.write(struct.pack('<L', chks))
f.close()
except:
print('Error: Not write file <%s>!' % fn)
sys.exit(-1)
if args.ram_all:
if image[0].size == 0 and image[1].size == 0:
print('Error: Ram_all = 0!')
sys.exit(-1)
fn = args.outdir + 'ram_all.bin'
try:
with open(fn, "wb") as f:
for s in image:
if s.hm & HM_IS_SRAM:
s.save_sram(f, fn)
f.close()
except:
print('Error: Not write file <%s>!' % fn)
sys.exit(-1)
print('Images size: SRAM %u bytes, SDRAM %u bytes [%u]' % (img_sram_use, img_sdram_use, img_sram_use + img_sdram_use))
def main():
parser = argparse.ArgumentParser(description='RtlAImages Utility version %s' % __version__, prog='rtlimage')
parser.add_argument('--ram_all', '-r', action='store_true', help='Generate ram_all files')
parser.add_argument('--ota', '-a', action='store_true', help='Generate OTA files')
parser.add_argument('elffile', type=str, help='Input ELF file',)
parser.add_argument('--outdir', '-o', type=str, default='', help='Outpyt directory')
args = parser.parse_args()
print('RtlAImages Utility version %s' % __version__)
if args.elffile is None:
parser.print_help()
sys.exit(1)
elf2image(args)
sys.exit(0)
if __name__ == '__main__':
try:
main()
except FatalError as e:
print('\nA fatal error occurred: %s' % e)
sys.exit(2)

View file

@ -6,8 +6,8 @@ SDK_PATH = USDK/
#GCC_PATH = d:/MCU/GNU_Tools_ARM_Embedded/6.2017-q1-update/bin/# + or set in PATH #GCC_PATH = d:/MCU/GNU_Tools_ARM_Embedded/6.2017-q1-update/bin/# + or set in PATH
#OPENOCD_PATH = D:/MCU/OpenOCD/bin/# + or set in PATH #OPENOCD_PATH = D:/MCU/OpenOCD/bin/# + or set in PATH
TOOLS_PATH ?= $(SDK_PATH)component/soc/realtek/8195a/misc/iar_utility/common/tools/ TOOLS_PATH ?= $(SDK_PATH)component/soc/realtek/8195a/misc/iar_utility/common/tools/
FLASHER_TYPE = Jlink #FLASHER_TYPE = Jlink
#FLASHER_TYPE = cmsis-dap FLASHER_TYPE = cmsis-dap
FLASHER_SPEED = 3500 FLASHER_SPEED = 3500
FLASHER_PATH = flasher/ FLASHER_PATH = flasher/
JLINK_PATH ?= D:/MCU/SEGGER/JLink_V612i/ JLINK_PATH ?= D:/MCU/SEGGER/JLink_V612i/