Add lwIP driver into Zynq demo - not yet fully functional.

pull/4/head
Richard Barry 11 years ago
parent 09a89763ee
commit 74ffdb0b89

@ -31,7 +31,11 @@
<listOptionValue builtIn="false" value="../../RTOSDemo_bsp/ps7_cortexa9_0/include"/> <listOptionValue builtIn="false" value="../../RTOSDemo_bsp/ps7_cortexa9_0/include"/>
</option> </option>
<option id="xilinx.gnu.compiler.dircategory.includes.1516519458" name="Include Paths" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath"> <option id="xilinx.gnu.compiler.dircategory.includes.1516519458" name="Include Paths" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo/lwIP_port/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo/lwIP_port/netif}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/FreeRTOS_Source/include}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/FreeRTOS_Source/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo/lwip-1.4.0/src/include/ipv4}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo/lwip-1.4.0/src/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo/FreeRTOS-Plus-CLI}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo/FreeRTOS-Plus-CLI}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo/Standard_Demo_Tasks/include}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo/Standard_Demo_Tasks/include}&quot;"/>
@ -91,6 +95,9 @@
<outputType id="org.eclipse.cdt.managedbuilder.ui.rcbs.outputtype.386600654" name="Resource Custom Build Step Output Type"/> <outputType id="org.eclipse.cdt.managedbuilder.ui.rcbs.outputtype.386600654" name="Resource Custom Build Step Output Type"/>
</tool> </tool>
</fileInfo> </fileInfo>
<sourceEntries>
<entry excluding="src/Full_Demo/lwIP_port/netif/xlltemacif.c|src/Full_Demo/lwIP_port/netif/xlltemacif_sdma.c|src/Full_Demo/lwIP_port/netif/xlltemacif_physpeed.c|src/Full_Demo/lwIP_port/netif/xlltemacif_hw.h|src/Full_Demo/lwIP_port/netif/xlltemacif_hw.c|src/Full_Demo/lwIP_port/netif/xlltemacif_fifo.h|src/Full_Demo/lwIP_port/netif/xlltemacif_fifo.c|src/Full_Demo/lwIP_port/netif/xemacliteif.c|src/Full_Demo/lwIP_port/netif/xaxiemacif.c|src/Full_Demo/lwIP_port/netif/xaxiemacif_physpeed.c|src/Full_Demo/lwIP_port/netif/xaxiemacif_hw.h|src/Full_Demo/lwIP_port/netif/xaxiemacif_hw.c|src/Full_Demo/lwIP_port/netif/xaxiemacif_fifo.h|src/Full_Demo/lwIP_port/netif/xaxiemacif_fifo.c|src/Full_Demo/lwIP_port/netif/xaxiemacif_dma.c|src/Full_Demo/lwIP_Apps/apps/httpserver_raw_from_lwIP_download/fsdata.c|src/Full_Demo/lwIP_Apps/apps/httpserver_raw_from_lwIP_download/makefsdata" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration> </configuration>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
@ -182,6 +189,13 @@
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMGCCManagedMakePerProjectProfileC"/> <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMGCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
</storageModule> </storageModule>
<storageModule moduleId="refreshScope"/> <storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/RTOSDemo"/>
</configuration>
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/RTOSDemo"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/> <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cproject> </cproject>

@ -49,6 +49,11 @@
<type>1</type> <type>1</type>
<locationURI>FREERTOS_ROOT/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c</locationURI> <locationURI>FREERTOS_ROOT/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c</locationURI>
</link> </link>
<link>
<name>src/Full_Demo/lwip-1.4.0</name>
<type>2</type>
<locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/ethernet/lwip-1.4.0</locationURI>
</link>
<link> <link>
<name>src/Full_Demo/Standard_Demo_Tasks/IntQueue.c</name> <name>src/Full_Demo/Standard_Demo_Tasks/IntQueue.c</name>
<type>1</type> <type>1</type>
@ -92,6 +97,15 @@
<arguments>1.0-name-matches-false-false-include</arguments> <arguments>1.0-name-matches-false-false-include</arguments>
</matcher> </matcher>
</filter> </filter>
<filter>
<id>1400583655287</id>
<name>src/Full_Demo/lwip-1.4.0</name>
<type>10</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-doc</arguments>
</matcher>
</filter>
<filter> <filter>
<id>1390074123406</id> <id>1390074123406</id>
<name>src/FreeRTOS_Source/portable/GCC</name> <name>src/FreeRTOS_Source/portable/GCC</name>
@ -173,6 +187,51 @@
<arguments>1.0-name-matches-false-false-alt*.*</arguments> <arguments>1.0-name-matches-false-false-alt*.*</arguments>
</matcher> </matcher>
</filter> </filter>
<filter>
<id>1400583733480</id>
<name>src/Full_Demo/lwip-1.4.0/ports</name>
<type>9</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-Zynq</arguments>
</matcher>
</filter>
<filter>
<id>1400584415021</id>
<name>src/Full_Demo/lwip-1.4.0/src/core</name>
<type>10</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-ipv6</arguments>
</matcher>
</filter>
<filter>
<id>1400584415036</id>
<name>src/Full_Demo/lwip-1.4.0/src/core</name>
<type>10</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-snmp</arguments>
</matcher>
</filter>
<filter>
<id>1400584349310</id>
<name>src/Full_Demo/lwip-1.4.0/src/netif</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-eth*.*</arguments>
</matcher>
</filter>
<filter>
<id>1400584349317</id>
<name>src/Full_Demo/lwip-1.4.0/src/netif</name>
<type>10</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-ppp</arguments>
</matcher>
</filter>
</filteredResources> </filteredResources>
<variableList> <variableList>
<variable> <variable>

@ -117,7 +117,7 @@
#define configUSE_TICK_HOOK 1 #define configUSE_TICK_HOOK 1
#define configMAX_PRIORITIES ( 7 ) #define configMAX_PRIORITIES ( 7 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 200 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 200 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 65536 ) ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 80 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 10 ) #define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 1 #define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0 #define configUSE_16_BIT_TICKS 0
@ -203,5 +203,31 @@ Zynq MPU. */
#define configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ( -0xf00 ) #define configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ( -0xf00 )
#define configUNIQUE_INTERRUPT_PRIORITIES 32 #define configUNIQUE_INTERRUPT_PRIORITIES 32
/****** Network configuration settings. ***************************************/
#define configLWIP_TASK_PRIORITY ( 5 )
/* MAC address configuration. */
#define configMAC_ADDR0 0x00
#define configMAC_ADDR1 0x13
#define configMAC_ADDR2 0x14
#define configMAC_ADDR3 0x15
#define configMAC_ADDR4 0x15
#define configMAC_ADDR5 0x16
/* IP address configuration. */
#define configIP_ADDR0 10
#define configIP_ADDR1 134
#define configIP_ADDR2 134
#define configIP_ADDR3 210
/* Netmask configuration. */
#define configNET_MASK0 255
#define configNET_MASK1 255
#define configNET_MASK2 255
#define configNET_MASK3 0
#endif /* FREERTOS_CONFIG_H */ #endif /* FREERTOS_CONFIG_H */

@ -0,0 +1,199 @@
/*
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Standard includes. */
#include "stdlib.h"
#include "string.h"
/* lwIP core includes */
#include "lwip/opt.h"
#include "lwip/sockets.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Utils includes. */
#include "FreeRTOS_CLI.h"
/* Dimensions the buffer into which input characters are placed. */
#define cmdMAX_INPUT_SIZE 20
/* Dimensions the buffer into which string outputs can be placed. */
#define cmdMAX_OUTPUT_SIZE 1024
/*-----------------------------------------------------------*/
void vBasicSocketsCommandInterpreterTask( void *pvParameters )
{
long lSocket, lClientFd, lBytes, lAddrLen = sizeof( struct sockaddr_in ), lInputIndex;
struct sockaddr_in sLocalAddr;
struct sockaddr_in client_addr;
const char *pcWelcomeMessage = "FreeRTOS command server - connection accepted.\r\nType Help to view a list of registered commands.\r\n\r\n>";
char cInChar;
static char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ];
portBASE_TYPE xReturned;
( void ) pvParameters;
lSocket = lwip_socket(AF_INET, SOCK_STREAM, 0);
if( lSocket >= 0 )
{
memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));
sLocalAddr.sin_family = AF_INET;
sLocalAddr.sin_len = sizeof(sLocalAddr);
sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
sLocalAddr.sin_port = ntohs( ( ( unsigned short ) 23 ) );
if( lwip_bind( lSocket, ( struct sockaddr *) &sLocalAddr, sizeof( sLocalAddr ) ) < 0 )
{
lwip_close( lSocket );
vTaskDelete( NULL );
}
if( lwip_listen( lSocket, 20 ) != 0 )
{
lwip_close( lSocket );
vTaskDelete( NULL );
}
for( ;; )
{
lClientFd = lwip_accept(lSocket, ( struct sockaddr * ) &client_addr, ( u32_t * ) &lAddrLen );
if( lClientFd > 0L )
{
lwip_send( lClientFd, pcWelcomeMessage, strlen( ( const char * ) pcWelcomeMessage ), 0 );
lInputIndex = 0;
memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
do
{
lBytes = lwip_recv( lClientFd, &cInChar, sizeof( cInChar ), 0 );
if( lBytes > 0L )
{
if( cInChar == '\n' )
{
/* The input string has been terminated. Was the
input a quit command? */
if( strcmp( "quit", ( const char * ) cInputString ) == 0 )
{
/* Set lBytes to 0 to close the connection. */
lBytes = 0L;
}
else
{
/* The input string was not a quit command.
Pass the string to the command interpreter. */
do
{
/* Get the next output string from the command interpreter. */
xReturned = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
lwip_send( lClientFd, cOutputString, strlen( ( const char * ) cOutputString ), 0 );
} while( xReturned != pdFALSE );
/* All the strings generated by the input
command have been sent. Clear the input
string ready to receive the next command. */
lInputIndex = 0;
memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
lwip_send( lClientFd, "\r\n>", strlen( "\r\n>" ), 0 );
}
}
else
{
if( cInChar == '\r' )
{
/* Ignore the character. */
}
else if( cInChar == '\b' )
{
/* Backspace was pressed. Erase the last
character in the string - if any. */
if( lInputIndex > 0 )
{
lInputIndex--;
cInputString[ lInputIndex ] = '\0';
}
}
else
{
/* A character was entered. Add it to the string
entered so far. When a \n is entered the complete
string will be passed to the command interpreter. */
if( lInputIndex < cmdMAX_INPUT_SIZE )
{
cInputString[ lInputIndex ] = cInChar;
lInputIndex++;
}
}
}
}
} while( lBytes > 0L );
lwip_close( lClientFd );
}
}
}
/* Will only get here if a listening socket could not be created. */
vTaskDelete( NULL );
}

@ -0,0 +1,177 @@
/*
* 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>
*
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include "fs.h"
#include "fsdata.h"
#include <string.h>
/** Set this to 1 to include "fsdata_custom.c" instead of "fsdata.c" for the
* file system (to prevent changing the file included in CVS) */
#ifndef HTTPD_USE_CUSTUM_FSDATA
#define HTTPD_USE_CUSTUM_FSDATA 0
#endif
#if HTTPD_USE_CUSTUM_FSDATA
#include "fsdata_custom.c"
#else /* HTTPD_USE_CUSTUM_FSDATA */
#include "fsdata.c"
#endif /* HTTPD_USE_CUSTUM_FSDATA */
/*-----------------------------------------------------------------------------------*/
/* Define the number of open files that we can support. */
#ifndef LWIP_MAX_OPEN_FILES
#define LWIP_MAX_OPEN_FILES 10
#endif
/* Define the file system memory allocation structure. */
struct fs_table {
struct fs_file file;
u8_t inuse;
};
/* Allocate file system memory */
struct fs_table fs_memory[LWIP_MAX_OPEN_FILES];
#if LWIP_HTTPD_CUSTOM_FILES
int fs_open_custom(struct fs_file *file, const char *name);
void fs_close_custom(struct fs_file *file);
#endif /* LWIP_HTTPD_CUSTOM_FILES */
/*-----------------------------------------------------------------------------------*/
static struct fs_file *
fs_malloc(void)
{
int i;
for(i = 0; i < LWIP_MAX_OPEN_FILES; i++) {
if(fs_memory[i].inuse == 0) {
fs_memory[i].inuse = 1;
return(&fs_memory[i].file);
}
}
return(NULL);
}
/*-----------------------------------------------------------------------------------*/
static void
fs_free(struct fs_file *file)
{
int i;
for(i = 0; i < LWIP_MAX_OPEN_FILES; i++) {
if(&fs_memory[i].file == file) {
fs_memory[i].inuse = 0;
break;
}
}
return;
}
/*-----------------------------------------------------------------------------------*/
struct fs_file *
fs_open(const char *name)
{
struct fs_file *file;
const struct fsdata_file *f;
file = fs_malloc();
if(file == NULL) {
return NULL;
}
#if LWIP_HTTPD_CUSTOM_FILES
if(fs_open_custom(file, name)) {
file->is_custom_file = 1;
return file;
}
file->is_custom_file = 0;
#endif /* LWIP_HTTPD_CUSTOM_FILES */
for(f = FS_ROOT; f != NULL; f = f->next) {
if (!strcmp(name, (char *)f->name)) {
file->data = (const char *)f->data;
file->len = f->len;
file->index = f->len;
file->pextension = NULL;
file->http_header_included = f->http_header_included;
#if HTTPD_PRECALCULATED_CHECKSUM
file->chksum_count = f->chksum_count;
file->chksum = f->chksum;
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
#if LWIP_HTTPD_FILE_STATE
file->state = fs_state_init(file, name);
#endif /* #if LWIP_HTTPD_FILE_STATE */
return file;
}
}
fs_free(file);
return NULL;
}
/*-----------------------------------------------------------------------------------*/
void
fs_close(struct fs_file *file)
{
#if LWIP_HTTPD_CUSTOM_FILES
if (file->is_custom_file) {
fs_close_custom(file);
}
#endif /* LWIP_HTTPD_CUSTOM_FILES */
#if LWIP_HTTPD_FILE_STATE
fs_state_free(file, file->state);
#endif /* #if LWIP_HTTPD_FILE_STATE */
fs_free(file);
}
/*-----------------------------------------------------------------------------------*/
int
fs_read(struct fs_file *file, char *buffer, int count)
{
int read;
if(file->index == file->len) {
return -1;
}
read = file->len - file->index;
if(read > count) {
read = count;
}
MEMCPY(buffer, (file->data + file->index), read);
file->index += read;
return(read);
}
/*-----------------------------------------------------------------------------------*/
int fs_bytes_left(struct fs_file *file)
{
return file->len - file->index;
}

@ -0,0 +1,100 @@
/*
* 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 __FS_H__
#define __FS_H__
#include "lwip/opt.h"
/** Set this to 1 and provide the functions:
* - "int fs_open_custom(struct fs_file *file, const char *name)"
* Called first for every opened file to allow opening files
* that are not included in fsdata(_custom).c
* - "void fs_close_custom(struct fs_file *file)"
* Called to free resources allocated by fs_open_custom().
*/
#ifndef LWIP_HTTPD_CUSTOM_FILES
#define LWIP_HTTPD_CUSTOM_FILES 0
#endif
/** Set this to 1 to include an application state argument per file
* that is opened. This allows to keep a state per connection/file.
*/
#ifndef LWIP_HTTPD_FILE_STATE
#define LWIP_HTTPD_FILE_STATE 0
#endif
/** HTTPD_PRECALCULATED_CHECKSUM==1: include precompiled checksums for
* predefined (MSS-sized) chunks of the files to prevent having to calculate
* the checksums at runtime. */
#ifndef HTTPD_PRECALCULATED_CHECKSUM
#define HTTPD_PRECALCULATED_CHECKSUM 0
#endif
#if HTTPD_PRECALCULATED_CHECKSUM
struct fsdata_chksum {
u32_t offset;
u16_t chksum;
u16_t len;
};
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
struct fs_file {
const char *data;
int len;
int index;
void *pextension;
#if HTTPD_PRECALCULATED_CHECKSUM
const struct fsdata_chksum *chksum;
u16_t chksum_count;
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
u8_t http_header_included;
#if LWIP_HTTPD_CUSTOM_FILES
u8_t is_custom_file;
#endif /* LWIP_HTTPD_CUSTOM_FILES */
#if LWIP_HTTPD_FILE_STATE
void *state;
#endif /* LWIP_HTTPD_FILE_STATE */
};
struct fs_file *fs_open(const char *name);
void fs_close(struct fs_file *file);
int fs_read(struct fs_file *file, char *buffer, int count);
int fs_bytes_left(struct fs_file *file);
#if LWIP_HTTPD_FILE_STATE
/** This user-defined function is called when a file is opened. */
void *fs_state_init(struct fs_file *file, const char *name);
/** This user-defined function is called when a file is closed. */
void fs_state_free(struct fs_file *file, void *state);
#endif /* #if LWIP_HTTPD_FILE_STATE */
#endif /* __FS_H__ */

@ -0,0 +1,50 @@
/*
* 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 __FSDATA_H__
#define __FSDATA_H__
#include "lwip/opt.h"
#include "fs.h"
struct fsdata_file {
const struct fsdata_file *next;
const unsigned char *name;
const unsigned char *data;
int len;
u8_t http_header_included;
#if HTTPD_PRECALCULATED_CHECKSUM
u16_t chksum_count;
const struct fsdata_chksum *chksum;
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
};
#endif /* __FSDATA_H__ */

