Example program for the lwIP TCP/IP stack (library lwip_1_4_0_rc2) and the QP state machine framework (library qp). This program demonstrates use of lwIP in hard real-time applications, in which the TCP/IP stack is used to monitor and configure the embedded device as well as to provide remote user interface (e.g., by means of a web browser). In particular, the lwIP stack, which is not reentrant, is strictly encapsulated inside a dedicated QP state machine object (active object in QP), so interrupt locking around calls to lwIP is unnecessary. Also, the Ethernet interrupt service routine (ISR) runs very fast without performing any lengthy copy operations. All this means that hard-real-time processing can be done at the task level, especially when you use the preemptive QK kernel built into QP for executing your application. No external RTOS component is needed to achieve fully deterministic real-time response of active object tasks prioritized above the lwiP task. The lwIP-QP integration uses exclusively the event-driven lwIP API. The heavyweight Berkeley-like socket API requiring a blocking RTOS and is not used, which results in much better performance of the lwIP stack and less memory consumption. NOTE: This example compiles cleanly, but does not run just yet because the low-level Ethernet driver in the lwIP library needs to be completed. See comments in the lwip_1_4_0_rc2 library for more information.

Dependencies:   mbed

Committer:
QL
Date:
Sun Mar 27 16:50:21 2011 +0000
Revision:
0:84f3d3d7e5d9
0.9

Who changed what in which revision?