@ -0,0 +1,236 @@
/*
* 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>
*
* This version of the file has been modified by Texas Instruments to offer
* simple server-side-include (SSI) and Common Gateway Interface (CGI)
* capability.
*/
#ifndef __HTTPD_H__
#define __HTTPD_H__
#include "lwip/opt.h"
#include "lwip/err.h"
#include "lwip/pbuf.h"
/** Set this to 1 to support CGI */
#ifndef LWIP_HTTPD_CGI
#define LWIP_HTTPD_CGI 0
#endif
/** Set this to 1 to support SSI (Server-Side-Includes) */
#ifndef LWIP_HTTPD_SSI
#define LWIP_HTTPD_SSI 1
#endif
/** Set this to 1 to support HTTP POST */
#ifndef LWIP_HTTPD_SUPPORT_POST
#define LWIP_HTTPD_SUPPORT_POST 0
#endif
#if LWIP_HTTPD_CGI
/*
* Function pointer for a CGI script handler.
*
* This function is called each time the HTTPD server is asked for a file
* whose name was previously registered as a CGI function using a call to
* http_set_cgi_handler. The iIndex parameter provides the index of the
* CGI within the ppcURLs array passed to http_set_cgi_handler. Parameters
* pcParam and pcValue provide access to the parameters provided along with
* the URI. iNumParams provides a count of the entries in the pcParam and
* pcValue arrays. Each entry in the pcParam array contains the name of a
* parameter with the corresponding entry in the pcValue array containing the
* value for that parameter. Note that pcParam may contain multiple elements
* with the same name if, for example, a multi-selection list control is used
* in the form generating the data.
*
* The function should return a pointer to a character string which is the
* path and filename of the response that is to be sent to the connected
* browser, for example "/thanks.htm" or "/response/error.ssi".
*
* The maximum number of parameters that will be passed to this function via
* iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in the incoming
* HTTP request above this number will be discarded.
*
* Requests intended for use by this CGI mechanism must be sent using the GET
* method (which encodes all parameters within the URI rather than in a block
* later in the request). Attempts to use the POST method will result in the
* request being ignored.
*
*/
typedef const char *(*tCGIHandler)(int iIndex, int iNumParams, char *pcParam[],
char *pcValue[]);
/*
* Structure defining the base filename (URL) of a CGI and the associated
* function which is to be called when that URL is requested.
*/
typedef struct
{
const char *pcCGIName;
tCGIHandler pfnCGIHandler;
} tCGI;
void http_set_cgi_handlers(const tCGI *pCGIs, int iNumHandlers);
/* The maximum number of parameters that the CGI handler can be sent. */
#ifndef LWIP_HTTPD_MAX_CGI_PARAMETERS
#define LWIP_HTTPD_MAX_CGI_PARAMETERS 16
#endif
#endif /* LWIP_HTTPD_CGI */
#if LWIP_HTTPD_SSI
/** LWIP_HTTPD_SSI_MULTIPART==1: SSI handler function is called with 2 more
* arguments indicating a counter for insert string that are too long to be
* inserted at once: the SSI handler function must then set 'next_tag_part'
* which will be passed back to it in the next call. */
#ifndef LWIP_HTTPD_SSI_MULTIPART
#define LWIP_HTTPD_SSI_MULTIPART 0
#endif
/*
* Function pointer for the SSI tag handler callback.
*
* This function will be called each time the HTTPD server detects a tag of the
* form <!--#name--> in a .shtml, .ssi or .shtm file where "name" appears as
* one of the tags supplied to http_set_ssi_handler in the ppcTags array. The
* returned insert string, which will be appended after the the string
* "<!--#name-->" in file sent back to the client,should be written to pointer
* pcInsert. iInsertLen contains the size of the buffer pointed to by
* pcInsert. The iIndex parameter provides the zero-based index of the tag as
* found in the ppcTags array and identifies the tag that is to be processed.
*
* The handler returns the number of characters written to pcInsert excluding
* any terminating NULL or a negative number to indicate a failure (tag not
* recognized, for example).
*
* Note that the behavior of this SSI mechanism is somewhat different from the
* "normal" SSI processing as found in, for example, the Apache web server. In
* this case, the inserted text is appended following the SSI tag rather than
* replacing the tag entirely. This allows for an implementation that does not
* require significant additional buffering of output data yet which will still
* offer usable SSI functionality. One downside to this approach is when
* attempting to use SSI within JavaScript. The SSI tag is structured to
* resemble an HTML comment but this syntax does not constitute a comment
* within JavaScript and, hence, leaving the tag in place will result in
* problems in these cases. To work around this, any SSI tag which needs to
* output JavaScript code must do so in an encapsulated way, sending the whole
* HTML <script>...</script> section as a single include.
*/
typedef u16_t (*tSSIHandler)(int iIndex, char *pcInsert, int iInsertLen
#if LWIP_HTTPD_SSI_MULTIPART
, u16_t current_tag_part, u16_t *next_tag_part
#endif /* LWIP_HTTPD_SSI_MULTIPART */
#if LWIP_HTTPD_FILE_STATE
, void *connection_state
#endif /* LWIP_HTTPD_FILE_STATE */
);
void http_set_ssi_handler(tSSIHandler pfnSSIHandler,
const char **ppcTags, int iNumTags);
/* The maximum length of the string comprising the tag name */
#ifndef LWIP_HTTPD_MAX_TAG_NAME_LEN
#define LWIP_HTTPD_MAX_TAG_NAME_LEN 8
#endif
/* The maximum length of string that can be returned to replace any given tag */
#ifndef LWIP_HTTPD_MAX_TAG_INSERT_LEN
#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192
#endif
#endif /* LWIP_HTTPD_SSI */
#if LWIP_HTTPD_SUPPORT_POST
/* These functions must be implemented by the application */
/** Called when a POST request has been received. The application can decide
* whether to accept it or not.
*
* @param connection Unique connection identifier, valid until httpd_post_end
* is called.
* @param uri The HTTP header URI receiving the POST request.
* @param http_request The raw HTTP request (the first packet, normally).
* @param http_request_len Size of 'http_request'.
* @param content_len Content-Length from HTTP header.
* @param response_uri Filename of response file, to be filled when denying the
* request
* @param response_uri_len Size of the 'response_uri' buffer.
* @param post_auto_wnd Set this to 0 to let the callback code handle window
* updates by calling 'httpd_post_data_recved' (to throttle rx speed)
* default is 1 (httpd handles window updates automatically)
* @return ERR_OK: Accept the POST request, data may be passed in
* another err_t: Deny the POST request, send back 'bad request'.
*/
err_t httpd_post_begin(void *connection, const char *uri, const char *http_request,
u16_t http_request_len, int content_len, char *response_uri,
u16_t response_uri_len, u8_t *post_auto_wnd);
/** Called for each pbuf of data that has been received for a POST.
* ATTENTION: The application is responsible for freeing the pbufs passed in!
*
* @param connection Unique connection identifier.
* @param p Received data.
* @return ERR_OK: Data accepted.
* another err_t: Data denied, http_post_get_response_uri will be called.
*/
err_t httpd_post_receive_data(void *connection, struct pbuf *p);
/** Called when all data is received or when the connection is closed.
* The application must return the filename/URI of a file to send in response
* to this POST request. If the response_uri buffer is untouched, a 404
* response is returned.
*
* @param connection Unique connection identifier.
* @param response_uri Filename of response file, to be filled when denying the request
* @param response_uri_len Size of the 'response_uri' buffer.
*/
void httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len);
#ifndef LWIP_HTTPD_POST_MANUAL_WND
#define LWIP_HTTPD_POST_MANUAL_WND 0
#endif
#if LWIP_HTTPD_POST_MANUAL_WND
void httpd_post_data_recved(void *connection, u16_t recved_len);
#endif /* LWIP_HTTPD_POST_MANUAL_WND */
#endif /* LWIP_HTTPD_SUPPORT_POST */
void httpd_init(void);
#endif /* __HTTPD_H__ */

@ -0,0 +1,115 @@
#ifndef __HTTPD_STRUCTS_H__
#define __HTTPD_STRUCTS_H__
#include "httpd.h"
/** This string is passed in the HTTP header as "Server: " */
#ifndef HTTPD_SERVER_AGENT
#define HTTPD_SERVER_AGENT "lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip)"
#endif
/** Set this to 1 if you want to include code that creates HTTP headers
* at runtime. Default is off: HTTP headers are then created statically
* by the makefsdata tool. Static headers mean smaller code size, but
* the (readonly) fsdata will grow a bit as every file includes the HTTP
* header. */
#ifndef LWIP_HTTPD_DYNAMIC_HEADERS
#define LWIP_HTTPD_DYNAMIC_HEADERS 0
#endif
#if LWIP_HTTPD_DYNAMIC_HEADERS
/** This struct is used for a list of HTTP header strings for various
* filename extensions. */
typedef struct
{
const char *extension;
int headerIndex;
} tHTTPHeader;
/** A list of strings used in HTTP headers */
static const char * const g_psHTTPHeaderStrings[] =
{
"Content-type: text/html\r\n\r\n",
"Content-type: text/html\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n",
"Content-type: image/gif\r\n\r\n",
"Content-type: image/png\r\n\r\n",
"Content-type: image/jpeg\r\n\r\n",
"Content-type: image/bmp\r\n\r\n",
"Content-type: image/x-icon\r\n\r\n",
"Content-type: application/octet-stream\r\n\r\n",
"Content-type: application/x-javascript\r\n\r\n",
"Content-type: application/x-javascript\r\n\r\n",
"Content-type: text/css\r\n\r\n",
"Content-type: application/x-shockwave-flash\r\n\r\n",
"Content-type: text/xml\r\n\r\n",
"Content-type: text/plain\r\n\r\n",
"HTTP/1.0 200 OK\r\n",
"HTTP/1.0 404 File not found\r\n",
"HTTP/1.0 400 Bad Request\r\n",
"HTTP/1.0 501 Not Implemented\r\n",
"HTTP/1.1 200 OK\r\n",
"HTTP/1.1 404 File not found\r\n",
"HTTP/1.1 400 Bad Request\r\n",
"HTTP/1.1 501 Not Implemented\r\n",
"Content-Length: ",
"Connection: Close\r\n",
"Server: "HTTPD_SERVER_AGENT"\r\n",
"\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
};
/* Indexes into the g_psHTTPHeaderStrings array */
#define HTTP_HDR_HTML 0 /* text/html */
#define HTTP_HDR_SSI 1 /* text/html Expires... */
#define HTTP_HDR_GIF 2 /* image/gif */
#define HTTP_HDR_PNG 3 /* image/png */
#define HTTP_HDR_JPG 4 /* image/jpeg */
#define HTTP_HDR_BMP 5 /* image/bmp */
#define HTTP_HDR_ICO 6 /* image/x-icon */
#define HTTP_HDR_APP 7 /* application/octet-stream */
#define HTTP_HDR_JS 8 /* application/x-javascript */
#define HTTP_HDR_RA 9 /* application/x-javascript */
#define HTTP_HDR_CSS 10 /* text/css */
#define HTTP_HDR_SWF 11 /* application/x-shockwave-flash */
#define HTTP_HDR_XML 12 /* text/xml */
#define HTTP_HDR_DEFAULT_TYPE 13 /* text/plain */
#define HTTP_HDR_OK 14 /* 200 OK */
#define HTTP_HDR_NOT_FOUND 15 /* 404 File not found */
#define HTTP_HDR_BAD_REQUEST 16 /* 400 Bad request */
#define HTTP_HDR_NOT_IMPL 17 /* 501 Not Implemented */
#define HTTP_HDR_OK_11 18 /* 200 OK */
#define HTTP_HDR_NOT_FOUND_11 19 /* 404 File not found */
#define HTTP_HDR_BAD_REQUEST_11 20 /* 400 Bad request */
#define HTTP_HDR_NOT_IMPL_11 21 /* 501 Not Implemented */
#define HTTP_HDR_CONTENT_LENGTH 22 /* Content-Length: (HTTP 1.1)*/
#define HTTP_HDR_CONN_CLOSE 23 /* Connection: Close (HTTP 1.1) */
#define HTTP_HDR_SERVER 24 /* Server: HTTPD_SERVER_AGENT */
#define DEFAULT_404_HTML 25 /* default 404 body */
/** A list of extension-to-HTTP header strings */
const static tHTTPHeader g_psHTTPHeaders[] =
{
{ "html", HTTP_HDR_HTML},
{ "htm", HTTP_HDR_HTML},
{ "shtml",HTTP_HDR_SSI},
{ "shtm", HTTP_HDR_SSI},
{ "ssi", HTTP_HDR_SSI},
{ "gif", HTTP_HDR_GIF},
{ "png", HTTP_HDR_PNG},
{ "jpg", HTTP_HDR_JPG},
{ "bmp", HTTP_HDR_BMP},
{ "ico", HTTP_HDR_ICO},
{ "class",HTTP_HDR_APP},
{ "cls", HTTP_HDR_APP},
{ "js", HTTP_HDR_JS},
{ "ram", HTTP_HDR_RA},
{ "css", HTTP_HDR_CSS},
{ "swf", HTTP_HDR_SWF},
{ "xml", HTTP_HDR_XML}
};
#define NUM_HTTP_HEADERS (sizeof(g_psHTTPHeaders) / sizeof(tHTTPHeader))
#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
#endif /* __HTTPD_STRUCTS_H__ */

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MakeFSData_proj", "MakeFSData_proj.vcxproj", "{31A9131E-BD1E-4F2D-8E1F-BC8E679E0368}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{31A9131E-BD1E-4F2D-8E1F-BC8E679E0368}.Debug|Win32.ActiveCfg = Debug|Win32
{31A9131E-BD1E-4F2D-8E1F-BC8E679E0368}.Debug|Win32.Build.0 = Debug|Win32
{31A9131E-BD1E-4F2D-8E1F-BC8E679E0368}.Release|Win32.ActiveCfg = Release|Win32
{31A9131E-BD1E-4F2D-8E1F-BC8E679E0368}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{31A9131E-BD1E-4F2D-8E1F-BC8E679E0368}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>MakeFSData_proj</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(LWIP_DIR)\src\include;$(LWIP_DIR)\..\contrib-1.4.0\ports\win32\include;$(LWIP_DIR)\src\include\ipv4</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="makefsdata.c" />
<ClCompile Include="stdafx.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="makefsdata.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

@ -0,0 +1,21 @@
<html>
<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
<body bgcolor="white" text="black">
<table width="100%">
<tr valign="top"><td width="80">
<a href="http://www.sics.se/"><img src="/img/sics.gif"
border="0" alt="SICS logo" title="SICS logo"></a>
</td><td width="500">
<h1>lwIP - A Lightweight TCP/IP Stack</h1>
<h2>404 - Page not found</h2>
<p>
Sorry, the page you are requesting was not found on this
server.
</p>
</td><td>
&nbsp;
</td></tr>
</table>
</body>
</html>

@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org lwIP WEB server demo</title>
</head>
<BODY onLoad="window.setTimeout(&quot;location.href='index.shtml'&quot;,2000)">
<font face="arial">
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
<br><p>
<hr>
<br><p>
<h2>Task statistics</h2>
Page will refresh every 2 seconds.<p>
<font face="courier"><pre>Task State Priority Stack #<br>************************************************<br>
<!--#rtos_stats-->
</pre></font>
</font>
</body>
</html>

@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org lwIP WEB server demo</title>
</head>
<BODY onLoad="window.setTimeout(&quot;location.href='runtime.shtml'&quot;,2000)">
<font face="arial">
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
<br><p>
<hr>
<br><p>
<h2>Run-time statistics</h2>
Page will refresh every 2 seconds.<p>
<font face="courier"><pre>Task Abs Time % Time<br>****************************************<br>
<!--#run_stats-->
</pre></font>
</font>
</body>
</html>

@ -0,0 +1,97 @@
#!/usr/bin/perl
open(OUTPUT, "> fsdata.c");
chdir("fs");
open(FILES, "find . -type f |");
while($file = <FILES>) {
# Do not include files in CVS directories nor backup files.
if($file =~ /(CVS|~)/) {
next;
}
chop($file);
open(HEADER, "> /tmp/header") || die $!;
if($file =~ /404/) {
print(HEADER "HTTP/1.0 404 File not found\r\n");
} else {
print(HEADER "HTTP/1.0 200 OK\r\n");
}
print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n");
if($file =~ /\.html$/) {
print(HEADER "Content-type: text/html\r\n");
} elsif($file =~ /\.gif$/) {
print(HEADER "Content-type: image/gif\r\n");
} elsif($file =~ /\.png$/) {
print(HEADER "Content-type: image/png\r\n");
} elsif($file =~ /\.jpg$/) {
print(HEADER "Content-type: image/jpeg\r\n");
} elsif($file =~ /\.class$/) {
print(HEADER "Content-type: application/octet-stream\r\n");
} elsif($file =~ /\.ram$/) {
print(HEADER "Content-type: audio/x-pn-realaudio\r\n");
} else {
print(HEADER "Content-type: text/plain\r\n");
}
print(HEADER "\r\n");
close(HEADER);
unless($file =~ /\.plain$/ || $file =~ /cgi/) {
system("cat /tmp/header $file > /tmp/file");
} else {
system("cp $file /tmp/file");
}
open(FILE, "/tmp/file");
unlink("/tmp/file");
unlink("/tmp/header");
$file =~ s/\.//;
$fvar = $file;
$fvar =~ s-/-_-g;
$fvar =~ s-\.-_-g;
print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");
print(OUTPUT "\t/* $file */\n\t");
for($j = 0; $j < length($file); $j++) {
printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
}
printf(OUTPUT "0,\n");
$i = 0;
while(read(FILE, $data, 1)) {
if($i == 0) {
print(OUTPUT "\t");
}
printf(OUTPUT "%#02x, ", unpack("C", $data));
$i++;
if($i == 10) {
print(OUTPUT "\n");
$i = 0;
}
}
print(OUTPUT "};\n\n");
close(FILE);
push(@fvars, $fvar);
push(@files, $file);
}
for($i = 0; $i < @fvars; $i++) {
$file = $files[$i];
$fvar = $fvars[$i];
if($i == 0) {
$prevfile = "NULL";
} else {
$prevfile = "file" . $fvars[$i - 1];
}
print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
}
print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n");
print(OUTPUT "#define FS_NUMFILES $i\n");

@ -0,0 +1,610 @@
/**
* makefsdata: Converts a directory structure for use with the lwIP httpd.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Jim Pettinato
* Simon Goldschmidt
*
* @todo:
* - take TCP_MSS, LWIP_TCP_TIMESTAMPS and
* PAYLOAD_ALIGN_TYPE/PAYLOAD_ALIGNMENT as arguments
*/
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#else
#include <dir.h>
#endif
#include <dos.h>
#include <string.h>
/* Compatibility defines Win32 vs. DOS */
#ifdef WIN32
#define FIND_T WIN32_FIND_DATAA
#define FIND_T_FILENAME(fInfo) (fInfo.cFileName)
#define FIND_T_IS_DIR(fInfo) ((fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
#define FIND_T_IS_FILE(fInfo) ((fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
#define FIND_RET_T HANDLE
#define FINDFIRST_FILE(path, result) FindFirstFileA(path, result)
#define FINDFIRST_DIR(path, result) FindFirstFileA(path, result)
#define FINDNEXT(ff_res, result) FindNextFileA(ff_res, result)
#define FINDFIRST_SUCCEEDED(ret) (ret != INVALID_HANDLE_VALUE)
#define FINDNEXT_SUCCEEDED(ret) (ret == TRUE)
#define GETCWD(path, len) GetCurrentDirectoryA(len, path)
#define CHDIR(path) SetCurrentDirectoryA(path)
#define NEWLINE "\r\n"
#define NEWLINE_LEN 2
#else
#define FIND_T struct fflbk
#define FIND_T_FILENAME(fInfo) (fInfo.ff_name)
#define FIND_T_IS_DIR(fInfo) ((fInfo.ff_attrib & FA_DIREC) == FA_DIREC)
#define FIND_T_IS_FILE(fInfo) (1)
#define FIND_RET_T int
#define FINDFIRST_FILE(path, result) findfirst(path, result, FA_ARCH)
#define FINDFIRST_DIR(path, result) findfirst(path, result, FA_DIREC)
#define FINDNEXT(ff_res, result) FindNextFileA(ff_res, result)
#define FINDFIRST_SUCCEEDED(ret) (ret == 0)
#define FINDNEXT_SUCCEEDED(ret) (ret == 0)
#define GETCWD(path, len) getcwd(path, len)
#define CHDIR(path) chdir(path)
#endif
/* define this to get the header variables we use to build HTTP headers */
#define LWIP_HTTPD_DYNAMIC_HEADERS 1
#include "../httpd_structs.h"
#include "../../../lwip-1.4.0/src/core/ipv4/inet_chksum.c"
#include "../../../lwip-1.4.0/src/core/def.c"
/** (Your server name here) */
const char *serverID = "Server: "HTTPD_SERVER_AGENT"\r\n";
/* change this to suit your MEM_ALIGNMENT */
#define PAYLOAD_ALIGNMENT 4
/* set this to 0 to prevent aligning payload */
#define ALIGN_PAYLOAD 1
/* define this to a type that has the required alignment */
#define PAYLOAD_ALIGN_TYPE "unsigned int"
static int payload_alingment_dummy_counter = 0;
#define HEX_BYTES_PER_LINE 16
#define MAX_PATH_LEN 256
#define COPY_BUFSIZE 10240
int process_sub(FILE *data_file, FILE *struct_file);
int process_file(FILE *data_file, FILE *struct_file, const char *filename);
int file_write_http_header(FILE *data_file, const char *filename, int file_size,
u16_t *http_hdr_len, u16_t *http_hdr_chksum);
int file_put_ascii(FILE *file, const char *ascii_string, int len, int *i);
int s_put_ascii(char *buf, const char *ascii_string, int len, int *i);
void concat_files(const char *file1, const char *file2, const char *targetfile);
static unsigned char file_buffer_raw[COPY_BUFSIZE];
/* 5 bytes per char + 3 bytes per line */
static char file_buffer_c[COPY_BUFSIZE * 5 + ((COPY_BUFSIZE / HEX_BYTES_PER_LINE) * 3)];
char curSubdir[MAX_PATH_LEN];
char lastFileVar[MAX_PATH_LEN];
char hdr_buf[4096];
unsigned char processSubs = 1;
unsigned char includeHttpHeader = 1;
unsigned char useHttp11 = 0;
unsigned char precalcChksum = 0;
int main(int argc, char *argv[])
{
FIND_T fInfo;
FIND_RET_T fret;
char path[MAX_PATH_LEN];
char appPath[MAX_PATH_LEN];
FILE *data_file;
FILE *struct_file;
int filesProcessed;
int i;
char targetfile[MAX_PATH_LEN];
strcpy(targetfile, "fsdata.c");
memset(path, 0, sizeof(path));
memset(appPath, 0, sizeof(appPath));
printf(NEWLINE " makefsdata - HTML to C source converter" NEWLINE);
printf(" by Jim Pettinato - circa 2003 " NEWLINE);
printf(" extended by Simon Goldschmidt - 2009 " NEWLINE NEWLINE);
strcpy(path, "fs");
for(i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
if (strstr(argv[i], "-s")) {
processSubs = 0;
} else if (strstr(argv[i], "-e")) {
includeHttpHeader = 0;
} else if (strstr(argv[i], "-11")) {
useHttp11 = 1;
} else if (strstr(argv[i], "-c")) {
precalcChksum = 1;
} else if((argv[i][1] == 'f') && (argv[i][2] == ':')) {
strcpy(targetfile, &argv[i][3]);
printf("Writing to file \"%s\"\n", targetfile);
}
} else {
strcpy(path, argv[i]);
}
}
/* if command line param or subdir named 'fs' not found spout usage verbiage */
fret = FINDFIRST_DIR(path, &fInfo);
if (!FINDFIRST_SUCCEEDED(fret)) {
/* if no subdir named 'fs' (or the one which was given) exists, spout usage verbiage */
printf(" Failed to open directory \"%s\"." NEWLINE NEWLINE, path);
printf(" Usage: htmlgen [targetdir] [-s] [-i] [-f:<filename>]" NEWLINE NEWLINE);
printf(" targetdir: relative or absolute path to files to convert" NEWLINE);
printf(" switch -s: toggle processing of subdirectories (default is on)" NEWLINE);
printf(" switch -e: exclude HTTP header from file (header is created at runtime, default is off)" NEWLINE);
printf(" switch -11: include HTTP 1.1 header (1.0 is default)" NEWLINE);
printf(" switch -c: precalculate checksums for all pages (default is off)" NEWLINE);
printf(" switch -f: target filename (default is \"fsdata.c\")" NEWLINE);
printf(" if targetdir not specified, htmlgen will attempt to" NEWLINE);
printf(" process files in subdirectory 'fs'" NEWLINE);
exit(-1);
}
printf("HTTP %sheader will %s statically included." NEWLINE,
(includeHttpHeader ? (useHttp11 ? "1.1 " : "1.0 ") : ""),
(includeHttpHeader ? "be" : "not be"));
sprintf(curSubdir, ""); /* start off in web page's root directory - relative paths */
printf(" Processing all files in directory %s", path);
if (processSubs) {
printf(" and subdirectories..." NEWLINE NEWLINE);
} else {
printf("..." NEWLINE NEWLINE);
}
GETCWD(appPath, MAX_PATH_LEN);
data_file = fopen("fsdata.tmp", "wb");
if (data_file == NULL) {
printf("Failed to create file \"fsdata.tmp\"\n");
exit(-1);
}
struct_file = fopen("fshdr.tmp", "wb");
if (struct_file == NULL) {
printf("Failed to create file \"fshdr.tmp\"\n");
exit(-1);
}
CHDIR(path);
fprintf(data_file, "#include \"fs.h\"" NEWLINE);
fprintf(data_file, "#include \"lwip/def.h\"" NEWLINE);
fprintf(data_file, "#include \"fsdata.h\"" NEWLINE NEWLINE NEWLINE);
fprintf(data_file, "#define file_NULL (struct fsdata_file *) NULL" NEWLINE NEWLINE NEWLINE);
sprintf(lastFileVar, "NULL");
filesProcessed = process_sub(data_file, struct_file);
/* data_file now contains all of the raw data.. now append linked list of
* file header structs to allow embedded app to search for a file name */
fprintf(data_file, NEWLINE NEWLINE);
fprintf(struct_file, "#define FS_ROOT file_%s" NEWLINE, lastFileVar);
fprintf(struct_file, "#define FS_NUMFILES %d" NEWLINE NEWLINE, filesProcessed);
fclose(data_file);
fclose(struct_file);
CHDIR(appPath);
/* append struct_file to data_file */
printf(NEWLINE "Creating target file..." NEWLINE NEWLINE);
concat_files("fsdata.tmp", "fshdr.tmp", targetfile);
/* if succeeded, delete the temporary files */
remove("fsdata.tmp");
remove("fshdr.tmp");
printf(NEWLINE "Processed %d files - done." NEWLINE NEWLINE, filesProcessed);
return 0;
}
static void copy_file(const char *filename_in, FILE *fout)
{
FILE *fin;
size_t len;
fin = fopen(filename_in, "rb");
if (fin == NULL) {
printf("Failed to open file \"%s\"\n", filename_in);
exit(-1);
}
while((len = fread(file_buffer_raw, 1, COPY_BUFSIZE, fin)) > 0)
{
fwrite(file_buffer_raw, 1, len, fout);
}
fclose(fin);
}
void concat_files(const char *file1, const char *file2, const char *targetfile)
{
FILE *fout;
fout = fopen(targetfile, "wb");
if (fout == NULL) {
printf("Failed to open file \"%s\"\n", targetfile);
exit(-1);
}
copy_file(file1, fout);
copy_file(file2, fout);
fclose(fout);
}
int process_sub(FILE *data_file, FILE *struct_file)
{
FIND_T fInfo;
FIND_RET_T fret;
int filesProcessed = 0;
char oldSubdir[MAX_PATH_LEN];
if (processSubs) {
/* process subs recursively */
strcpy(oldSubdir, curSubdir);
fret = FINDFIRST_DIR("*", &fInfo);
if (FINDFIRST_SUCCEEDED(fret)) {
do {
const char *curName = FIND_T_FILENAME(fInfo);
if (curName == NULL) continue;
if (curName[0] == '.') continue;
if (strcmp(curName, "CVS") == 0) continue;
if (!FIND_T_IS_DIR(fInfo)) continue;
CHDIR(curName);
strcat(curSubdir, "/");
strcat(curSubdir, curName);
printf(NEWLINE "processing subdirectory %s/..." NEWLINE, curSubdir);
filesProcessed += process_sub(data_file, struct_file);
CHDIR("..");
strcpy(curSubdir, oldSubdir);
} while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo)));
}
}
fret = FINDFIRST_FILE("*.*", &fInfo);
if (FINDFIRST_SUCCEEDED(fret)) {
/* at least one file in directory */
do {
if (FIND_T_IS_FILE(fInfo)) {
const char *curName = FIND_T_FILENAME(fInfo);
printf("processing %s/%s..." NEWLINE, curSubdir, curName);
if (process_file(data_file, struct_file, curName) < 0) {
printf(NEWLINE "Error... aborting" NEWLINE);
return -1;
}
filesProcessed++;
}
} while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo)));
}
return filesProcessed;
}
int get_file_size(const char* filename)
{
FILE *inFile;
int file_size = -1;
inFile = fopen(filename, "rb");
if (inFile == NULL) {
printf("Failed to open file \"%s\"\n", filename);
exit(-1);
}
fseek(inFile, 0, SEEK_END);
file_size = ftell(inFile);
fclose(inFile);
return file_size;
}
void process_file_data(const char *filename, FILE *data_file)
{
FILE *source_file;
size_t len, written, i, src_off=0;
source_file = fopen(filename, "rb");
do {
size_t off = 0;
len = fread(file_buffer_raw, 1, COPY_BUFSIZE, source_file);
if (len > 0) {
for (i = 0; i < len; i++) {
sprintf(&file_buffer_c[off], "0x%02.2x,", file_buffer_raw[i]);
off += 5;
if ((++src_off % HEX_BYTES_PER_LINE) == 0) {
memcpy(&file_buffer_c[off], NEWLINE, NEWLINE_LEN);
off += NEWLINE_LEN;
}
}
written = fwrite(file_buffer_c, 1, off, data_file);
}
} while(len > 0);
fclose(source_file);
}
int write_checksums(FILE *struct_file, const char *filename, const char *varname,
u16_t hdr_len, u16_t hdr_chksum)
{
int chunk_size = TCP_MSS;
int offset;
size_t len;
int i = 0;
FILE *f;
#if LWIP_TCP_TIMESTAMPS
/* when timestamps are used, usable space is 12 bytes less per segment */
chunk_size -= 12;
#endif
fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE);
fprintf(struct_file, "const struct fsdata_chksum chksums_%s[] = {" NEWLINE, varname);
memset(file_buffer_raw, 0xab, sizeof(file_buffer_raw));
f = fopen(filename, "rb");
if (f == INVALID_HANDLE_VALUE) {
printf("Failed to open file \"%s\"\n", filename);
exit(-1);
}
if (hdr_len > 0) {
/* add checksum for HTTP header */
fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, 0, hdr_chksum, hdr_len);
i++;
}
for (offset = hdr_len; ; offset += len) {
unsigned short chksum;
len = fread(file_buffer_raw, 1, chunk_size, f);
if (len == 0) {
break;
}
chksum = ~inet_chksum(file_buffer_raw, (u16_t)len);
/* add checksum for data */
fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, offset, chksum, len);
i++;
}
fclose(f);
fprintf(struct_file, "};" NEWLINE);
fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE);
return i;
}
int process_file(FILE *data_file, FILE *struct_file, const char *filename)
{
char *pch;
char varname[MAX_PATH_LEN];
int i = 0;
char qualifiedName[MAX_PATH_LEN];
int file_size;
u16_t http_hdr_chksum = 0;
u16_t http_hdr_len = 0;
int chksum_count = 0;
/* create qualified name (TODO: prepend slash or not?) */
sprintf(qualifiedName,"%s/%s", curSubdir, filename);
/* create C variable name */
strcpy(varname, qualifiedName);
/* convert slashes & dots to underscores */
while ((pch = strpbrk(varname, "./\\")) != NULL) {
*pch = '_';
}
#if ALIGN_PAYLOAD
/* to force even alignment of array */
fprintf(data_file, "static const " PAYLOAD_ALIGN_TYPE " dummy_align_%s = %d;" NEWLINE, varname, payload_alingment_dummy_counter++);
#endif /* ALIGN_PAYLOAD */
fprintf(data_file, "static const unsigned char data_%s[] = {" NEWLINE, varname);
/* encode source file name (used by file system, not returned to browser) */
fprintf(data_file, "/* %s (%d chars) */" NEWLINE, qualifiedName, strlen(qualifiedName)+1);
file_put_ascii(data_file, qualifiedName, strlen(qualifiedName)+1, &i);
#if ALIGN_PAYLOAD
/* pad to even number of bytes to assure payload is on aligned boundary */
while(i % PAYLOAD_ALIGNMENT != 0) {
fprintf(data_file, "0x%02.2x,", 0);
i++;
}
#endif /* ALIGN_PAYLOAD */
fprintf(data_file, NEWLINE);
file_size = get_file_size(filename);
if (includeHttpHeader) {
file_write_http_header(data_file, filename, file_size, &http_hdr_len, &http_hdr_chksum);
}
if (precalcChksum) {
chksum_count = write_checksums(struct_file, filename, varname, http_hdr_len, http_hdr_chksum);
}
/* build declaration of struct fsdata_file in temp file */
fprintf(struct_file, "const struct fsdata_file file_%s[] = { {" NEWLINE, varname);
fprintf(struct_file, "file_%s," NEWLINE, lastFileVar);
fprintf(struct_file, "data_%s," NEWLINE, varname);
fprintf(struct_file, "data_%s + %d," NEWLINE, varname, i);
fprintf(struct_file, "sizeof(data_%s) - %d," NEWLINE, varname, i);
fprintf(struct_file, "%d," NEWLINE, includeHttpHeader);
if (precalcChksum) {
fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE);
fprintf(struct_file, "%d, chksums_%s," NEWLINE, chksum_count, varname);
fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE);
}
fprintf(struct_file, "}};" NEWLINE NEWLINE);
strcpy(lastFileVar, varname);
/* write actual file contents */
i = 0;
fprintf(data_file, NEWLINE "/* raw file data (%d bytes) */" NEWLINE, file_size);
process_file_data(filename, data_file);
fprintf(data_file, "};" NEWLINE NEWLINE);
return 0;
}
int file_write_http_header(FILE *data_file, const char *filename, int file_size,
u16_t *http_hdr_len, u16_t *http_hdr_chksum)
{
int i = 0;
int response_type = HTTP_HDR_OK;
int file_type = HTTP_HDR_DEFAULT_TYPE;
const char *cur_string;
size_t cur_len;
int written = 0;
size_t hdr_len = 0;
u16_t acc;
const char *file_ext;
int j;
memset(hdr_buf, 0, sizeof(hdr_buf));
if (useHttp11) {
response_type = HTTP_HDR_OK_11;
}
fprintf(data_file, NEWLINE "/* HTTP header */");
if (strstr(filename, "404") == filename) {
response_type = HTTP_HDR_NOT_FOUND;
if (useHttp11) {
response_type = HTTP_HDR_NOT_FOUND_11;
}
} else if (strstr(filename, "400") == filename) {
response_type = HTTP_HDR_BAD_REQUEST;
if (useHttp11) {
response_type = HTTP_HDR_BAD_REQUEST_11;
}
} else if (strstr(filename, "501") == filename) {
response_type = HTTP_HDR_NOT_IMPL;
if (useHttp11) {
response_type = HTTP_HDR_NOT_IMPL_11;
}
}
cur_string = g_psHTTPHeaderStrings[response_type];
cur_len = strlen(cur_string);
fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
written += file_put_ascii(data_file, cur_string, cur_len, &i);
i = 0;
if (precalcChksum) {
memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
hdr_len += cur_len;
}
cur_string = serverID;
cur_len = strlen(cur_string);
fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
written += file_put_ascii(data_file, cur_string, cur_len, &i);
i = 0;
if (precalcChksum) {
memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
hdr_len += cur_len;
}
file_ext = filename;
while(strstr(file_ext, ".") != NULL) {
file_ext = strstr(file_ext, ".");
file_ext++;
}
if((file_ext == NULL) || (*file_ext == 0)) {
printf("failed to get extension for file \"%s\", using default.\n", filename);
} else {
for(j = 0; j < NUM_HTTP_HEADERS; j++) {
if(!strcmp(file_ext, g_psHTTPHeaders[j].extension)) {
file_type = g_psHTTPHeaders[j].headerIndex;
break;
}
}
if (j >= NUM_HTTP_HEADERS) {
printf("failed to get file type for extension \"%s\", using default.\n", file_ext);
file_type = HTTP_HDR_DEFAULT_TYPE;
}
}
if (useHttp11) {
char intbuf[MAX_PATH_LEN];
memset(intbuf, 0, sizeof(intbuf));
cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH];
cur_len = strlen(cur_string);
fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%d+ bytes) */" NEWLINE, cur_string, file_size, cur_len+2);
written += file_put_ascii(data_file, cur_string, cur_len, &i);
if (precalcChksum) {
memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
hdr_len += cur_len;
}
_itoa(file_size, intbuf, 10);
strcat(intbuf, "\r\n");
cur_len = strlen(intbuf);
written += file_put_ascii(data_file, intbuf, cur_len, &i);
i = 0;
if (precalcChksum) {
memcpy(&hdr_buf[hdr_len], intbuf, cur_len);
hdr_len += cur_len;
}
cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE];
cur_len = strlen(cur_string);
fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
written += file_put_ascii(data_file, cur_string, cur_len, &i);
i = 0;
if (precalcChksum) {
memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
hdr_len += cur_len;
}
}
cur_string = g_psHTTPHeaderStrings[file_type];
cur_len = strlen(cur_string);
fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
written += file_put_ascii(data_file, cur_string, cur_len, &i);
i = 0;
if (precalcChksum) {
memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
hdr_len += cur_len;
LWIP_ASSERT("hdr_len <= 0xffff", hdr_len <= 0xffff);
LWIP_ASSERT("strlen(hdr_buf) == hdr_len", strlen(hdr_buf) == hdr_len);
acc = ~inet_chksum(hdr_buf, (u16_t)hdr_len);
*http_hdr_len = (u16_t)hdr_len;
*http_hdr_chksum = acc;
}
return written;
}
int file_put_ascii(FILE *file, const char* ascii_string, int len, int *i)
{
int x;
for(x = 0; x < len; x++) {
unsigned char cur = ascii_string[x];
fprintf(file, "0x%02.2x,", cur);
if ((++(*i) % HEX_BYTES_PER_LINE) == 0) {
fprintf(file, NEWLINE);
}
}
return len;
}
int s_put_ascii(char *buf, const char *ascii_string, int len, int *i)
{
int x;
int idx = 0;
for(x = 0; x < len; x++) {
unsigned char cur = ascii_string[x];
sprintf(&buf[idx], "0x%02.2x,", cur);
idx += 5;
if ((++(*i) % HEX_BYTES_PER_LINE) == 0) {
sprintf(&buf[idx], NEWLINE);
idx += NEWLINE_LEN;
}
}
return len;
}

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// MakeFSData_proj.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

@ -0,0 +1,15 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here

@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