UserRevisionLine numberNew contents of line
QL 0:84f3d3d7e5d9 1 /*
QL 0:84f3d3d7e5d9 2 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
QL 0:84f3d3d7e5d9 3 * All rights reserved.
QL 0:84f3d3d7e5d9 4 *
QL 0:84f3d3d7e5d9 5 * Redistribution and use in source and binary forms, with or without
QL 0:84f3d3d7e5d9 6 * modification, are permitted provided that the following conditions are met:
QL 0:84f3d3d7e5d9 7 *
QL 0:84f3d3d7e5d9 8 * 1. Redistributions of source code must retain the above copyright notice,
QL 0:84f3d3d7e5d9 9 * this list of conditions and the following disclaimer.
QL 0:84f3d3d7e5d9 10 * 2. Redistributions in binary form must reproduce the above copyright
QL 0:84f3d3d7e5d9 11 * notice, this list of conditions and the following disclaimer in the
QL 0:84f3d3d7e5d9 12 * documentation and/or other materials provided with the distribution.
QL 0:84f3d3d7e5d9 13 * 3. The name of the author may not be used to endorse or promote products
QL 0:84f3d3d7e5d9 14 * derived from this software without specific prior written permission.
QL 0:84f3d3d7e5d9 15 *
QL 0:84f3d3d7e5d9 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
QL 0:84f3d3d7e5d9 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
QL 0:84f3d3d7e5d9 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
QL 0:84f3d3d7e5d9 19 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
QL 0:84f3d3d7e5d9 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
QL 0:84f3d3d7e5d9 21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
QL 0:84f3d3d7e5d9 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
QL 0:84f3d3d7e5d9 23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
QL 0:84f3d3d7e5d9 24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
QL 0:84f3d3d7e5d9 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
QL 0:84f3d3d7e5d9 26 *
QL 0:84f3d3d7e5d9 27 * This file is part of the lwIP TCP/IP stack.
QL 0:84f3d3d7e5d9 28 *
QL 0:84f3d3d7e5d9 29 * Author: Adam Dunkels <adam@sics.se>
QL 0:84f3d3d7e5d9 30 */
QL 0:84f3d3d7e5d9 31
QL 0:84f3d3d7e5d9 32 #include <string.h>
QL 0:84f3d3d7e5d9 33 #include "fs.h" /* file system abstraction */
QL 0:84f3d3d7e5d9 34
QL 0:84f3d3d7e5d9 35 struct fsdata_file {
QL 0:84f3d3d7e5d9 36 struct fsdata_file const *next;
QL 0:84f3d3d7e5d9 37 unsigned char const *name;
QL 0:84f3d3d7e5d9 38 unsigned char const *data;
QL 0:84f3d3d7e5d9 39 int len;
QL 0:84f3d3d7e5d9 40 };
QL 0:84f3d3d7e5d9 41
QL 0:84f3d3d7e5d9 42 #include "fsdata.h" /* file-system data generated by qfsdata utility */
QL 0:84f3d3d7e5d9 43
QL 0:84f3d3d7e5d9 44 /*--------------------------------------------------------------------------*/
QL 0:84f3d3d7e5d9 45 /* Define the number of open files that we can support. */
QL 0:84f3d3d7e5d9 46 #ifndef LWIP_MAX_OPEN_FILES
QL 0:84f3d3d7e5d9 47 #define LWIP_MAX_OPEN_FILES 10
QL 0:84f3d3d7e5d9 48 #endif
QL 0:84f3d3d7e5d9 49
QL 0:84f3d3d7e5d9 50 /* Define the file system memory allocation structure. */
QL 0:84f3d3d7e5d9 51 struct fs_table {
QL 0:84f3d3d7e5d9 52 struct fs_file file;
QL 0:84f3d3d7e5d9 53 int inuse;
QL 0:84f3d3d7e5d9 54 };
QL 0:84f3d3d7e5d9 55
QL 0:84f3d3d7e5d9 56 /* Allocate file system memory */
QL 0:84f3d3d7e5d9 57 struct fs_table fs_memory[LWIP_MAX_OPEN_FILES];
QL 0:84f3d3d7e5d9 58
QL 0:84f3d3d7e5d9 59 /*--------------------------------------------------------------------------*/
QL 0:84f3d3d7e5d9 60 static struct fs_file *fs_malloc(void) {
QL 0:84f3d3d7e5d9 61 int i;
QL 0:84f3d3d7e5d9 62 for (i = 0; i < LWIP_MAX_OPEN_FILES; i++) {
QL 0:84f3d3d7e5d9 63 if (fs_memory[i].inuse == 0) {
QL 0:84f3d3d7e5d9 64 fs_memory[i].inuse = 1;
QL 0:84f3d3d7e5d9 65 return (&fs_memory[i].file);
QL 0:84f3d3d7e5d9 66 }
QL 0:84f3d3d7e5d9 67 }
QL 0:84f3d3d7e5d9 68 return (NULL);
QL 0:84f3d3d7e5d9 69 }
QL 0:84f3d3d7e5d9 70
QL 0:84f3d3d7e5d9 71 /*--------------------------------------------------------------------------*/
QL 0:84f3d3d7e5d9 72 static void fs_free(struct fs_file *file) {
QL 0:84f3d3d7e5d9 73 int i;
QL 0:84f3d3d7e5d9 74 for (i = 0; i < LWIP_MAX_OPEN_FILES; i++) {
QL 0:84f3d3d7e5d9 75 if (&fs_memory[i].file == file) {
QL 0:84f3d3d7e5d9 76 fs_memory[i].inuse = 0;
QL 0:84f3d3d7e5d9 77 break;
QL 0:84f3d3d7e5d9 78 }
QL 0:84f3d3d7e5d9 79 }
QL 0:84f3d3d7e5d9 80 return;
QL 0:84f3d3d7e5d9 81 }
QL 0:84f3d3d7e5d9 82
QL 0:84f3d3d7e5d9 83 /*--------------------------------------------------------------------------*/
QL 0:84f3d3d7e5d9 84 struct fs_file *fs_open(char const *name) {
QL 0:84f3d3d7e5d9 85 struct fs_file *file;
QL 0:84f3d3d7e5d9 86 const struct fsdata_file *f;
QL 0:84f3d3d7e5d9 87
QL 0:84f3d3d7e5d9 88 file = fs_malloc();
QL 0:84f3d3d7e5d9 89 if (file == NULL) {
QL 0:84f3d3d7e5d9 90 return NULL;
QL 0:84f3d3d7e5d9 91 }
QL 0:84f3d3d7e5d9 92
QL 0:84f3d3d7e5d9 93 for (f = FS_ROOT; f != NULL; f = f->next) {
QL 0:84f3d3d7e5d9 94 if (!strcmp(name, (char *)f->name)) {
QL 0:84f3d3d7e5d9 95 file->data = (char *)f->data;
QL 0:84f3d3d7e5d9 96 file->len = f->len;
QL 0:84f3d3d7e5d9 97 file->index = f->len;
QL 0:84f3d3d7e5d9 98 file->pextension = NULL;
QL 0:84f3d3d7e5d9 99 return file;
QL 0:84f3d3d7e5d9 100 }
QL 0:84f3d3d7e5d9 101 }
QL 0:84f3d3d7e5d9 102 fs_free(file);
QL 0:84f3d3d7e5d9 103 return NULL;
QL 0:84f3d3d7e5d9 104 }
QL 0:84f3d3d7e5d9 105
QL 0:84f3d3d7e5d9 106 /*--------------------------------------------------------------------------*/
QL 0:84f3d3d7e5d9 107 void fs_close(struct fs_file *file) {
QL 0:84f3d3d7e5d9 108 fs_free(file);
QL 0:84f3d3d7e5d9 109 }
QL 0:84f3d3d7e5d9 110 /*--------------------------------------------------------------------------*/
QL 0:84f3d3d7e5d9 111 int fs_read(struct fs_file *file, char *buffer, int count) {
QL 0:84f3d3d7e5d9 112 int read;
QL 0:84f3d3d7e5d9 113
QL 0:84f3d3d7e5d9 114 if (file->index == file->len) {
QL 0:84f3d3d7e5d9 115 return -1;
QL 0:84f3d3d7e5d9 116 }
QL 0:84f3d3d7e5d9 117
QL 0:84f3d3d7e5d9 118 read = file->len - file->index;
QL 0:84f3d3d7e5d9 119 if (read > count) {
QL 0:84f3d3d7e5d9 120 read = count;
QL 0:84f3d3d7e5d9 121 }
QL 0:84f3d3d7e5d9 122
QL 0:84f3d3d7e5d9 123 memcpy(buffer, (file->data + file->index), read);
QL 0:84f3d3d7e5d9 124 file->index += read;
QL 0:84f3d3d7e5d9 125
QL 0:84f3d3d7e5d9 126 return (read);
QL 0:84f3d3d7e5d9 127 }