@ -0,0 +1,238 @@
/*
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Standard includes. */
#include <string.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* lwIP core includes */
#include "lwip/opt.h"
#include "lwip/tcpip.h"
/* applications includes */
#include "apps/httpserver_raw_from_lwIP_download/httpd.h"
/* include the port-dependent configuration */
#include "lwipcfg_msvc.h"
/* Dimensions the cTxBuffer array - which is itself used to hold replies from
command line commands. cTxBuffer is a shared buffer, so protected by the
xTxBufferMutex mutex. */
#define lwipappsTX_BUFFER_SIZE 1024
/* The maximum time to block waiting to obtain the xTxBufferMutex to become
available. */
#define lwipappsMAX_TIME_TO_WAIT_FOR_TX_BUFFER_MS ( 100 / portTICK_RATE_MS )
/* Definitions of the various SSI callback functions within the pccSSITags
array. If pccSSITags is updated, then these definitions must also be updated. */
#define ssiTASK_STATS_INDEX 0
#define ssiRUN_TIME_STATS_INDEX 1
/*-----------------------------------------------------------*/
/*
* The function that implements the lwIP based sockets command interpreter
* server.
*/
extern void vBasicSocketsCommandInterpreterTask( void *pvParameters );
/*
* The SSI handler callback function passed to lwIP.
*/
static unsigned short uslwIPAppsSSIHandler( int iIndex, char *pcBuffer, int iBufferLength );
/*-----------------------------------------------------------*/
/* The SSI strings that are embedded in the served html files. If this array
is changed, then the index position defined by the #defines such as
ssiTASK_STATS_INDEX above must also be updated. */
static const char *pccSSITags[] =
{
"rtos_stats",
"run_stats"
};
/* Semaphore used to guard the Tx buffer. */
static xSemaphoreHandle xTxBufferMutex = NULL;
/* The Tx buffer itself. This is used to hold the text generated by the
execution of command line commands, and (hopefully) the execution of
server side include callbacks. It is a shared buffer so protected by the
xTxBufferMutex mutex. pcLwipAppsBlockingGetTxBuffer() and
vLwipAppsReleaseTxBuffer() are provided to obtain and release the
xTxBufferMutex respectively. pcLwipAppsBlockingGetTxBuffer() must be used with
caution as it has the potential to block. */
static signed char cTxBuffer[ lwipappsTX_BUFFER_SIZE ];
/*-----------------------------------------------------------*/
/* Called from the TCP/IP thread. */
void lwIPAppsInit( void *pvArgument )
{
ip_addr_t xIPAddr, xNetMask, xGateway;
extern err_t xemacpsif_init( struct netif *netif );
extern void xemacif_input_thread( struct netif *netif );
static struct netif xNetIf;
( void ) pvArgument;
/* Set up the network interface. */
ip_addr_set_zero( &xGateway );
ip_addr_set_zero( &xIPAddr );
ip_addr_set_zero( &xNetMask );
LWIP_PORT_INIT_GW(&xGateway);
LWIP_PORT_INIT_IPADDR( &xIPAddr );
LWIP_PORT_INIT_NETMASK(&xNetMask);
/* Set mac address */
xNetIf.hwaddr_len = 6;
xNetIf.hwaddr[ 0 ] = configMAC_ADDR0;
xNetIf.hwaddr[ 1 ] = configMAC_ADDR1;
xNetIf.hwaddr[ 2 ] = configMAC_ADDR2;
xNetIf.hwaddr[ 3 ] = configMAC_ADDR3;
xNetIf.hwaddr[ 4 ] = configMAC_ADDR4;
xNetIf.hwaddr[ 5 ] = configMAC_ADDR5;
netif_set_default( netif_add( &xNetIf, &xIPAddr, &xNetMask, &xGateway, XPAR_XEMACPS_0_BASEADDR, xemacpsif_init, tcpip_input ) );
netif_set_up( &xNetIf );
/* Install the server side include handler. */
http_set_ssi_handler( uslwIPAppsSSIHandler, pccSSITags, sizeof( pccSSITags ) / sizeof( char * ) );
/* Create the mutex used to ensure mutual exclusive access to the Tx
buffer. */
xTxBufferMutex = xSemaphoreCreateMutex();
configASSERT( xTxBufferMutex );
/* Create the httpd server from the standard lwIP code. This demonstrates
use of the lwIP raw API. */
httpd_init();
sys_thread_new( "lwIP Input", xemacif_input_thread, &xNetIf, configMINIMAL_STACK_SIZE * 6, tskIDLE_PRIORITY );
/* Create the FreeRTOS defined basic command server. This demonstrates use
of the lwIP sockets API. */
#warning Commented out CLI
// xTaskCreate( vBasicSocketsCommandInterpreterTask, "CmdInt", configMINIMAL_STACK_SIZE * 10, NULL, configMAX_PRIORITIES - 2, NULL );
}
/*-----------------------------------------------------------*/
static unsigned short uslwIPAppsSSIHandler( int iIndex, char *pcBuffer, int iBufferLength )
{
static unsigned int uiUpdateCount = 0;
static char cUpdateString[ 200 ];
extern char *pcMainGetTaskStatusMessage( void );
/* Unused parameter. */
( void ) iBufferLength;
/* The SSI handler function that generates text depending on the index of
the SSI tag encountered. */
switch( iIndex )
{
case ssiTASK_STATS_INDEX :
vTaskList( pcBuffer );
break;
case ssiRUN_TIME_STATS_INDEX :
vTaskGetRunTimeStats( pcBuffer );
break;
}
/* Include a count of the number of times an SSI function has been executed
in the returned string. */
uiUpdateCount++;
sprintf( cUpdateString, "\r\n\r\n%u\r\nStatus - %s", uiUpdateCount, pcMainGetTaskStatusMessage() );
strcat( pcBuffer, cUpdateString );
return strlen( pcBuffer );
}
/*-----------------------------------------------------------*/
signed char *pcLwipAppsBlockingGetTxBuffer( void )
{
signed char *pcReturn;
/* Attempt to obtain the semaphore that guards the Tx buffer. */
if( xSemaphoreTakeRecursive( xTxBufferMutex, lwipappsMAX_TIME_TO_WAIT_FOR_TX_BUFFER_MS ) == pdFAIL )
{
/* The semaphore could not be obtained before timing out. */
pcReturn = NULL;
}
else
{
/* The semaphore was obtained successfully. Return a pointer to the
Tx buffer. */
pcReturn = cTxBuffer;
}
return pcReturn;
}
/*-----------------------------------------------------------*/
void vLwipAppsReleaseTxBuffer( void )
{
/* Finished with the Tx buffer. Return the mutex. */
xSemaphoreGiveRecursive( xTxBufferMutex );
}

@ -0,0 +1,62 @@
/*
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef LWIP_APPS_H
#define LWIP_APPS_H
/* Functions used to obtain and release exclusive access to the Tx buffer. The
Get function will block if the Tx buffer is not available - use with care! */
signed char *pcLwipAppsBlockingGetTxBuffer( void );
void vLwipAppsReleaseTxBuffer( void );
#endif /* LWIP_APPS_H */

@ -0,0 +1,46 @@
/**
* Additional settings for the win32 port.
* Copy this to lwipcfg_msvc.h and make the config changes you need.
*/
/* configuration for this port */
#define PPP_USERNAME "Admin"
#define PPP_PASSWORD "pass"
/** Define this to the GUID of the windows network adapter to use
* or NOT define this if you want PACKET_LIB_ADAPTER_NR to be used */
/*#define PACKET_LIB_ADAPTER_GUID "00000000-0000-0000-0000-000000000000"*/
/*#define PACKET_LIB_GET_ADAPTER_NETADDRESS(addr) IP4_ADDR((addr), 192,168,1,0)*/
/*#define PACKET_LIB_QUIET*/
#define LWIP_PORT_INIT_IPADDR(addr) IP4_ADDR((addr), configIP_ADDR0,configIP_ADDR1,configIP_ADDR2,configIP_ADDR3)
#define LWIP_PORT_INIT_GW(addr) IP4_ADDR((addr), 192,168,0,3)
#define LWIP_PORT_INIT_NETMASK(addr) IP4_ADDR((addr), 255,255,255,0)
/* remember to change this MAC address to suit your needs!
the last octet will be increased by netif->num for each netif */
#define LWIP_MAC_ADDR_BASE {0x00,0x01,0x02,0x03,0x04,0x05}
/* configuration for applications */
#define LWIP_CHARGEN_APP 0
#define LWIP_DNS_APP 0
#define LWIP_HTTPD_APP 1
/* Set this to 1 to use the netconn http server,
* otherwise the raw api server will be used. */
/*#define LWIP_HTTPD_APP_NETCONN */
#define LWIP_NETBIOS_APP 0
#define LWIP_NETIO_APP 0
#define LWIP_PING_APP 0
#define LWIP_RTP_APP 0
#define LWIP_SHELL_APP 0
#define LWIP_SNTP_APP 0
#define LWIP_SOCKET_EXAMPLES_APP 0
#define LWIP_TCPECHO_APP 0
/* Set this to 1 to use the netconn tcpecho server,
* otherwise the raw api server will be used. */
/*#define LWIP_TCPECHO_APP_NETCONN */
#define LWIP_UDPECHO_APP 0

@ -0,0 +1,109 @@
/*
* 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_CC_H__
#define __ARCH_CC_H__
#if 1
/* Include some files for defining library routines */
#include <stdio.h> /* printf, fflush, FILE */
#include <stdlib.h> /* abort */
#else
/* Declare fuction prototypes for assert/diag/error - leads to some warnings,
* but good to test if no includes are missing. */
int printf(const char *format, ...);
void abort(void);
struct _iobuf;
typedef struct _iobuf FILE;
int fflush(FILE *stream);
#endif
/** @todo fix some warnings: don't use #pragma if compiling with cygwin gcc */
#ifndef __GNUC__
#include <limits.h>
#pragma warning (disable: 4244) /* disable conversion warning (implicit integer promotion!) */
#pragma warning (disable: 4127) /* conditional expression is constant */
#pragma warning (disable: 4996) /* 'strncpy' was declared deprecated */
#pragma warning (disable: 4103) /* structure packing changed by including file */
#endif
#define LWIP_PROVIDE_ERRNO
/* Define platform endianness (might already be defined) */
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* BYTE_ORDER */
/* Define generic types used in lwIP */
typedef unsigned char u8_t;
typedef signed char s8_t;
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned long u32_t;
typedef signed long s32_t;
typedef size_t mem_ptr_t;
typedef u32_t sys_prot_t;
/* Define (sn)printf formatters for these lwIP types */
#define X8_F "02x"
#define U16_F "hu"
#define S16_F "hd"
#define X16_F "hx"
#define U32_F "lu"
#define S32_F "ld"
#define X32_F "lx"
#define SZT_F U32_F
/* Compiler hints for packing structures */
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_USE_INCLUDES
/* Plaform specific diagnostic output */
#define LWIP_PLATFORM_DIAG(x) do { printf x; } while(0)
#define LWIP_PLATFORM_ASSERT(x) do { printf("Assertion \"%s\" failed at line %d in %s\n", \
x, __LINE__, __FILE__); fflush(NULL); abort(); } while(0)
#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
printf("Assertion \"%s\" failed at line %d in %s\n", message, __LINE__, __FILE__); \
fflush(NULL);handler;} } while(0)
/* C runtime functions redefined */
#define snprintf _snprintf
u32_t dns_lookup_external_hosts_file(const char *name);
#define LWIP_RAND() ((u32_t)rand())
#endif /* __ARCH_CC_H__ */

@ -0,0 +1,40 @@
/*
* Copyright (c) 2001, 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. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE OR CONTRIBUTORS 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__ */

@ -0,0 +1,58 @@
/*
* 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_SYS_ARCH_H__
#define __ARCH_SYS_ARCH_H__
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#define SYS_MBOX_NULL ( ( QueueHandle_t ) NULL )
#define SYS_SEM_NULL ( ( SemaphoreHandle_t ) NULL )
#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
typedef SemaphoreHandle_t sys_sem_t;
typedef SemaphoreHandle_t sys_mutex_t;
typedef QueueHandle_t sys_mbox_t;
typedef TaskHandle_t sys_thread_t;
typedef unsigned long sys_prot_t;
#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
#define sys_mbox_set_invalid( x ) ( ( *x ) = NULL )
#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
#define sys_sem_set_invalid( x ) ( ( *x ) = NULL )
#endif /* __ARCH_SYS_ARCH_H__ */

@ -0,0 +1,67 @@
/*
* Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __XADAPTER_H_
#define __XADAPTER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "lwipopts.h"
#if !NO_SYS
#ifdef OS_IS_XILKERNEL
#include "xmk.h"
#endif
#include "lwip/sys.h"
#endif
#include "lwip/netif.h"
#include "lwip/ip.h"
#include "netif/xtopology.h"
struct xemac_s {
enum xemac_types type;
int topology_index;
void *state;
#if !NO_SYS
sys_sem_t sem_rx_data_available;
#endif
};
void lwip_raw_init();
int xemacif_input(struct netif *netif);
void xemacif_input_thread(struct netif *netif);
struct netif * xemac_add(struct netif *netif,
struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw,
unsigned char *mac_ethernet_address,
unsigned mac_baseaddr);
#ifdef __arm__
void xemacpsif_resetrx_on_no_rxdata(struct netif *netif);
#endif
/* global lwip debug variable used for debugging */
extern int lwip_runtime_debug;
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,94 @@
/*
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __NETIF_XAXIEMACIF_H__
#define __NETIF_XAXIEMACIF_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "xlwipconfig.h"
#include "lwip/netif.h"
#include "netif/etharp.h"
#include "netif/xadapter.h"
#include "xparameters.h"
#include "xstatus.h"
#include "xaxiethernet.h"
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_FIFO
#include "xllfifo.h"
#else
#include "xaxidma.h"
#include "xaxidma_hw.h"
#endif
#include "netif/xpqueue.h"
#include "xlwipconfig.h"
void xaxiemacif_setmac(u32_t index, u8_t *addr);
u8_t* xaxiemacif_getmac(u32_t index);
err_t xaxiemacif_init(struct netif *netif);
int xaxiemacif_input(struct netif *netif);
unsigned get_IEEE_phy_speed(XAxiEthernet *xaxiemacp);
unsigned configure_IEEE_phy_speed(XAxiEthernet *xaxiemacp, unsigned speed);
unsigned Phy_Setup (XAxiEthernet *xaxiemacp);
/* xaxiemacif_hw.c */
void xaxiemac_error_handler(XAxiEthernet * Temac);
/* structure within each netif, encapsulating all information required for
* using a particular temac instance
*/
typedef struct {
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_FIFO
XLlFifo axififo;
#else
XAxiDma axidma;
#endif
XAxiEthernet axi_ethernet;
/* queue to store overflow packets */
pq_queue_t *recv_q;
pq_queue_t *send_q;
/* pointers to memory holding buffer descriptors (used only with SDMA) */
void *rx_bdspace;
void *tx_bdspace;
} xaxiemacif_s;
extern xaxiemacif_s xaxiemacif;
int is_tx_space_available(xaxiemacif_s *emac);
/* xaxiemacif_dma.c */
#ifndef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_FIFO
XStatus init_axi_dma(struct xemac_s *xemac);
int process_sent_bds(XAxiDma_BdRing *txring);
void axidma_send_handler(void *arg);
XStatus axidma_sgsend(xaxiemacif_s *xaxiemacif, struct pbuf *p);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __NETIF_XAXIEMACIF_H__ */

@ -0,0 +1,53 @@
/*
* Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __NETIF_XEMACLITEIF_H__
#define __NETIF_XEMACLITEIF_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "lwip/netif.h"
#include "netif/etharp.h"
#include "netif/xpqueue.h"
#include "xemaclite.h"
#include "xemaclite_i.h"
#include "xstatus.h"
/* structure within each netif, encapsulating all information required for
* using a particular emaclite instance
*/
typedef struct {
XEmacLite *instance;
/* queue to store overflow packets */
pq_queue_t *recv_q;
pq_queue_t *send_q;
} xemacliteif_s;
void xemacliteif_setmac(u32_t index, u8_t *addr);
u8_t* xemacliteif_getmac(u32_t index);
err_t xemacliteif_init(struct netif *netif);
int xemacliteif_input(struct netif *netif);
#ifdef __cplusplus
}
#endif
#endif /* __NETIF_XEMACLITEIF_H__ */

@ -0,0 +1,109 @@
/*
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __NETIF_XEMACPSIF_H__
#define __NETIF_XEMACPSIF_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "xlwipconfig.h"
#include "lwip/netif.h"
#include "netif/etharp.h"
#include "netif/xadapter.h"
#include "xstatus.h"
#include "sleep.h"
#include "xparameters.h"
#include "xparameters_ps.h" /* defines XPAR values */
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
#include "xil_exception.h"
#include "xpseudo_asm.h"
#include "xil_cache.h"
#include "xil_printf.h"
#include "xuartps.h"
#include "xscugic.h"
#include "xemacps.h" /* defines XEmacPs API */
#include "netif/xpqueue.h"
#include "xlwipconfig.h"
void xemacpsif_setmac(u32_t index, u8_t *addr);
u8_t* xemacpsif_getmac(u32_t index);
err_t xemacpsif_init(struct netif *netif);
int xemacpsif_input(struct netif *netif);
#ifdef NOTNOW_BHILL
unsigned get_IEEE_phy_speed(XLlTemac *xlltemacp);
#endif
/* xaxiemacif_hw.c */
void xemacps_error_handler(XEmacPs * Temac);
/* structure within each netif, encapsulating all information required for
* using a particular temac instance
*/
typedef struct {
XEmacPs emacps;
/* queue to store overflow packets */
pq_queue_t *recv_q;
pq_queue_t *send_q;
/* pointers to memory holding buffer descriptors (used only with SDMA) */
void *rx_bdspace;
void *tx_bdspace;
unsigned int last_rx_frms_cntr;
} xemacpsif_s;
extern xemacpsif_s xemacpsif;
int is_tx_space_available(xemacpsif_s *emac);
/* xaxiemacif_dma.c */
XStatus init_axi_dma(struct xemac_s *xemac);
void process_sent_bds(XEmacPs_BdRing *txring);
unsigned Phy_Setup (XEmacPs *xemacpsp);
void emacps_send_handler(void *arg);
XStatus emacps_sgsend(xemacpsif_s *xemacpsif, struct pbuf *p);
void emacps_recv_handler(void *arg);
void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord);
void setup_rx_bds(XEmacPs_BdRing *rxring);
void HandleTxErrors(struct xemac_s *xemac);
void HandleEmacPsError(struct xemac_s *xemac);
XEmacPs_Config *xemacps_lookup_config(unsigned mac_base);
void init_emacps(xemacpsif_s *xemacps, struct netif *netif);
void setup_isr (struct xemac_s *xemac);
XStatus init_dma(struct xemac_s *xemac);
void start_emacps (xemacpsif_s *xemacps);
void FreeTxRxPBufs(void);
void FreeOnlyTxPBufs(void);
void init_emacps_on_error (xemacpsif_s *xemacps, struct netif *netif);
void clean_dma_txdescs(struct xemac_s *xemac);
void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif);
#ifdef __cplusplus
}
#endif
#endif /* __NETIF_XAXIEMACIF_H__ */

@ -0,0 +1,80 @@
/*
* Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __NETIF_XLLTEMACIF_H__
#define __NETIF_XLLTEMACIF_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "lwip/netif.h"
#include "netif/etharp.h"
#include "netif/xadapter.h"
#include "xparameters.h"
#include "xstatus.h"
#include "xlltemac.h"
#include "xlldma.h"
#include "xllfifo.h"
#include "xlldma_bdring.h"
#include "netif/xpqueue.h"
#include "xlwipconfig.h"
void xlltemacif_setmac(u32_t index, u8_t *addr);
u8_t* xlltemacif_getmac(u32_t index);
err_t xlltemacif_init(struct netif *netif);
int xlltemacif_input(struct netif *netif);
unsigned get_IEEE_phy_speed(XLlTemac *xlltemacp);
unsigned Phy_Setup (XLlTemac *xlltemacp);
unsigned configure_IEEE_phy_speed(XLlTemac *xlltemacp, unsigned speed);
/* xlltemacif_hw.c */
void xlltemac_error_handler(XLlTemac * Temac);
/* structure within each netif, encapsulating all information required for
* using a particular temac instance
*/
typedef struct {
XLlDma lldma;
XLlFifo llfifo;
XLlTemac lltemac;
/* queue to store overflow packets */
pq_queue_t *recv_q;
pq_queue_t *send_q;
/* pointers to memory holding buffer descriptors (used only with SDMA) */
void *rx_bdspace;
void *tx_bdspace;
} xlltemacif_s;
extern xlltemacif_s xlltemacif;
/* xlltemacif_sdma.c */
XStatus init_sdma(struct xemac_s *xemac);
int process_sent_bds(XLlDma_BdRing *txring);
void lldma_send_handler(void *arg);
XStatus lldma_sgsend(xlltemacif_s *xlltemacif, struct pbuf *p);
#ifdef __cplusplus
}
#endif
#endif /* __NETIF_XLLTEMACIF_H__ */

@ -0,0 +1,42 @@
/*
* Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __LWIP_PBUF_QUEUE_H_
#define __LWIP_PBUF_QUEUE_H_
#ifdef __cplusplus
extern "C" {
#endif
#define PQ_QUEUE_SIZE 4096
typedef struct {
void *data[PQ_QUEUE_SIZE];
int head, tail, len;
} pq_queue_t;
pq_queue_t* pq_create_queue();
int pq_enqueue(pq_queue_t *q, void *p);
void* pq_dequeue(pq_queue_t *q);
int pq_qlength(pq_queue_t *q);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,46 @@
/*
* Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __XTOPOLOGY_H_
#define __XTOPOLOGY_H_
#ifdef __cplusplus
extern "C" {
#endif
enum xemac_types { xemac_type_unknown = -1, xemac_type_xps_emaclite, xemac_type_xps_ll_temac, xemac_type_axi_ethernet, xemac_type_emacps };
struct xtopology_t {
unsigned emac_baseaddr;
enum xemac_types emac_type;
unsigned intc_baseaddr;
unsigned intc_emac_intr; /* valid only for xemac_type_xps_emaclite */
unsigned scugic_baseaddr; /* valid only for Zynq */
unsigned scugic_emac_intr; /* valid only for GEM */
};
extern int xtopology_n_emacs;
extern struct xtopology_t xtopology[];
int xtopology_find_index(unsigned base);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,12 @@
#ifndef __XLWIPCONFIG_H_
#define __XLWIPCONFIG_H_
/* This is a generated file - do not edit */
#define XLWIP_CONFIG_INCLUDE_GEM 1
#define XLWIP_CONFIG_EMAC_NUMBER 0
#define XLWIP_CONFIG_N_TX_DESC 64
#define XLWIP_CONFIG_N_RX_DESC 64
#endif

@ -0,0 +1,274 @@
/*
* Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include "lwipopts.h"
#include "xlwipconfig.h"
#if !NO_SYS
#ifdef OS_IS_XILKERNEL
#include "xmk.h"
#include "sys/process.h"
#endif
#endif
#include "lwip/mem.h"
#include "lwip/stats.h"
#include "lwip/sys.h"
#include "lwip/ip.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
#include "lwip/tcp_impl.h"
#include "netif/etharp.h"
#include "netif/xadapter.h"
#ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
#include "netif/xemacliteif.h"
#endif
#ifdef XLWIP_CONFIG_INCLUDE_TEMAC
#include "netif/xlltemacif.h"
#endif
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
#include "netif/xaxiemacif.h"
#endif
#ifdef XLWIP_CONFIG_INCLUDE_GEM
#include "netif/xemacpsif.h"
#endif
#if !NO_SYS
#include "lwip/tcpip.h"
#endif
/* global lwip debug variable used for debugging */
int lwip_runtime_debug = 0;
void
lwip_raw_init()
{
ip_init(); /* Doesn't do much, it should be called to handle future changes. */
#if LWIP_UDP
udp_init(); /* Clears the UDP PCB list. */
#endif
#if LWIP_TCP
tcp_init(); /* Clears the TCP PCB list and clears some internal TCP timers. */
/* Note: you must call tcp_fasttmr() and tcp_slowtmr() at the */
/* predefined regular intervals after this initialization. */
#endif
}
static enum xemac_types
find_mac_type(unsigned base)
{
int i;
for (i = 0; i < xtopology_n_emacs; i++) {
if (xtopology[i].emac_baseaddr == base)
return xtopology[i].emac_type;
}
return xemac_type_unknown;
}
int
xtopology_find_index(unsigned base)
{
int i;
for (i = 0; i < xtopology_n_emacs; i++) {
if (xtopology[i].emac_baseaddr == base)
return i;
}
return -1;
}
/*
* xemac_add: this is a wrapper around lwIP's netif_add function.
* The objective is to provide portability between the different Xilinx MAC's
* This function can be used to add both xps_ethernetlite and xps_ll_temac
* based interfaces
*/
struct netif *
xemac_add(struct netif *netif,
struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw,
unsigned char *mac_ethernet_address,
unsigned mac_baseaddr)
{
int i;
/* set mac address */
netif->hwaddr_len = 6;
for (i = 0; i < 6; i++)
netif->hwaddr[i] = mac_ethernet_address[i];
/* initialize based on MAC type */
switch (find_mac_type(mac_baseaddr)) {
case xemac_type_xps_emaclite:
#ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
return netif_add(netif, ipaddr, netmask, gw,
(void*)mac_baseaddr,
xemacliteif_init,
#if NO_SYS
ethernet_input
#else
tcpip_input
#endif
);
#else
return NULL;
#endif
case xemac_type_xps_ll_temac:
#ifdef XLWIP_CONFIG_INCLUDE_TEMAC
return netif_add(netif, ipaddr, netmask, gw,
(void*)mac_baseaddr,
xlltemacif_init,
#if NO_SYS
ethernet_input
#else
tcpip_input
#endif
);
#else
return NULL;
#endif
case xemac_type_axi_ethernet:
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
return netif_add(netif, ipaddr, netmask, gw,
(void*)mac_baseaddr,
xaxiemacif_init,
#if NO_SYS
ethernet_input
#else
tcpip_input
#endif
);
#else
return NULL;
#endif
#ifdef __arm__
case xemac_type_emacps:
#ifdef XLWIP_CONFIG_INCLUDE_GEM
return netif_add(netif, ipaddr, netmask, gw,
(void*)mac_baseaddr,
xemacpsif_init,
#if NO_SYS
ethernet_input
#else
tcpip_input
#endif
);
#endif
#endif
default:
printf("unable to determine type of EMAC with baseaddress 0x%08x\r\n",
mac_baseaddr);
return NULL;
}
}
#if !NO_SYS
/*
* The input thread calls lwIP to process any received packets.
* This thread waits until a packet is received (sem_rx_data_available),
* and then calls xemacif_input which processes 1 packet at a time.
*/
void
xemacif_input_thread(struct netif *netif)
{
struct xemac_s *emac = (struct xemac_s *)netif->state;
while (1) {
/* sleep until there are packets to process
* This semaphore is set by the packet receive interrupt
* routine.
*/
sys_sem_wait(&emac->sem_rx_data_available);
/* move all received packets to lwIP */
xemacif_input(netif);
}
}
#endif
int
xemacif_input(struct netif *netif)
{
struct xemac_s *emac = (struct xemac_s *)netif->state;
SYS_ARCH_DECL_PROTECT(lev);
int n_packets = 0;
switch (emac->type) {
case xemac_type_xps_emaclite:
#ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
SYS_ARCH_PROTECT(lev);
n_packets = xemacliteif_input(netif);
SYS_ARCH_UNPROTECT(lev);
break;
#else
print("incorrect configuration: xps_ethernetlite drivers not present?");
while(1);
return 0;
#endif
case xemac_type_xps_ll_temac:
#ifdef XLWIP_CONFIG_INCLUDE_TEMAC
SYS_ARCH_PROTECT(lev);
n_packets = xlltemacif_input(netif);
SYS_ARCH_UNPROTECT(lev);
break;
#else
print("incorrect configuration: xps_ll_temac drivers not present?");
while(1);
return 0;
#endif
case xemac_type_axi_ethernet:
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
SYS_ARCH_PROTECT(lev);
n_packets = xaxiemacif_input(netif);
SYS_ARCH_UNPROTECT(lev);
break;
#else
print("incorrect configuration: axi_ethernet drivers not present?");
while(1);
return 0;
#endif
#ifdef __arm__
case xemac_type_emacps:
#ifdef XLWIP_CONFIG_INCLUDE_GEM
SYS_ARCH_PROTECT(lev);
n_packets = xemacpsif_input(netif);
SYS_ARCH_UNPROTECT(lev);
break;
#else
xil_printf("incorrect configuration: ps7_ethernet drivers not present?\r\n");
while(1);
return 0;
#endif
#endif
default:
print("incorrect configuration: unknown temac type");
while(1);
return 0;
}
return n_packets;
}

@ -0,0 +1,458 @@
/*
* 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>
*
*/
/*
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <stdio.h>
#include <string.h>
#include <xparameters.h>
#include "lwipopts.h"
#include "xlwipconfig.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "lwip/igmp.h"
#include "netif/etharp.h"
#include "netif/xemacpsif.h"
#include "netif/xadapter.h"
#include "netif/xpqueue.h"
#include "xparameters.h"
#include "xuartps.h"
#include "xscugic.h"
#include "xemacps.h"
/* Define those to better describe your network interface. */
#define IFNAME0 't'
#define IFNAME1 'e'
#if LWIP_IGMP
static err_t xemacpsif_mac_filter_update (struct netif *netif,
struct ip_addr *group, u8_t action);
static u8_t xemacps_mcast_entry_mask = 0;
#endif
XEmacPs_Config *mac_config;
struct netif *NetIf;
void FreeTxPBufs(void);
/*
* this function is always called with interrupts off
* this function also assumes that there are available BD's
*/
static err_t _unbuffered_low_level_output(xemacpsif_s *xemacpsif,
struct pbuf *p)
{
XStatus status = 0;
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
status = emacps_sgsend(xemacpsif, p);
if (status != XST_SUCCESS) {
#if LINK_STATS
lwip_stats.link.drop++;
#endif
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
#if LINK_STATS
lwip_stats.link.xmit++;
#endif /* LINK_STATS */
return ERR_OK;
}
/*
* low_level_output():
*
* 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.
*
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
SYS_ARCH_DECL_PROTECT(lev);
err_t err;
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
SYS_ARCH_PROTECT(lev);
/* check if space is available to send */
if (is_tx_space_available(xemacpsif)) {
_unbuffered_low_level_output(xemacpsif, p);
err = ERR_OK;
} else {
#if LINK_STATS
lwip_stats.link.drop++;
#endif
print("pack dropped, no space\r\n");
err = ERR_MEM;
}
SYS_ARCH_UNPROTECT(lev);
return err;
}
/*
* low_level_input():
*
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
*/
static struct pbuf * low_level_input(struct netif *netif)
{
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
struct pbuf *p;
/* see if there is data to process */
if (pq_qlength(xemacpsif->recv_q) == 0)
return NULL;
/* return one packet from receive q */
p = (struct pbuf *)pq_dequeue(xemacpsif->recv_q);
return p;
}
/*
* xemacpsif_output():
*
* This function is called by the TCP/IP stack when an IP packet
* should be sent. It calls the function called low_level_output() to
* do the actual transmission of the packet.
*
*/
static err_t xemacpsif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr)
{
/* resolve hardware address, then send (or queue) packet */
return etharp_output(netif, p, ipaddr);
}
/*
* xemacpsif_input():
*
* 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.
*
* Returns the number of packets read (max 1 packet on success,
* 0 if there are no packets)
*
*/
int xemacpsif_input(struct netif *netif)
{
struct eth_hdr *ethhdr;
struct pbuf *p;
SYS_ARCH_DECL_PROTECT(lev);
#ifdef OS_IS_FREERTOS
while (1)
#endif
{
/* move received packet into a new pbuf */
SYS_ARCH_PROTECT(lev);
p = low_level_input(netif);
SYS_ARCH_UNPROTECT(lev);
/* no packet could be read, silently ignore this */
if (p == NULL) {
return 0;
}
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
#if LINK_STATS
lwip_stats.link.recv++;
#endif /* LINK_STATS */
switch (htons(ethhdr->type)) {
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_ARP:
#if PPPOE_SUPPORT
/* PPPoE packet? */
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* full packet send to tcpip_thread to process */
if (netif->input(p, netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("xemacpsif_input: IP input error\r\n"));
pbuf_free(p);
p = NULL;
}
break;
default:
pbuf_free(p);
p = NULL;
break;
}
}
return 1;
}
static err_t low_level_init(struct netif *netif)
{
unsigned mac_address = (unsigned)(netif->state);
struct xemac_s *xemac;
xemacpsif_s *xemacpsif;
u32 dmacrreg;
int Status = XST_SUCCESS;
NetIf = netif;
xemacpsif = mem_malloc(sizeof *xemacpsif);
if (xemacpsif == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, ("xemacpsif_init: out of memory\r\n"));
return ERR_MEM;
}
xemac = mem_malloc(sizeof *xemac);
if (xemac == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, ("xemacpsif_init: out of memory\r\n"));
return ERR_MEM;
}
xemac->state = (void *)xemacpsif;
xemac->topology_index = xtopology_find_index(mac_address);
xemac->type = xemac_type_emacps;
xemacpsif->send_q = NULL;
xemacpsif->recv_q = pq_create_queue();
if (!xemacpsif->recv_q)
return ERR_MEM;
/* maximum transfer unit */
netif->mtu = XEMACPS_MTU - XEMACPS_HDR_SIZE;
#if LWIP_IGMP
netif->igmp_mac_filter = xemacpsif_mac_filter_update;
#endif
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
NETIF_FLAG_LINK_UP;
#if LWIP_IGMP
netif->flags |= NETIF_FLAG_IGMP;
#endif
#if !NO_SYS
sys_sem_new(&xemac->sem_rx_data_available, 0);
#endif
/* obtain config of this emac */
mac_config = (XEmacPs_Config *)xemacps_lookup_config((unsigned)netif->state);
Status = XEmacPs_CfgInitialize(&xemacpsif->emacps, mac_config,
mac_config->BaseAddress);
if (Status != XST_SUCCESS) {
xil_printf("In %s:EmacPs Configuration Failed....\r\n", __func__);
}
/* initialize the mac */
init_emacps(xemacpsif, netif);
dmacrreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_DMACR_OFFSET);
dmacrreg = dmacrreg | (0x00000010);
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_DMACR_OFFSET, dmacrreg);
setup_isr(xemac);
init_dma(xemac);
start_emacps(xemacpsif);
/* replace the state in netif (currently the emac baseaddress)
* with the mac instance pointer.
*/
netif->state = (void *)xemac;
return ERR_OK;
}
void HandleEmacPsError(struct xemac_s *xemac)
{
xemacpsif_s *xemacpsif;
int Status = XST_SUCCESS;
u32 dmacrreg;
SYS_ARCH_DECL_PROTECT(lev);
SYS_ARCH_PROTECT(lev);
FreeTxRxPBufs();
xemacpsif = (xemacpsif_s *)(xemac->state);
Status = XEmacPs_CfgInitialize(&xemacpsif->emacps, mac_config,
mac_config->BaseAddress);
if (Status != XST_SUCCESS) {
xil_printf("In %s:EmacPs Configuration Failed....\r\n", __func__);
}
/* initialize the mac */
init_emacps_on_error(xemacpsif, NetIf);
dmacrreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_DMACR_OFFSET);
dmacrreg = dmacrreg | (0x01000000);
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_DMACR_OFFSET, dmacrreg);
setup_isr(xemac);
init_dma(xemac);
start_emacps(xemacpsif);
SYS_ARCH_UNPROTECT(lev);
}
void HandleTxErrors(struct xemac_s *xemac)
{
xemacpsif_s *xemacpsif;
u32 netctrlreg;
SYS_ARCH_DECL_PROTECT(lev);
SYS_ARCH_PROTECT(lev);
xemacpsif = (xemacpsif_s *)(xemac->state);
netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET, netctrlreg);
FreeOnlyTxPBufs();
clean_dma_txdescs(xemac);
netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET, netctrlreg);
SYS_ARCH_UNPROTECT(lev);
}
#if LWIP_IGMP
static err_t xemacpsif_mac_filter_update (struct netif *netif, struct ip_addr *group,
u8_t action)
{
return 0;
}
#endif
/*
* xemacpsif_init():
*
* 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.
*
*/
err_t xemacpsif_init(struct netif *netif)
{
#if LWIP_SNMP
/* ifType ethernetCsmacd(6) @see RFC1213 */
netif->link_type = 6;
/* your link speed here */
netif->link_speed = ;
netif->ts = 0;
netif->ifinoctets = 0;
netif->ifinucastpkts = 0;
netif->ifinnucastpkts = 0;
netif->ifindiscards = 0;
netif->ifoutoctets = 0;
netif->ifoutucastpkts = 0;
netif->ifoutnucastpkts = 0;
netif->ifoutdiscards = 0;
#endif
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
netif->output = xemacpsif_output;
netif->linkoutput = low_level_output;
low_level_init(netif);
return ERR_OK;
}
/*
* xemacpsif_resetrx_on_no_rxdata():
*
* Should be called by the user at regular intervals, typically
* from a timer (100 msecond). This is to provide a SW workaround
* for the HW bug (SI #692601). Please refer to the function header
* for the function resetrx_on_no_rxdata in xemacpsif_dma.c to
* know more about the SI.
*
*/
void xemacpsif_resetrx_on_no_rxdata(struct netif *netif)
{
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
resetrx_on_no_rxdata(xemacpsif);
}

@ -0,0 +1,606 @@
/*
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include "lwipopts.h"
#include "lwip/stats.h"
#include "lwip/sys.h"
#include "lwip/inet_chksum.h"
#include "netif/xadapter.h"
#include "netif/xemacpsif.h"
#include "xstatus.h"
#include "xlwipconfig.h"
#include "xparameters.h"
#include "xparameters_ps.h"
#include "xil_exception.h"
#include "xil_mmu.h"
#ifdef CONFIG_XTRACE
#include "xtrace.h"
#endif
#ifdef OS_IS_FREERTOS
#include "FreeRTOS.h"
#include "semphr.h"
#include "timers.h"
#endif
/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
*** to run it on a PEEP board
***/
#define INTC_BASE_ADDR XPAR_SCUGIC_CPU_BASEADDR
#define INTC_DIST_BASE_ADDR XPAR_SCUGIC_DIST_BASEADDR
/* Byte alignment of BDs */
#define BD_ALIGNMENT (XEMACPS_DMABD_MINIMUM_ALIGNMENT*2)
static int tx_pbufs_storage[XLWIP_CONFIG_N_TX_DESC];
static int rx_pbufs_storage[XLWIP_CONFIG_N_RX_DESC];
static int EmacIntrNum;
extern u8 _end;
#ifdef OS_IS_FREERTOS
long xInsideISR = 0;
#endif
#define XEMACPS_BD_TO_INDEX(ringptr, bdptr) \
(((u32)bdptr - (u32)(ringptr)->BaseBdAddr) / (ringptr)->Separation)
int is_tx_space_available(xemacpsif_s *emac)
{
XEmacPs_BdRing *txring;
int freecnt = 0;
txring = &(XEmacPs_GetTxRing(&emac->emacps));
/* tx space is available as long as there are valid BD's */
freecnt = XEmacPs_BdRingGetFreeCnt(txring);
return freecnt;
}
void process_sent_bds(XEmacPs_BdRing *txring)
{
XEmacPs_Bd *txbdset;
XEmacPs_Bd *CurBdPntr;
int n_bds;
XStatus Status;
int n_pbufs_freed = 0;
unsigned int BdIndex;
struct pbuf *p;
unsigned int *Temp;
while (1) {
/* obtain processed BD's */
n_bds = XEmacPs_BdRingFromHwTx(txring,
XLWIP_CONFIG_N_TX_DESC, &txbdset);
if (n_bds == 0) {
return;
}
/* free the processed BD's */
n_pbufs_freed = n_bds;
CurBdPntr = txbdset;
while (n_pbufs_freed > 0) {
BdIndex = XEMACPS_BD_TO_INDEX(txring, CurBdPntr);
Temp = (unsigned int *)CurBdPntr;
*Temp = 0;
Temp++;
*Temp = 0x80000000;
if (BdIndex == (XLWIP_CONFIG_N_TX_DESC - 1)) {
*Temp = 0xC0000000;
}
p = (struct pbuf *)tx_pbufs_storage[BdIndex];
if(p != NULL) {
pbuf_free(p);
}
tx_pbufs_storage[BdIndex] = 0;
CurBdPntr = XEmacPs_BdRingNext(txring, CurBdPntr);
n_pbufs_freed--;
dsb();
}
Status = XEmacPs_BdRingFree(txring, n_bds, txbdset);
if (Status != XST_SUCCESS) {
LWIP_DEBUGF(NETIF_DEBUG, ("Failure while freeing in Tx Done ISR\r\n"));
}
}
return;
}
void emacps_send_handler(void *arg)
{
struct xemac_s *xemac;
xemacpsif_s *xemacpsif;
XEmacPs_BdRing *TxRingPtr;
unsigned int regval;
#ifdef OS_IS_FREERTOS
xInsideISR++;
#endif
xemac = (struct xemac_s *)(arg);
xemacpsif = (xemacpsif_s *)(xemac->state);
TxRingPtr = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_TXSR_OFFSET);
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,XEMACPS_TXSR_OFFSET, regval);
/* If Transmit done interrupt is asserted, process completed BD's */
process_sent_bds(TxRingPtr);
#ifdef OS_IS_FREERTOS
xInsideISR--;
#endif
}
XStatus emacps_sgsend(xemacpsif_s *xemacpsif, struct pbuf *p)
{
struct pbuf *q;
int n_pbufs;
XEmacPs_Bd *txbdset, *txbd, *last_txbd = NULL;
XEmacPs_Bd *temp_txbd;
XStatus Status;
XEmacPs_BdRing *txring;
unsigned int BdIndex;
unsigned int lev;
lev = mfcpsr();
mtcpsr(lev | 0x000000C0);
#ifdef PEEP
while((XEmacPs_ReadReg((xemacpsif->emacps).Config.BaseAddress,
XEMACPS_TXSR_OFFSET)) & 0x08);
#endif
txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
/* first count the number of pbufs */
for (q = p, n_pbufs = 0; q != NULL; q = q->next)
n_pbufs++;
/* obtain as many BD's */
Status = XEmacPs_BdRingAlloc(txring, n_pbufs, &txbdset);
if (Status != XST_SUCCESS) {
mtcpsr(lev);
LWIP_DEBUGF(NETIF_DEBUG, ("sgsend: Error allocating TxBD\r\n"));
return ERR_IF;
}
for(q = p, txbd = txbdset; q != NULL; q = q->next) {
BdIndex = XEMACPS_BD_TO_INDEX(txring, txbd);
if (tx_pbufs_storage[BdIndex] != 0) {
mtcpsr(lev);
LWIP_DEBUGF(NETIF_DEBUG, ("PBUFS not available\r\n"));
return ERR_IF;
}
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. */
Xil_DCacheFlushRange((unsigned int)q->payload, (unsigned)q->len);
XEmacPs_BdSetAddressTx(txbd, (u32)q->payload);
if (q->len > (XEMACPS_MAX_FRAME_SIZE - 18))
XEmacPs_BdSetLength(txbd, (XEMACPS_MAX_FRAME_SIZE - 18) & 0x3FFF);
else
XEmacPs_BdSetLength(txbd, q->len & 0x3FFF);
tx_pbufs_storage[BdIndex] = (int)q;
pbuf_ref(q);
last_txbd = txbd;
XEmacPs_BdClearLast(txbd);
dsb();
txbd = XEmacPs_BdRingNext(txring, txbd);
}
XEmacPs_BdSetLast(last_txbd);
dsb();
/* For fragmented packets, remember the 1st BD allocated for the 1st
packet fragment. The used bit for this BD should be cleared at the end
after clearing out used bits for other fragments. For packets without
just remember the allocated BD. */
temp_txbd = txbdset;
txbd = txbdset;
txbd = XEmacPs_BdRingNext(txring, txbd);
q = p->next;
for(; q != NULL; q = q->next) {
XEmacPs_BdClearTxUsed(txbd);
txbd = XEmacPs_BdRingNext(txring, txbd);
}
XEmacPs_BdClearTxUsed(temp_txbd);
dsb();
Status = XEmacPs_BdRingToHw(txring, n_pbufs, txbdset);
if (Status != XST_SUCCESS) {
mtcpsr(lev);
LWIP_DEBUGF(NETIF_DEBUG, ("sgsend: Error submitting TxBD\r\n"));
return ERR_IF;
}
dsb();
/* Start transmit */
XEmacPs_WriteReg((xemacpsif->emacps).Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET,
(XEmacPs_ReadReg((xemacpsif->emacps).Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET) | XEMACPS_NWCTRL_STARTTX_MASK));
dsb();
mtcpsr(lev);
return Status;
}
void setup_rx_bds(XEmacPs_BdRing *rxring)
{
XEmacPs_Bd *rxbd;
XStatus Status;
struct pbuf *p;
unsigned int FreeBds;
unsigned int BdIndex;
unsigned int *Temp;
FreeBds = XEmacPs_BdRingGetFreeCnt (rxring);
while (FreeBds > 0) {
FreeBds--;
Status = XEmacPs_BdRingAlloc(rxring, 1, &rxbd);
if (Status != XST_SUCCESS) {
LWIP_DEBUGF(NETIF_DEBUG, ("setup_rx_bds: Error allocating RxBD\r\n"));
return;
}
BdIndex = XEMACPS_BD_TO_INDEX(rxring, rxbd);
Temp = (unsigned int *)rxbd;
*Temp = 0;
if (BdIndex == (XLWIP_CONFIG_N_RX_DESC - 1)) {
*Temp = 0x00000002;
}
Temp++;
*Temp = 0;
p = pbuf_alloc(PBUF_RAW, XEMACPS_MAX_FRAME_SIZE, PBUF_POOL);
if (!p) {
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif
LWIP_DEBUGF(NETIF_DEBUG, ("unable to alloc pbuf in recv_handler\r\n"));
XEmacPs_BdRingUnAlloc(rxring, 1, rxbd);
dsb();
return;
}
XEmacPs_BdSetAddressRx(rxbd, (u32)p->payload);
dsb();
rx_pbufs_storage[BdIndex] = (int)p;
Status = XEmacPs_BdRingToHw(rxring, 1, rxbd);
if (Status != XST_SUCCESS) {
LWIP_DEBUGF(NETIF_DEBUG, ("Error committing RxBD to hardware: "));
if (Status == XST_DMA_SG_LIST_ERROR)
LWIP_DEBUGF(NETIF_DEBUG, ("XST_DMA_SG_LIST_ERROR: this function was called out of sequence with XEmacPs_BdRingAlloc()\r\n"));
else
LWIP_DEBUGF(NETIF_DEBUG, ("set of BDs was rejected because the first BD did not have its start-of-packet bit set, or the last BD did not have its end-of-packet bit set, or any one of the BD set has 0 as length value\r\n"));
return;
}
}
}
void emacps_recv_handler(void *arg)
{
struct pbuf *p;
XEmacPs_Bd *rxbdset, *CurBdPtr;
struct xemac_s *xemac;
xemacpsif_s *xemacpsif;
XEmacPs_BdRing *rxring;
volatile int bd_processed;
int rx_bytes, k;
unsigned int BdIndex;
unsigned int regval;
xemac = (struct xemac_s *)(arg);
xemacpsif = (xemacpsif_s *)(xemac->state);
rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps);
#ifdef OS_IS_FREERTOS
xInsideISR++;
#endif
/*
* If Reception done interrupt is asserted, call RX call back function
* to handle the processed BDs and then raise the according flag.
*/
regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET);
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET, regval);
resetrx_on_no_rxdata(xemacpsif);
while(1) {
bd_processed = XEmacPs_BdRingFromHwRx(rxring, XLWIP_CONFIG_N_RX_DESC, &rxbdset);
if (bd_processed <= 0) {
break;
}
for (k = 0, CurBdPtr=rxbdset; k < bd_processed; k++) {
BdIndex = XEMACPS_BD_TO_INDEX(rxring, CurBdPtr);
p = (struct pbuf *)rx_pbufs_storage[BdIndex];
/*
* Adjust the buffer size to the actual number of bytes received.
*/
rx_bytes = XEmacPs_BdGetLength(CurBdPtr);
pbuf_realloc(p, rx_bytes);
Xil_DCacheInvalidateRange((unsigned int)p->payload, (unsigned)XEMACPS_MAX_FRAME_SIZE);
/* store it in the receive queue,
* where it'll be processed by a different handler
*/
if (pq_enqueue(xemacpsif->recv_q, (void*)p) < 0) {
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif
pbuf_free(p);
} else {
#if !NO_SYS
sys_sem_signal(&xemac->sem_rx_data_available);
#endif
}
CurBdPtr = XEmacPs_BdRingNext( rxring, CurBdPtr);
}
/* free up the BD's */
XEmacPs_BdRingFree(rxring, bd_processed, rxbdset);
setup_rx_bds(rxring);
}
#ifdef OS_IS_FREERTOS
xInsideISR--;
#endif
return;
}
void clean_dma_txdescs(struct xemac_s *xemac)
{
XEmacPs_Bd BdTemplate;
XEmacPs_BdRing *TxRingPtr;
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
TxRingPtr = &XEmacPs_GetTxRing(&xemacpsif->emacps);
XEmacPs_BdClear(&BdTemplate);
XEmacPs_BdSetStatus(&BdTemplate, XEMACPS_TXBUF_USED_MASK);
/*
* Create the TxBD ring
*/
XEmacPs_BdRingCreate(TxRingPtr, (u32) xemacpsif->tx_bdspace,
(u32) xemacpsif->tx_bdspace, BD_ALIGNMENT,
XLWIP_CONFIG_N_TX_DESC);
XEmacPs_BdRingClone(TxRingPtr, &BdTemplate, XEMACPS_SEND);
}
XStatus init_dma(struct xemac_s *xemac)
{
XEmacPs_Bd BdTemplate;
XEmacPs_BdRing *RxRingPtr, *TxRingPtr;
XEmacPs_Bd *rxbd;
struct pbuf *p;
XStatus Status;
int i;
unsigned int BdIndex;
char *endAdd = &_end;
/*
* Align the BD starte address to 1 MB boundary.
*/
char *endAdd_aligned = (char *)(((int)endAdd + 0x100000) & (~0xFFFFF));
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
/*
* The BDs need to be allocated in uncached memory. Hence the 1 MB
* address range that starts at address 0xFF00000 is made uncached
* by setting appropriate attributes in the translation table.
*/
Xil_SetTlbAttributes((int)endAdd_aligned, 0xc02); // addr, attr
RxRingPtr = &XEmacPs_GetRxRing(&xemacpsif->emacps);
TxRingPtr = &XEmacPs_GetTxRing(&xemacpsif->emacps);
LWIP_DEBUGF(NETIF_DEBUG, ("RxRingPtr: 0x%08x\r\n", RxRingPtr));
LWIP_DEBUGF(NETIF_DEBUG, ("TxRingPtr: 0x%08x\r\n", TxRingPtr));
xemacpsif->rx_bdspace = (void *)endAdd_aligned;
/*
* We allocate 65536 bytes for Rx BDs which can accomodate a
* maximum of 8192 BDs which is much more than any application
* will ever need.
*/
xemacpsif->tx_bdspace = (void *)(endAdd_aligned + 0x10000);
LWIP_DEBUGF(NETIF_DEBUG, ("rx_bdspace: 0x%08x\r\n", xemacpsif->rx_bdspace));
LWIP_DEBUGF(NETIF_DEBUG, ("tx_bdspace: 0x%08x\r\n", xemacpsif->tx_bdspace));
if (!xemacpsif->rx_bdspace || !xemacpsif->tx_bdspace) {
xil_printf("%s@%d: Error: Unable to allocate memory for TX/RX buffer descriptors",
__FILE__, __LINE__);
return XST_FAILURE;
}
/*
* Setup RxBD space.
*
* Setup a BD template for the Rx channel. This template will be copied to
* every RxBD. We will not have to explicitly set these again.
*/
XEmacPs_BdClear(&BdTemplate);
/*
* Create the RxBD ring
*/
Status = XEmacPs_BdRingCreate(RxRingPtr, (u32) xemacpsif->rx_bdspace,
(u32) xemacpsif->rx_bdspace, BD_ALIGNMENT,
XLWIP_CONFIG_N_RX_DESC);
if (Status != XST_SUCCESS) {
LWIP_DEBUGF(NETIF_DEBUG, ("Error setting up RxBD space\r\n"));
return XST_FAILURE;
}
Status = XEmacPs_BdRingClone(RxRingPtr, &BdTemplate, XEMACPS_RECV);
if (Status != XST_SUCCESS) {
LWIP_DEBUGF(NETIF_DEBUG, ("Error initializing RxBD space\r\n"));
return XST_FAILURE;
}
XEmacPs_BdClear(&BdTemplate);
XEmacPs_BdSetStatus(&BdTemplate, XEMACPS_TXBUF_USED_MASK);
/*
* Create the TxBD ring
*/
Status = XEmacPs_BdRingCreate(TxRingPtr, (u32) xemacpsif->tx_bdspace,
(u32) xemacpsif->tx_bdspace, BD_ALIGNMENT,
XLWIP_CONFIG_N_TX_DESC);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* We reuse the bd template, as the same one will work for both rx and tx. */
Status = XEmacPs_BdRingClone(TxRingPtr, &BdTemplate, XEMACPS_SEND);
if (Status != XST_SUCCESS) {
return ERR_IF;
}
/*
* Allocate RX descriptors, 1 RxBD at a time.
*/
for (i = 0; i < XLWIP_CONFIG_N_RX_DESC; i++) {
Status = XEmacPs_BdRingAlloc(RxRingPtr, 1, &rxbd);
if (Status != XST_SUCCESS) {
LWIP_DEBUGF(NETIF_DEBUG, ("init_dma: Error allocating RxBD\r\n"));
return ERR_IF;
}
p = pbuf_alloc(PBUF_RAW, XEMACPS_MAX_FRAME_SIZE, PBUF_POOL);
if (!p) {
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif
LWIP_DEBUGF(NETIF_DEBUG, ("unable to alloc pbuf in recv_handler\r\n"));
return -1;
}
XEmacPs_BdSetAddressRx(rxbd, (u32)p->payload);
BdIndex = XEMACPS_BD_TO_INDEX(RxRingPtr, rxbd);
rx_pbufs_storage[BdIndex] = (int)p;
/* Enqueue to HW */
Status = XEmacPs_BdRingToHw(RxRingPtr, 1, rxbd);
if (Status != XST_SUCCESS) {
LWIP_DEBUGF(NETIF_DEBUG, ("Error: committing RxBD to HW\r\n"));
return XST_FAILURE;
}
}
/*
* Connect the device driver handler that will be called when an
* interrupt for the device occurs, the handler defined above performs
* the specific interrupt processing for the device.
*/
XScuGic_RegisterHandler(INTC_BASE_ADDR, xtopologyp->scugic_emac_intr,
(Xil_ExceptionHandler)XEmacPs_IntrHandler,
(void *)&xemacpsif->emacps);
/*
* Enable the interrupt for emacps.
*/
XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, (u32) xtopologyp->scugic_emac_intr);
EmacIntrNum = (u32) xtopologyp->scugic_emac_intr;
return 0;
}
/*
* resetrx_on_no_rxdata():
*
* It is called at regular intervals through the API xemacpsif_resetrx_on_no_rxdata
* called by the user.
* The EmacPs has a HW bug (SI# 692601) on the Rx path for heavy Rx traffic.
* Under heavy Rx traffic because of the HW bug there are times when the Rx path
* becomes unresponsive. The workaround for it is to check for the Rx path for
* traffic (by reading the stats registers regularly). If the stats register
* does not increment for sometime (proving no Rx traffic), the function resets
* the Rx data path.
*
*/
void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
{
unsigned long regctrl;
unsigned long tempcntr;
tempcntr = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET);
if ((!tempcntr) && (!(xemacpsif->last_rx_frms_cntr))) {
regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET, regctrl);
regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET);
regctrl |= (XEMACPS_NWCTRL_RXEN_MASK);
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET, regctrl);
}
xemacpsif->last_rx_frms_cntr = tempcntr;
}
void FreeTxRxPBufs(void)
{
int Index;
struct pbuf *p;
for (Index = 0; Index < XLWIP_CONFIG_N_TX_DESC; Index++) {
if (tx_pbufs_storage[Index] != 0) {
p = (struct pbuf *)tx_pbufs_storage[Index];
pbuf_free(p);
tx_pbufs_storage[Index] = 0;
}
}
for (Index = 0; Index < XLWIP_CONFIG_N_RX_DESC; Index++) {
p = (struct pbuf *)rx_pbufs_storage[Index];
pbuf_free(p);
}
}
void FreeOnlyTxPBufs(void)
{
int Index;
struct pbuf *p;
for (Index = 0; Index < XLWIP_CONFIG_N_TX_DESC; Index++) {
if (tx_pbufs_storage[Index] != 0) {
p = (struct pbuf *)tx_pbufs_storage[Index];
pbuf_free(p);
tx_pbufs_storage[Index] = 0;
}
}
}
void EmacDisableIntr(void)
{
XScuGic_DisableIntr(INTC_DIST_BASE_ADDR, EmacIntrNum);
}
void EmacEnableIntr(void)
{
XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, EmacIntrNum);
}

@ -0,0 +1,198 @@
/*
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include "netif/xemacpsif.h"
#include "lwipopts.h"
/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
*** to run it on a PEEP board
***/
unsigned int link_speed = 100;
XEmacPs_Config *xemacps_lookup_config(unsigned mac_base)
{
extern XEmacPs_Config XEmacPs_ConfigTable[];
XEmacPs_Config *CfgPtr = NULL;
int i;
for (i = 0; i < XPAR_XEMACPS_NUM_INSTANCES; i++) {
if (XEmacPs_ConfigTable[i].BaseAddress == mac_base) {
CfgPtr = &XEmacPs_ConfigTable[i];
break;
}
}
return (CfgPtr);
}
void init_emacps(xemacpsif_s *xemacps, struct netif *netif)
{
unsigned mac_address = (unsigned)(netif->state);
XEmacPs *xemacpsp;
XEmacPs_Config *mac_config;
int Status = XST_SUCCESS;
/* obtain config of this emac */
mac_config = (XEmacPs_Config *)xemacps_lookup_config(mac_address);
xemacpsp = &xemacps->emacps;
/* set mac address */
Status = XEmacPs_SetMacAddress(xemacpsp, (void*)(netif->hwaddr), 1);
if (Status != XST_SUCCESS) {
xil_printf("In %s:Emac Mac Address set failed...\r\n",__func__);
}
XEmacPs_SetMdioDivisor(xemacpsp, MDC_DIV_224);
link_speed = Phy_Setup(xemacpsp);
XEmacPs_SetOperatingSpeed(xemacpsp, link_speed);
/* Setting the operating speed of the MAC needs a delay. */
{
volatile int wait;
for (wait=0; wait < 20000; wait++);
}
}
void init_emacps_on_error (xemacpsif_s *xemacps, struct netif *netif)
{
unsigned mac_address = (unsigned)(netif->state);
XEmacPs *xemacpsp;
XEmacPs_Config *mac_config;
int Status = XST_SUCCESS;
/* obtain config of this emac */
mac_config = (XEmacPs_Config *)xemacps_lookup_config(mac_address);
xemacpsp = &xemacps->emacps;
/* set mac address */
Status = XEmacPs_SetMacAddress(xemacpsp, (void*)(netif->hwaddr), 1);
if (Status != XST_SUCCESS) {
xil_printf("In %s:Emac Mac Address set failed...\r\n",__func__);
}
XEmacPs_SetOperatingSpeed(xemacpsp, link_speed);
/* Setting the operating speed of the MAC needs a delay. */
{
volatile int wait;
for (wait=0; wait < 20000; wait++);
}
}
void setup_isr (struct xemac_s *xemac)
{
xemacpsif_s *xemacpsif;
xemacpsif = (xemacpsif_s *)(xemac->state);
/*
* Setup callbacks
*/
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
(void *) emacps_send_handler,
(void *) xemac);
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
(void *) emacps_recv_handler,
(void *) xemac);
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
(void *) emacps_error_handler,
(void *) xemac);
}
void start_emacps (xemacpsif_s *xemacps)
{
/* start the temac */
XEmacPs_Start(&xemacps->emacps);
}
void restart_emacps_transmitter (xemacpsif_s *xemacps) {
u32 Reg;
Reg = XEmacPs_ReadReg(xemacps->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
Reg = Reg & (~XEMACPS_NWCTRL_TXEN_MASK);
XEmacPs_WriteReg(xemacps->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET, Reg);
Reg = XEmacPs_ReadReg(xemacps->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
Reg = Reg | (XEMACPS_NWCTRL_TXEN_MASK);
XEmacPs_WriteReg(xemacps->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET, Reg);
}
void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord)
{
struct xemac_s *xemac;
xemacpsif_s *xemacpsif;
struct xtopology_t *xtopologyp;
XEmacPs *xemacps;
XEmacPs_BdRing *rxring;
XEmacPs_BdRing *txring;
xemac = (struct xemac_s *)(arg);
xemacpsif = (xemacpsif_s *)(xemac->state);
rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps);
txring = &XEmacPs_GetRxRing(&xemacpsif->emacps);
xtopologyp = &xtopology[xemac->topology_index];
xemacps = &xemacpsif->emacps;
if (ErrorWord != 0) {
switch (Direction) {
case XEMACPS_RECV:
if (ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK) {
LWIP_DEBUGF(NETIF_DEBUG, ("Receive DMA error\r\n"));
HandleEmacPsError(xemac);
}
if (ErrorWord & XEMACPS_RXSR_RXOVR_MASK) {
LWIP_DEBUGF(NETIF_DEBUG, ("Receive over run\r\n"));
emacps_recv_handler(arg);
setup_rx_bds(rxring);
}
if (ErrorWord & XEMACPS_RXSR_BUFFNA_MASK) {
LWIP_DEBUGF(NETIF_DEBUG, ("Receive buffer not available\r\n"));
emacps_recv_handler(arg);
setup_rx_bds(rxring);
}
break;
case XEMACPS_SEND:
if (ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK) {
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit DMA error\r\n"));
HandleEmacPsError(xemac);
}
if (ErrorWord & XEMACPS_TXSR_URUN_MASK) {
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit under run\r\n"));
HandleTxErrors(xemac);
}
if (ErrorWord & XEMACPS_TXSR_BUFEXH_MASK) {
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit buffer exhausted\r\n"));
HandleTxErrors(xemac);
}
if (ErrorWord & XEMACPS_TXSR_RXOVR_MASK) {
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit retry excessed limits\r\n"));
HandleTxErrors(xemac);
}
if (ErrorWord & XEMACPS_TXSR_FRAMERX_MASK) {
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit collision\r\n"));
process_sent_bds(txring);
}
break;
}
}
}

@ -0,0 +1,37 @@
/*
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef __XEMACPSIF_HW_H_
#define __XEMACPSIF_HW_H_
#include "netif/xemacpsif.h"
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
XEmacPs_Config * lookup_config(unsigned mac_base);
void init_emacps(xemacpsif_s *xemacpsif, struct netif *netif);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,559 @@
/*
* Copyright (c) 2007-2008, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Advanced Micro Devices, Inc. nor the names
* of its contributors may be used to endorse or promote products
* derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "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 COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*/
/*
* Some portions copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include "netif/xemacpsif.h"
#include "lwipopts.h"
#include "xparameters_ps.h"
#include "xparameters.h"
/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
*** to run it on a PEEP board
***/
/* Advertisement control register. */
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
#define ADVERTISE_100_AND_10 (ADVERTISE_10FULL | ADVERTISE_100FULL | \
ADVERTISE_10HALF | ADVERTISE_100HALF)
#define ADVERTISE_100 (ADVERTISE_100FULL | ADVERTISE_100HALF)
#define ADVERTISE_10 (ADVERTISE_10FULL | ADVERTISE_10HALF)
#define ADVERTISE_1000 0x0300
#define IEEE_CONTROL_REG_OFFSET 0
#define IEEE_STATUS_REG_OFFSET 1
#define IEEE_AUTONEGO_ADVERTISE_REG 4
#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
#define IEEE_1000_ADVERTISE_REG_OFFSET 9
#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET 10
#define IEEE_COPPER_SPECIFIC_CONTROL_REG 16
#define IEEE_SPECIFIC_STATUS_REG 17
#define IEEE_COPPER_SPECIFIC_STATUS_REG_2 19
#define IEEE_CONTROL_REG_MAC 21
#define IEEE_PAGE_ADDRESS_REGISTER 22
#define IEEE_CTRL_1GBPS_LINKSPEED_MASK 0x2040
#define IEEE_CTRL_LINKSPEED_MASK 0x0040
#define IEEE_CTRL_LINKSPEED_1000M 0x0040
#define IEEE_CTRL_LINKSPEED_100M 0x2000
#define IEEE_CTRL_LINKSPEED_10M 0x0000
#define IEEE_CTRL_RESET_MASK 0x8000
#define IEEE_CTRL_AUTONEGOTIATE_ENABLE 0x1000
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#define IEEE_CTRL_RESET 0x9140
#define IEEE_CTRL_ISOLATE_DISABLE 0xFBFF
#endif
#define IEEE_STAT_AUTONEGOTIATE_CAPABLE 0x0008
#define IEEE_STAT_AUTONEGOTIATE_COMPLETE 0x0020
#define IEEE_STAT_AUTONEGOTIATE_RESTART 0x0200
#define IEEE_STAT_1GBPS_EXTENSIONS 0x0100
#define IEEE_AN1_ABILITY_MASK 0x1FE0
#define IEEE_AN3_ABILITY_MASK_1GBPS 0x0C00
#define IEEE_AN1_ABILITY_MASK_100MBPS 0x0380
#define IEEE_AN1_ABILITY_MASK_10MBPS 0x0060
#define IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK 0x0030
#define IEEE_ASYMMETRIC_PAUSE_MASK 0x0800
#define IEEE_PAUSE_MASK 0x0400
#define IEEE_AUTONEG_ERROR_MASK 0x8000
#define PHY_DETECT_REG 1
#define PHY_DETECT_MASK 0x1808
#define XEMACPS_GMII2RGMII_SPEED1000_FD 0x140
#define XEMACPS_GMII2RGMII_SPEED100_FD 0x2100
#define XEMACPS_GMII2RGMII_SPEED10_FD 0x100
#define XEMACPS_GMII2RGMII_REG_NUM 0x10
/* Frequency setting */
#define SLCR_LOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x4)
#define SLCR_UNLOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x8)
#define SLCR_GEM0_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x140)
#define SLCR_GEM1_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x144)
#ifdef PEEP
#define SLCR_GEM_10M_CLK_CTRL_VALUE 0x00103031
#define SLCR_GEM_100M_CLK_CTRL_VALUE 0x00103001
#define SLCR_GEM_1G_CLK_CTRL_VALUE 0x00103011
#endif
#define SLCR_LOCK_KEY_VALUE 0x767B
#define SLCR_UNLOCK_KEY_VALUE 0xDF0D
#define SLCR_ADDR_GEM_RST_CTRL (XPS_SYS_CTRL_BASEADDR + 0x214)
#define EMACPS_SLCR_DIV_MASK 0xFC0FC0FF
#define EMAC0_BASE_ADDRESS 0xE000B000
#define EMAC1_BASE_ADDRESS 0xE000C000
static int detect_phy(XEmacPs *xemacpsp)
{
u16 phy_reg;
u32 phy_addr;
for (phy_addr = 31; phy_addr > 0; phy_addr--) {
XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,
&phy_reg);
if ((phy_reg != 0xFFFF) &&
((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
/* Found a valid PHY address */
LWIP_DEBUGF(NETIF_DEBUG, ("XEmacPs detect_phy: PHY detected at address %d.\r\n",
phy_addr));
LWIP_DEBUGF(NETIF_DEBUG, ("XEmacPs detect_phy: PHY detected.\r\n"));
return phy_addr;
}
}
LWIP_DEBUGF(NETIF_DEBUG, ("XEmacPs detect_phy: No PHY detected. Assuming a PHY at address 0\r\n"));
/* default to zero */
return 0;
}
#ifdef PEEP
unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
{
u16 control;
u16 status;
u16 partner_capabilities;
u16 partner_capabilities_1000;
u16 phylinkspeed;
u32 phy_addr = detect_phy(xemacpsp);
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
ADVERTISE_1000);
/* Advertise PHY speed of 100 and 10 Mbps */
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
ADVERTISE_100_AND_10);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
&control);
control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |
IEEE_STAT_AUTONEGOTIATE_RESTART);
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
/* Read PHY control and status registers is successful. */
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) && (status &
IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
&status);
}
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_1_REG_OFFSET,
&partner_capabilities);
if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_3_REG_OFFSET,
&partner_capabilities_1000);
if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS)
return 1000;
}
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS)
return 100;
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
return 10;
xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
__FUNCTION__);
return 10;
} else {
/* Update TEMAC speed accordingly */
if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
/* Get commanded link speed */
phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;
switch (phylinkspeed) {
case (IEEE_CTRL_LINKSPEED_1000M):
return 1000;
case (IEEE_CTRL_LINKSPEED_100M):
return 100;
case (IEEE_CTRL_LINKSPEED_10M):
return 10;
default:
xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
__FUNCTION__, phylinkspeed);
return 10;
}
} else {
return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;
}
}
}
#else /* Zynq */
unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
{
u16 temp;
u16 control;
u16 status;
u16 partner_capabilities;
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
u32 phy_addr = XPAR_PCSPMA_SGMII_PHYADDR;
#else
u32 phy_addr = detect_phy(xemacpsp);
#endif
xil_printf("Start PHY autonegotiation \r\n");
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
control |= IEEE_ASYMMETRIC_PAUSE_MASK;
control |= IEEE_PAUSE_MASK;
control |= ADVERTISE_100;
control |= ADVERTISE_10;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
&control);
control |= ADVERTISE_1000;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
control);
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
&control);
control |= (7 << 12); /* max number of gigabit attempts */
control |= (1 << 11); /* enable downshift */
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
control);
#endif
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
control &= IEEE_CTRL_ISOLATE_DISABLE;
#endif
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
control |= IEEE_CTRL_RESET_MASK;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
while (1) {
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
if (control & IEEE_CTRL_RESET_MASK)
continue;
else
break;
}
#endif
xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
sleep(1);
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
&temp);
if (temp & IEEE_AUTONEG_ERROR_MASK) {
xil_printf("Auto negotiation error \r\n");
}
#endif
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
&status);
}
xil_printf("autonegotiation complete \r\n");
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_SPECIFIC_STATUS_REG, &partner_capabilities);
#endif
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
while(!(temp & 0x8000)) {
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
}
if((temp & 0x0C00) == 0x0800) {
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
return 1000;
}
else if((temp & 0x0C00) == 0x0400) {
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
return 100;
}
else if((temp & 0x0C00) == 0x0000) {
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
return 10;
} else {
xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\r\n");
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
return 10;
}
#else
if ( ((partner_capabilities >> 14) & 3) == 2)/* 1000Mbps */
return 1000;
else if ( ((partner_capabilities >> 14) & 3) == 1)/* 100Mbps */
return 100;
else /* 10Mbps */
return 10;
#endif
}
#endif
unsigned configure_IEEE_phy_speed(XEmacPs *xemacpsp, unsigned speed)
{
u16 control;
u32 phy_addr = detect_phy(xemacpsp);
XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
control |= IEEE_ASYMMETRIC_PAUSE_MASK;
control |= IEEE_PAUSE_MASK;
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
control &= ~IEEE_CTRL_LINKSPEED_1000M;
control &= ~IEEE_CTRL_LINKSPEED_100M;
control &= ~IEEE_CTRL_LINKSPEED_10M;
if (speed == 1000) {
control |= IEEE_CTRL_LINKSPEED_1000M;
}
else if (speed == 100) {
control |= IEEE_CTRL_LINKSPEED_100M;
/* Dont advertise PHY speed of 1000 Mbps */
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0);
/* Dont advertise PHY speed of 10 Mbps */
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
ADVERTISE_100);
}
else if (speed == 10) {
control |= IEEE_CTRL_LINKSPEED_10M;
/* Dont advertise PHY speed of 1000 Mbps */
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
0);
/* Dont advertise PHY speed of 100 Mbps */
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
ADVERTISE_10);
}
XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
control | IEEE_CTRL_RESET_MASK);
{
volatile int wait;
for (wait=0; wait < 100000; wait++);
}
return 0;
}
static void SetUpSLCRDivisors(int mac_baseaddr, int speed)
{
volatile u32 slcrBaseAddress;
#ifndef PEEP
u32 SlcrDiv0;
u32 SlcrDiv1;
u32 SlcrTxClkCntrl;
#endif
*(volatile unsigned int *)(SLCR_UNLOCK_ADDR) = SLCR_UNLOCK_KEY_VALUE;
if (mac_baseaddr == EMAC0_BASE_ADDRESS) {
slcrBaseAddress = SLCR_GEM0_CLK_CTRL_ADDR;
} else {
slcrBaseAddress = SLCR_GEM1_CLK_CTRL_ADDR;
}
#ifdef PEEP
if (speed == 1000) {
*(volatile unsigned int *)(slcrBaseAddress) =
SLCR_GEM_1G_CLK_CTRL_VALUE;
} else if (speed == 100) {
*(volatile unsigned int *)(slcrBaseAddress) =
SLCR_GEM_100M_CLK_CTRL_VALUE;
} else {
*(volatile unsigned int *)(slcrBaseAddress) =
SLCR_GEM_10M_CLK_CTRL_VALUE;
}
#else
if (speed == 1000) {
if (mac_baseaddr == EMAC0_BASE_ADDRESS) {
#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1;
#endif
} else {
#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV1;
#endif
}
} else if (speed == 100) {
if (mac_baseaddr == EMAC0_BASE_ADDRESS) {
#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1;
#endif
} else {
#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV1;
#endif
}
} else {
if (mac_baseaddr == EMAC0_BASE_ADDRESS) {
#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV1;
#endif
} else {
#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0
SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0;
SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV1;
#endif
}
}
SlcrTxClkCntrl = *(volatile unsigned int *)(slcrBaseAddress);
SlcrTxClkCntrl &= EMACPS_SLCR_DIV_MASK;
SlcrTxClkCntrl |= (SlcrDiv1 << 20);
SlcrTxClkCntrl |= (SlcrDiv0 << 8);
*(volatile unsigned int *)(slcrBaseAddress) = SlcrTxClkCntrl;
#endif
*(volatile unsigned int *)(SLCR_LOCK_ADDR) = SLCR_LOCK_KEY_VALUE;
return;
}
unsigned Phy_Setup (XEmacPs *xemacpsp)
{
unsigned link_speed;
unsigned short regval;
unsigned long conv_present = 0;
unsigned long convspeeddupsetting = 0;
unsigned long convphyaddr = 0;
#ifdef XPAR_GMII2RGMIICON_0N_ETH0_ADDR
convphyaddr = XPAR_GMII2RGMIICON_0N_ETH0_ADDR;
conv_present = 1;
#else
#ifdef XPAR_GMII2RGMIICON_0N_ETH1_ADDR
convphyaddr = XPAR_GMII2RGMIICON_0N_ETH1_ADDR;
conv_present = 1;
#endif
#endif
#ifdef CONFIG_LINKSPEED_AUTODETECT
link_speed = get_IEEE_phy_speed(xemacpsp);
if (link_speed == 1000) {
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
} else if (link_speed == 100) {
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
} else {
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
}
#elif defined(CONFIG_LINKSPEED1000)
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
link_speed = 1000;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
sleep(1);
#elif defined(CONFIG_LINKSPEED100)
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
link_speed = 100;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
sleep(1);
#elif defined(CONFIG_LINKSPEED10)
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
link_speed = 10;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
sleep(1);
#endif
if (conv_present) {
XEmacPs_PhyWrite(xemacpsp, convphyaddr,
XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
}
xil_printf("link speed: %d\r\n", link_speed);
return link_speed;
}

@ -0,0 +1,80 @@
/*
* Copyright (c) 2007-13 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <stdlib.h>
#include "netif/xpqueue.h"
#define NUM_QUEUES 2
pq_queue_t pq_queue[NUM_QUEUES];
pq_queue_t *
pq_create_queue()
{
static int i;
pq_queue_t *q = NULL;
if (i >= NUM_QUEUES) {
xil_printf("ERR: Max Queues allocated\n\r");
return q;
}
q = &pq_queue[i++];
if (!q)
return q;
q->head = q->tail = q->len = 0;
return q;
}
int
pq_enqueue(pq_queue_t *q, void *p)
{
if (q->len == PQ_QUEUE_SIZE)
return -1;
q->data[q->head] = p;
q->head = (q->head + 1)%PQ_QUEUE_SIZE;
q->len++;
return 0;
}
void*
pq_dequeue(pq_queue_t *q)
{
int ptail;
if (q->len == 0)
return NULL;
ptail = q->tail;
q->tail = (q->tail + 1)%PQ_QUEUE_SIZE;
q->len--;
return q->data[ptail];
}
int
pq_qlength(pq_queue_t *q)
{
return q->len;
}

@ -0,0 +1,15 @@
#include "netif/xtopology.h"
#include "xparameters.h"
struct xtopology_t xtopology[] = {
{
0xE000B000,
xemac_type_emacps,
0x0,
0x0,
0xF8F00100,
0x36,
},
};
int xtopology_n_emacs = 1;

@ -0,0 +1,541 @@
/*
* 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>
*
*/
//*****************************************************************************
//
// Include OS functionality.
//
//*****************************************************************************
/* ------------------------ System architecture includes ----------------------------- */
#include "arch/sys_arch.h"
/* ------------------------ lwIP includes --------------------------------- */
#include "lwip/opt.h"
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/stats.h"
/*---------------------------------------------------------------------------*
* Routine: sys_mbox_new
*---------------------------------------------------------------------------*
* Description:
* Creates a new mailbox
* Inputs:
* int size -- Size of elements in the mailbox
* Outputs:
* sys_mbox_t -- Handle to new mailbox
*---------------------------------------------------------------------------*/
err_t sys_mbox_new( sys_mbox_t *pxMailBox, int iSize )
{
err_t xReturn = ERR_MEM;
*pxMailBox = xQueueCreate( iSize, sizeof( void * ) );
if( *pxMailBox != NULL )
{
xReturn = ERR_OK;
SYS_STATS_INC_USED( mbox );
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_mbox_free
*---------------------------------------------------------------------------*
* Description:
* 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.
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* Outputs:
* sys_mbox_t -- Handle to new mailbox
*---------------------------------------------------------------------------*/
void sys_mbox_free( sys_mbox_t *pxMailBox )
{
unsigned long ulMessagesWaiting;
ulMessagesWaiting = uxQueueMessagesWaiting( *pxMailBox );
configASSERT( ( ulMessagesWaiting == 0 ) );
#if SYS_STATS
{
if( ulMessagesWaiting != 0UL )
{
SYS_STATS_INC( mbox.err );
}
SYS_STATS_DEC( mbox.used );
}
#endif /* SYS_STATS */
vQueueDelete( *pxMailBox );
}
/*---------------------------------------------------------------------------*
* Routine: sys_mbox_post
*---------------------------------------------------------------------------*
* Description:
* Post the "msg" to the mailbox.
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* void *data -- Pointer to data to post
*---------------------------------------------------------------------------*/
void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost )
{
while( xQueueSendToBack( *pxMailBox, &pxMessageToPost, portMAX_DELAY ) != pdTRUE );
}
/*---------------------------------------------------------------------------*
* Routine: sys_mbox_trypost
*---------------------------------------------------------------------------*
* Description:
* Try to post the "msg" to the mailbox. Returns immediately with
* error if cannot.
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* void *msg -- Pointer to data to post
* Outputs:
* err_t -- ERR_OK if message posted, else ERR_MEM
* if not.
*---------------------------------------------------------------------------*/
err_t sys_mbox_trypost( sys_mbox_t *pxMailBox, void *pxMessageToPost )
{
err_t xReturn;
if( xQueueSend( *pxMailBox, &pxMessageToPost, 0UL ) == pdPASS )
{
xReturn = ERR_OK;
}
else
{
/* The queue was already full. */
xReturn = ERR_MEM;
SYS_STATS_INC( mbox.err );
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_mbox_fetch
*---------------------------------------------------------------------------*
* Description:
* 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.
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* void **msg -- Pointer to pointer to msg received
* u32_t timeout -- Number of milliseconds until timeout
* Outputs:
* u32_t -- SYS_ARCH_TIMEOUT if timeout, else number
* of milliseconds until received.
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_fetch( sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut )
{
void *pvDummy;
TickType_t xStartTime, xEndTime, xElapsed;
unsigned long ulReturn;
xStartTime = xTaskGetTickCount();
if( NULL == ppvBuffer )
{
ppvBuffer = &pvDummy;
}
if( ulTimeOut != 0UL )
{
if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), ulTimeOut/ portTICK_PERIOD_MS ) )
{
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS;
ulReturn = xElapsed;
}
else
{
/* Timed out. */
*ppvBuffer = NULL;
ulReturn = SYS_ARCH_TIMEOUT;
}
}
else
{
while( pdTRUE != xQueueReceive( *pxMailBox, &( *ppvBuffer ), portMAX_DELAY ) );
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS;
if( xElapsed == 0UL )
{
xElapsed = 1UL;
}
ulReturn = xElapsed;
}
return ulReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_mbox_tryfetch
*---------------------------------------------------------------------------*
* Description:
* 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.
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* void **msg -- Pointer to pointer to msg received
* Outputs:
* u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise,
* return ERR_OK.
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_tryfetch( sys_mbox_t *pxMailBox, void **ppvBuffer )
{
void *pvDummy;
unsigned long ulReturn;
if( ppvBuffer== NULL )
{
ppvBuffer = &pvDummy;
}
if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), 0UL ) )
{
ulReturn = ERR_OK;
}
else
{
ulReturn = SYS_MBOX_EMPTY;
}
return ulReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_new
*---------------------------------------------------------------------------*
* Description:
* Creates and returns a new semaphore. The "ucCount" argument specifies
* the initial state of the semaphore.
* NOTE: Currently this routine only creates counts of 1 or 0
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* u8_t ucCount -- Initial ucCount of semaphore (1 or 0)
* Outputs:
* sys_sem_t -- Created semaphore or 0 if could not create.
*---------------------------------------------------------------------------*/
err_t sys_sem_new( sys_sem_t *pxSemaphore, u8_t ucCount )
{
err_t xReturn = ERR_MEM;
vSemaphoreCreateBinary( ( *pxSemaphore ) );
if( *pxSemaphore != NULL )
{
if( ucCount == 0U )
{
xSemaphoreTake( *pxSemaphore, 1UL );
}
xReturn = ERR_OK;
SYS_STATS_INC_USED( sem );
}
else
{
SYS_STATS_INC( sem.err );
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_sem_wait
*---------------------------------------------------------------------------*
* Description:
* Blocks the thread while waiting for the semaphore to be
* signaled. If the "timeout" argument is non-zero, the thread should
* only be blocked for the specified time (measured in
* milliseconds).
*
* If the timeout argument is non-zero, the return value is the number of
* milliseconds spent waiting for the semaphore to be signaled. If the
* semaphore wasn't signaled within the specified time, the return value is
* SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
* (i.e., it was already signaled), the function may return zero.
*
* Notice that lwIP implements a function with a similar name,
* sys_sem_wait(), that uses the sys_arch_sem_wait() function.
* Inputs:
* sys_sem_t sem -- Semaphore to wait on
* u32_t timeout -- Number of milliseconds until timeout
* Outputs:
* u32_t -- Time elapsed or SYS_ARCH_TIMEOUT.
*---------------------------------------------------------------------------*/
u32_t sys_arch_sem_wait( sys_sem_t *pxSemaphore, u32_t ulTimeout )
{
TickType_t xStartTime, xEndTime, xElapsed;
unsigned long ulReturn;
xStartTime = xTaskGetTickCount();
if( ulTimeout != 0UL )
{
if( xSemaphoreTake( *pxSemaphore, ulTimeout / portTICK_PERIOD_MS ) == pdTRUE )
{
xEndTime = xTaskGetTickCount();
xElapsed = (xEndTime - xStartTime) * portTICK_PERIOD_MS;
ulReturn = xElapsed;
}
else
{
ulReturn = SYS_ARCH_TIMEOUT;
}
}
else
{
while( xSemaphoreTake( *pxSemaphore, portMAX_DELAY ) != pdTRUE );
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_PERIOD_MS;
if( xElapsed == 0UL )
{
xElapsed = 1UL;
}
ulReturn = xElapsed;
}
return ulReturn;
}
/** Create a new mutex
* @param mutex pointer to the mutex to create
* @return a new mutex */
err_t sys_mutex_new( sys_mutex_t *pxMutex )
{
err_t xReturn = ERR_MEM;
*pxMutex = xSemaphoreCreateMutex();
if( *pxMutex != NULL )
{
xReturn = ERR_OK;
SYS_STATS_INC_USED( mutex );
}
else
{
SYS_STATS_INC( mutex.err );
}
return xReturn;
}
/** Lock a mutex
* @param mutex the mutex to lock */
void sys_mutex_lock( sys_mutex_t *pxMutex )
{
while( xSemaphoreTake( *pxMutex, portMAX_DELAY ) != pdPASS );
}
/** Unlock a mutex
* @param mutex the mutex to unlock */
void sys_mutex_unlock(sys_mutex_t *pxMutex )
{
xSemaphoreGive( *pxMutex );
}
/** Delete a semaphore
* @param mutex the mutex to delete */
void sys_mutex_free( sys_mutex_t *pxMutex )
{
SYS_STATS_DEC( mutex.used );
vQueueDelete( *pxMutex );
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_signal
*---------------------------------------------------------------------------*
* Description:
* Signals (releases) a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to signal
*---------------------------------------------------------------------------*/
void sys_sem_signal( sys_sem_t *pxSemaphore )
{
xSemaphoreGive( *pxSemaphore );
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_free
*---------------------------------------------------------------------------*
* Description:
* Deallocates a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to free
*---------------------------------------------------------------------------*/
void sys_sem_free( sys_sem_t *pxSemaphore )
{
SYS_STATS_DEC(sem.used);
vQueueDelete( *pxSemaphore );
}
/*---------------------------------------------------------------------------*
* Routine: sys_init
*---------------------------------------------------------------------------*
* Description:
* Initialize sys arch
*---------------------------------------------------------------------------*/
void sys_init(void)
{
}
u32_t sys_now(void)
{
return xTaskGetTickCount();
}
/*---------------------------------------------------------------------------*
* Routine: sys_thread_new
*---------------------------------------------------------------------------*
* Description:
* 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.
* Inputs:
* char *name -- Name of thread
* void (* thread)(void *arg) -- Pointer to function to run.
* void *arg -- Argument passed into function
* int stacksize -- Required stack amount in bytes
* int prio -- Thread priority
* Outputs:
* sys_thread_t -- Pointer to per-thread timeouts.
*---------------------------------------------------------------------------*/
sys_thread_t sys_thread_new( const char *pcName, void( *pxThread )( void *pvParameters ), void *pvArg, int iStackSize, int iPriority )
{
TaskHandle_t xCreatedTask;
portBASE_TYPE xResult;
sys_thread_t xReturn;
xResult = xTaskCreate( pxThread, pcName, iStackSize, pvArg, iPriority, &xCreatedTask );
if( xResult == pdPASS )
{
xReturn = xCreatedTask;
}
else
{
xReturn = NULL;
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_protect
*---------------------------------------------------------------------------*
* Description:
* 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.
* Outputs:
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
sys_prot_t sys_arch_protect( void )
{
taskENTER_CRITICAL();
return ( sys_prot_t ) 1;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_unprotect
*---------------------------------------------------------------------------*
* Description:
* 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.
* Inputs:
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
void sys_arch_unprotect( sys_prot_t xValue )
{
(void) xValue;
taskEXIT_CRITICAL();
}
/*
* Prints an assertion messages and aborts execution.
*/
void sys_assert( const char *pcMessage )
{
(void) pcMessage;
for (;;)
{
}
}
/*-------------------------------------------------------------------------*
* End of File: sys_arch.c
*-------------------------------------------------------------------------*/

@ -145,6 +145,9 @@
#include "IntQueue.h" #include "IntQueue.h"
#include "EventGroupsDemo.h" #include "EventGroupsDemo.h"
/* lwIP includes. */
#include "lwip/tcpip.h"
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
@ -225,6 +228,11 @@ extern void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriori
*/ */
static void prvPseudoRandomiser( void *pvParameters ); static void prvPseudoRandomiser( void *pvParameters );
/*
* Defined in lwIPApps.c.
*/
extern void lwIPAppsInit( void *pvArguments );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
@ -233,10 +241,16 @@ then the register check tasks has not discovered any errors. If a variable
stops incrementing, then an error has been found. */ stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/* String for display in the web server. It is set to an error message if the
check task detects an error. */
char *pcStatusMessage = "All tasks running without error";
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
/* Init lwIP and start lwIP tasks. */
tcpip_init( lwIPAppsInit, NULL );
/* Start all the other standard demo/test tasks. They have not particular /* Start all the other standard demo/test tasks. They have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ kernel port. */
@ -409,11 +423,18 @@ unsigned long ulErrorFound = pdFALSE;
gone wrong (it might just be that the loop back connector required gone wrong (it might just be that the loop back connector required
by the comtest tasks has not been fitted). */ by the comtest tasks has not been fitted). */
xDelayPeriod = mainERROR_CHECK_TASK_PERIOD; xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;
pcStatusMessage = "Error found in at least one task.";
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
char *pcMainGetTaskStatusMessage( void )
{
return pcStatusMessage;
}
/*-----------------------------------------------------------*/
static void prvRegTestTaskEntry1( void *pvParameters ) static void prvRegTestTaskEntry1( void *pvParameters )
{ {
/* Although the regtest task is written in assembler, its entry point is /* Although the regtest task is written in assembler, its entry point is

@ -0,0 +1,305 @@
/*
* 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 __LWIPOPTS_H__
#define __LWIPOPTS_H__
#include <limits.h>
/* Functions used to obtain and release exclusive access to the Tx buffer. The
Get function will block if the Tx buffer is not available - use with care! */
signed char *pcLwipBlockingGetTxBuffer( void );
void vLwipAppsReleaseTxBuffer( void );
#define CONFIG_LINKSPEED_AUTODETECT 1
/* SSI options. */
#define TCPIP_THREAD_NAME "tcpip"
#define LWIP_HTTPD_MAX_TAG_NAME_LEN 20
#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 1024
#define TCPIP_THREAD_PRIO configLWIP_TASK_PRIORITY
#define TCPIP_THREAD_STACKSIZE configMINIMAL_STACK_SIZE * 3
#define DEFAULT_TCP_RECVMBOX_SIZE 5
#define DEFAULT_ACCEPTMBOX_SIZE 5
#define TCPIP_MBOX_SIZE 10
#define NO_SYS 0
#define LWIP_SOCKET (NO_SYS==0)
#define LWIP_NETCONN 1
#define LWIP_SNMP 0
#define LWIP_IGMP 0
#define LWIP_ICMP 1
/* DNS is not going to be used as this is a simple local example. */
#define LWIP_DNS 0
#define LWIP_HAVE_LOOPIF 0
#define TCP_LISTEN_BACKLOG 0
#define LWIP_SO_RCVTIMEO 1
#define LWIP_SO_RCVBUF 1
#ifdef LWIP_DEBUG
#define LWIP_DBG_MIN_LEVEL 0
#define PPP_DEBUG LWIP_DBG_ON
#define MEM_DEBUG LWIP_DBG_ON
#define MEMP_DEBUG LWIP_DBG_ON
#define PBUF_DEBUG LWIP_DBG_ON
#define API_LIB_DEBUG LWIP_DBG_ON
#define API_MSG_DEBUG LWIP_DBG_ON
#define TCPIP_DEBUG LWIP_DBG_ON
#define NETIF_DEBUG LWIP_DBG_ON
#define SOCKETS_DEBUG LWIP_DBG_ON
#define DNS_DEBUG LWIP_DBG_ON
#define AUTOIP_DEBUG LWIP_DBG_ON
#define DHCP_DEBUG LWIP_DBG_ON
#define IP_DEBUG LWIP_DBG_ON
#define IP_REASS_DEBUG LWIP_DBG_ON
#define ICMP_DEBUG LWIP_DBG_ON
#define IGMP_DEBUG LWIP_DBG_ON
#define UDP_DEBUG LWIP_DBG_ON
#define TCP_DEBUG LWIP_DBG_ON
#define TCP_INPUT_DEBUG LWIP_DBG_ON
#define TCP_OUTPUT_DEBUG LWIP_DBG_ON
#define TCP_RTO_DEBUG LWIP_DBG_ON
#define TCP_CWND_DEBUG LWIP_DBG_ON
#define TCP_WND_DEBUG LWIP_DBG_ON
#define TCP_FR_DEBUG LWIP_DBG_ON
#define TCP_QLEN_DEBUG LWIP_DBG_ON
#define TCP_RST_DEBUG LWIP_DBG_ON
#endif
#define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT)
/* ---------- Memory options ---------- */
/* 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
byte alignment -> define MEM_ALIGNMENT to 2. */
/* MSVC port: intel processors don't need 4-byte alignment,
but are faster that way! */
#define MEM_ALIGNMENT 4
/* 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. */
#define MEM_SIZE 0x20000
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
#define MEMP_NUM_PBUF 16
/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One
per active RAW "connection". */
#define LWIP_RAW 0
#define MEMP_NUM_RAW_PCB 0
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 4
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#define MEMP_NUM_TCP_PCB 32
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 8
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#define MEMP_NUM_TCP_SEG 256
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 8
/* The following four are used only with the sequential API and can be
set to 0 if the application only will use the raw API. */
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
#define MEMP_NUM_NETBUF 0
/* MEMP_NUM_NETCONN: the number of struct netconns. */
#define MEMP_NUM_NETCONN 10
/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used
for sequential API communication and incoming packets. Used in
src/api/tcpip.c. */
#define MEMP_NUM_TCPIP_MSG_API 4
#define MEMP_NUM_TCPIP_MSG_INPKT 4
#define MEMP_NUM_ARP_QUEUE 5
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#define PBUF_POOL_SIZE 256
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE 1700
/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
link level header. */
#define PBUF_LINK_HLEN 16
/** SYS_LIGHTWEIGHT_PROT
* define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
* for certain critical regions during buffer allocation, deallocation and memory
* allocation and deallocation.
*/
#define SYS_LIGHTWEIGHT_PROT (NO_SYS==0)
/* ---------- TCP options ---------- */
#define LWIP_TCP 1
#define TCP_TTL 255
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ 1
/* TCP Maximum segment size. */
#define TCP_MSS 1460
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF 8129
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
#define TCP_SND_QUEUELEN (16 * TCP_SND_BUF/TCP_MSS)
/* TCP writable space (bytes). This must be less than or equal
to TCP_SND_BUF. It is the amount of space which must be
available in the tcp snd_buf for select to return writable */
#define TCP_SNDLOWAT (TCP_SND_BUF/2)
/* TCP receive window. */
#define TCP_WND ( 2048 )
/* Maximum number of retransmissions of data segments. */
#define TCP_MAXRTX 12
/* Maximum number of retransmissions of SYN segments. */
#define TCP_SYNMAXRTX 4
/* ---------- ARP options ---------- */
#define LWIP_ARP 1
#define ARP_TABLE_SIZE 10
#define ARP_QUEUEING 1
/* ---------- IP options ---------- */
/* Define IP_FORWARD to 1 if you wish to have 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 0
/* IP reassembly and segmentation.These are orthogonal even
* if they both deal with IP fragments */
#define IP_REASSEMBLY 0
#define IP_REASS_MAX_PBUFS 10
#define MEMP_NUM_REASSDATA 10
#define IP_FRAG 0
/* ---------- ICMP options ---------- */
#define ICMP_TTL 255
/* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
interfaces. */
#define LWIP_DHCP 0
/* 1 if you want to do an ARP check on the offered address
(recommended). */
#define DHCP_DOES_ARP_CHECK (LWIP_DHCP)
/* ---------- AUTOIP options ------- */
#define LWIP_AUTOIP 0
#define LWIP_DHCP_AUTOIP_COOP (LWIP_DHCP && LWIP_AUTOIP)
/* ---------- UDP options ---------- */
#define LWIP_UDP 1
#define LWIP_UDPLITE 1
#define UDP_TTL 255
/* ---------- Statistics options ---------- */
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 0
#if LWIP_STATS
#define LINK_STATS 1
#define IP_STATS 1
#define ICMP_STATS 0
#define IGMP_STATS 0
#define IPFRAG_STATS 0
#define UDP_STATS 1
#define TCP_STATS 1
#define MEM_STATS 1
#define MEMP_STATS 1
#define PBUF_STATS 1
#define SYS_STATS 1
#endif /* LWIP_STATS */
/* ---------- PPP options ---------- */
#define PPP_SUPPORT 0 /* Set > 0 for PPP */
#if PPP_SUPPORT
#define NUM_PPP 1 /* Max PPP sessions. */
/* Select modules to enable. Ideally these would be set in the makefile but
* we're limited by the command line length so you need to modify the settings
* in this file.
*/
#define PPPOE_SUPPORT 1
#define PPPOS_SUPPORT 1
#define PAP_SUPPORT 1 /* Set > 0 for PAP. */
#define CHAP_SUPPORT 1 /* Set > 0 for CHAP. */
#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP (NOT FUNCTIONAL!) */
#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
#define CCP_SUPPORT 0 /* Set > 0 for CCP (NOT FUNCTIONAL!) */
#define VJ_SUPPORT 1 /* Set > 0 for VJ header compression. */
#define MD5_SUPPORT 1 /* Set > 0 for MD5 (see also CHAP) */
#endif /* PPP_SUPPORT */
#endif /* __LWIPOPTS_H__ */

@ -282,12 +282,4 @@ int main(void)
#endif #endif
/* To keep linker happy. */
int write( int i, char* c, int n)
{
(void)i;
(void)n;
(void)c;
return 0;
}

Loading…
Cancel
Save