Add new LPC1768 RedSuite demo.

This commit is contained in:
Richard Barry 2009-07-12 14:23:25 +00:00
parent 09f28cb98c
commit b686daaa40
59 changed files with 15105 additions and 0 deletions

View File

@ -0,0 +1,33 @@
//*****************************************************************************
// +--+
// | ++----+
// +-++ |
// | |
// +-+--+ |
// | +--+--+
// +----+ Copyright (c) 2009 Code Red Technologies Ltd.
//
// font.h - header file for font data contained in system_fixed_be_8_15.c
//
// Software License Agreement
//
// The software is owned by Code Red Technologies and/or its suppliers, and is
// protected under applicable copyright laws. All rights are reserved. Any
// use in violation of the foregoing restrictions may subject the user to criminal
// sanctions under applicable laws, as well as to civil liability for the breach
// of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
// CODE RED TECHNOLOGIES LTD.
#ifndef FONT_H_
#define FONT_H_
extern const unsigned char font_data_table[];
extern const unsigned char font_index_table[];
#endif /*FONT_H_*/

View File

@ -0,0 +1,308 @@
//*****************************************************************************
// +--+
// | ++----+
// +-++ |
// | |
// +-+--+ |
// | +--+--+
// +----+ Copyright (c) 2009 Code Red Technologies Ltd.
//
// lcd.c contains various routines to plot to the LCD display on the RDB1768
// development board.
//
// Software License Agreement
//
// The software is owned by Code Red Technologies and/or its suppliers, and is
// protected under applicable copyright laws. All rights are reserved. Any
// use in violation of the foregoing restrictions may subject the user to criminal
// sanctions under applicable laws, as well as to civil liability for the breach
// of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
// CODE RED TECHNOLOGIES LTD.
#include "lcd_commands.h"
#include "lcd.h"
#include "lcd_driver.h"
#include "font.h"
#include <stdlib.h> // to provice abs() function
// Routine to draw a filled rectangle to the LCD.
// Two corners of rectangle are at (xmin,ymin) and (xmax,ymax).
// The Rectangle is filled with the RGB565 color specified
void LCD_FilledRect(int xmin,int xmax,int ymin,int ymax,int color)
{
int i;
// Specify to LCD controller coordinates we are writing to...
LCDdriver_WriteCom(DD_CASET); // Set the column address
LCDdriver_WriteData(xmin); // min address
LCDdriver_WriteData(xmax); // max address
LCDdriver_WriteCom(DD_RASET); // Set the row address
LCDdriver_WriteData(ymin + 1); // min address
LCDdriver_WriteData(ymax + 1); // max address
LCDdriver_WriteCom(DD_RAMWR); // RAM Write command
// Plot the color data to the LCD buffer
for(i = ((xmax - xmin + 1) * (ymax - ymin + 1)); i > 0; i--)
{
LCDdriver_WriteData(color >> 8); // top 8 bits of RGB565 color
LCDdriver_WriteData(color); // bottom 8 bits of RGB565 color
}
}
// Routine to draw an unfilled rectangle to the LCD.
// Two corners of rectangle are at (xmin,ymin) and (xmax,ymax).
// The Rectangle is drawn in the RGB565 color specified
void LCD_Rect(int xmin,int xmax,int ymin,int ymax,int color)
{
// Draw 4 lines of rectange as 4 filled rectanges, each of 1 pixel wide
LCD_FilledRect(xmin,xmin,ymin,ymax,color);
LCD_FilledRect(xmax,xmax,ymin,ymax,color);
LCD_FilledRect(xmin,xmax,ymin,ymin,color);
LCD_FilledRect(xmin,xmax,ymax,ymax,color);
}
// Plot a point on the screen in the 6:5:6 color format
void LCD_PlotPoint(int x,int y,int color)
{
LCDdriver_WriteCom(DD_CASET); // Set the column address
LCDdriver_WriteData(x); // min address
LCDdriver_WriteData(x); // max address
LCDdriver_WriteCom(DD_RASET); // Set the row address
LCDdriver_WriteData(y + 1); // min address
LCDdriver_WriteData(y + 1); // max address
LCDdriver_WriteCom(DD_RAMWR); // RAM Write command
LCDdriver_WriteData(color >> 8); // top 8 bits of RGB565 color
LCDdriver_WriteData(color); // top 8 bits of RGB565 color
}
// Routine to draw a filled circle to the LCD.
// The centre of the circle is at (x0,y0) and the circle has the
// specifed radius. The circle is filled with the RGB565 color
// The circle is drawn using the "Midpoint circle algorithm",
// also known as "Bresenham's circle algorithm". In order to fill
// the circle, the algorithm has been modifed to draw a line between
// each two points, rather than plotting the two points individually.
void LCD_FilledCircle (int x0, int y0, int radius, int color)
{
int f = 1 - radius;
int ddF_x = 1;
int ddF_y = -2 * radius;
int x = 0;
int y = radius;
LCD_FilledRect(x0, x0 ,y0 - radius,y0 + radius, color);
LCD_FilledRect(x0 - radius, x0 + radius ,y0,y0, color);
while(x < y)
{
if(f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
LCD_FilledRect(x0-x, x0+x ,y0 +y, y0 + y, color);
LCD_FilledRect(x0-x, x0+x ,y0 - y, y0 - y, color);
LCD_FilledRect(x0-y, x0+y ,y0 + x, y0 + x, color);
LCD_FilledRect(x0-y, x0+y ,y0 - x, y0 - x, color);
}
}
// Routine to draw an unfilled circle to the LCD.
// The centre of the circle is at (x0,y0) and the circle has the
// specifed radius. The circle is drawn in the RGB565 color
// The circle is drawn using the "Midpoint circle algorithm",
// also known as "Bresenham's circle algorithm".
void LCD_Circle (int x0, int y0, int radius, int color)
{
int f = 1 - radius;
int ddF_x = 1;
int ddF_y = -2 * radius;
int x = 0;
int y = radius;
LCD_PlotPoint(x0, y0 + radius, color);
LCD_PlotPoint(x0, y0 - radius, color);
LCD_PlotPoint(x0 + radius, y0, color);
LCD_PlotPoint(x0 - radius, y0, color);
while(x < y)
{
if(f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
LCD_PlotPoint(x0 + x, y0 + y, color);
LCD_PlotPoint(x0 - x, y0 + y, color);
LCD_PlotPoint(x0 + x, y0 - y, color);
LCD_PlotPoint(x0 - x, y0 - y, color);
LCD_PlotPoint(x0 + y, y0 + x, color);
LCD_PlotPoint(x0 - y, y0 + x, color);
LCD_PlotPoint(x0 + y, y0 - x, color);
LCD_PlotPoint(x0 - y, y0 - x, color);
}
}
// Routine to draw a line in the RGB565 color to the LCD.
// The line is drawn from (xmin,ymin) to (xmax,ymax).
// The algorithm used to draw the line is "Bresenham's line
// algorithm".
#define SWAP(a, b) a ^= b; b ^= a; a ^= b;
void LCD_Line (int xmin,int xmax,int ymin,int ymax,int color)
{
int Dx = xmax - xmin;
int Dy = ymax - ymin;
int steep = (abs(Dy) >= abs(Dx));
if (steep) {
SWAP(xmin, ymin);
SWAP(xmax, ymax);
// recompute Dx, Dy after swap
Dx = xmax - xmin;
Dy = ymax - ymin;
}
int xstep = 1;
if (Dx < 0) {
xstep = -1;
Dx = -Dx;
}
int ystep = 1;
if (Dy < 0) {
ystep = -1;
Dy = -Dy;
}
int TwoDy = 2*Dy;
int TwoDyTwoDx = TwoDy - 2*Dx; // 2*Dy - 2*Dx
int E = TwoDy - Dx; //2*Dy - Dx
int y = ymin;
int xDraw, yDraw;
int x;
for (x = xmin; x != xmax; x += xstep) {
if (steep) {
xDraw = y;
yDraw = x;
} else {
xDraw = x;
yDraw = y;
}
// plot
LCD_PlotPoint(xDraw, yDraw, color);
// next
if (E > 0) {
E += TwoDyTwoDx; //E += 2*Dy - 2*Dx;
y = y + ystep;
} else {
E += TwoDy; //E += 2*Dy;
}
}
}
// Routine to clear the LCD.
// Implemented by drawing a black rectangle across the whole screen
void LCD_ClearScreen(void)
{
LCD_FilledRect (0,LCD_MAX_X,0 , LCD_MAX_Y, COLOR_BLACK);
}
// Routine to write a single character to screen in the font pointed
// to by pBitMap. This routine is intended to be used via the
// LCD_PrintChar() and LCD_PrintString() routines, rather than called
// directly from user code.
void LCD_WriteBitMap8x15(int x, int y, int height, int width, unsigned char *pBitMap, int color)
{
int xmax = x + width - 1; // start at zero
int ymax = y + height - 1; // start at zero
int iRow, iCol;
unsigned char ucRowData;
LCDdriver_WriteCom(DD_CASET); // Column address set
LCDdriver_WriteData(x); // Start column
LCDdriver_WriteData(xmax); // End column
LCDdriver_WriteCom(DD_RASET); // Row address set
LCDdriver_WriteData(y); // Start row
LCDdriver_WriteData(ymax); // End row
LCDdriver_WriteCom(DD_RAMWR); // Memory write
for(iRow=0;iRow<height;iRow++)
{
ucRowData = *pBitMap++;
for(iCol=0;iCol<width;iCol++)
{
// Look at each input bitmap bit
// and write as a black-pixel or
// a color-pixel.
if(ucRowData & 0x80) // 'color pixel'
{
LCDdriver_WriteData(color >> 8);
LCDdriver_WriteData(color);
}
else // black pixel
{
LCDdriver_WriteData(0x00);
LCDdriver_WriteData(0x00);
}
ucRowData = ucRowData<<1;
}
}
}
// Prints the character 'c' to the LCD in the appropriate color.
void LCD_PrintChar(int x, int y, unsigned char c, int color )
{
const unsigned char index = font_index_table[c];
const unsigned int offset = index * 15;
unsigned char *pData = (unsigned char *)&font_data_table[offset];
LCD_WriteBitMap8x15(x, y, 15, 8, pData, color);
}
// Prints the string to the LCD in the appropriate color.
void LCD_PrintString(int x, int y, char *pcString, int iStrLen, int color)
{
unsigned char index;
unsigned int offset;
unsigned char *pData;
unsigned char c;
int i;
for(i=0;i<iStrLen;i++)
{
c = pcString[i];
if(c==0)
break;
index = font_index_table[c];
offset = index * 15;
pData = (unsigned char *)&font_data_table[offset];
LCD_WriteBitMap8x15(x, y, 15, 8, pData, color);
x += 8;
}
}

View File

@ -0,0 +1,92 @@
//*****************************************************************************
// +--+
// | ++----+
// +-++ |
// | |
// +-+--+ |
// | +--+--+
// +----+ Copyright (c) 2009 Code Red Technologies Ltd.
//
// lcd.h - Routines containing primitives for writing to the LCD
//
//
// Software License Agreement
//
// The software is owned by Code Red Technologies and/or its suppliers, and is
// protected under applicable copyright laws. All rights are reserved. Any
// use in violation of the foregoing restrictions may subject the user to criminal
// sanctions under applicable laws, as well as to civil liability for the breach
// of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
// CODE RED TECHNOLOGIES LTD.
#ifndef LCD_H_
#define LCD_H_
// Define size of LCD screen.
#define LCD_MAX_X 128
#define LCD_MAX_Y 128
// Translates a 24-bit RGB color to RGB565
#define TRANSLATE24BIT_TO_RGB565(c) ((((c) & 0x00ff0000) >> 19) | \
((((c) & 0x0000ff00) >> 5) & 0x000007e0) | \
((((c) & 0x000000ff) << 8) & 0x0000f800))
// Define a basic set of 24bit colors, based on the standard "websafe" set
#define COLOR24_AQUA 0x00FFFF
#define COLOR24_GREY 0x808080
#define COLOR24_NAVY 0x000080
#define COLOR24_SILVER 0xC0C0C0
#define COLOR24_BLACK 0x000000
#define COLOR24_GREEN 0x008000
#define COLOR24_OLIVE 0x808000
#define COLOR24_TEAL 0x008080
#define COLOR24_BLUE 0x0000FF
#define COLOR24_LIME 0x00FF00
#define COLOR24_PURPLE 0x800080
#define COLOR24_WHITE 0xFFFFFF
#define COLOR24_FUCHSIA 0xFF00FF
#define COLOR24_MAROON 0x800000
#define COLOR24_RED 0xFF0000
#define COLOR24_YELLOW 0xFFFF00
// Create a set of RGB565 colors that can be used directly within code
#define COLOR_AQUA TRANSLATE24BIT_TO_RGB565(COLOR24_AQUA)
#define COLOR_GREY TRANSLATE24BIT_TO_RGB565(COLOR24_GREY)
#define COLOR_NAVY TRANSLATE24BIT_TO_RGB565(COLOR24_NAVY)
#define COLOR_SILVER TRANSLATE24BIT_TO_RGB565(COLOR24_SILVER)
#define COLOR_BLACK TRANSLATE24BIT_TO_RGB565(COLOR24_BLACK)
#define COLOR_GREEN TRANSLATE24BIT_TO_RGB565(COLOR24_GREEN)
#define COLOR_OLIVE TRANSLATE24BIT_TO_RGB565(COLOR24_OLIVE)
#define COLOR_TEAL TRANSLATE24BIT_TO_RGB565(COLOR24_TEAL)
#define COLOR_BLUE TRANSLATE24BIT_TO_RGB565(COLOR24_BLUE)
#define COLOR_LIME TRANSLATE24BIT_TO_RGB565(COLOR24_LIME)
#define COLOR_PURPLE TRANSLATE24BIT_TO_RGB565(COLOR24_PURPLE)
#define COLOR_WHITE TRANSLATE24BIT_TO_RGB565(COLOR24_WHITE)
#define COLOR_FUCHSIA TRANSLATE24BIT_TO_RGB565(COLOR24_FUCHSIA)
#define COLOR_MAROON TRANSLATE24BIT_TO_RGB565(COLOR24_MAROON)
#define COLOR_RED TRANSLATE24BIT_TO_RGB565(COLOR24_RED)
#define COLOR_YELLOW TRANSLATE24BIT_TO_RGB565(COLOR24_YELLOW)
void LCD_Line (int xmin,int xmax,int ymin,int ymax,int color);
void LCD_FilledRect(int xmin,int xmax,int ymin,int ymax,int color);
void LCD_Rect(int xmin,int xmax,int ymin,int ymax,int color);
void LCD_WriteBitMap8x15(int x, int y, int height, int width, unsigned char *pBitMap, int color);
void LCD_PlotPoint(int x,int y,int color);
void LCD_Circle (int x0, int y0, int radius, int color);
void LCD_FilledCircle (int x0, int y0, int radius, int color);
void LCD_ClearScreen(void);
void LCD_WriteBitMap8x15(int x, int y, int height, int width, unsigned char *pBitMap, int color);
void LCD_PrintChar(int x, int y, unsigned char c, int color );
void LCD_PrintString(int x, int y, char *pcString, int iStrLen, int color);
#endif /*LCD_H_*/

View File

@ -0,0 +1,53 @@
//*****************************************************************************
// +--+
// | ++----+
// +-++ |
// | |
// +-+--+ |
// | +--+--+
// +----+ Copyright (c) 2009 Code Red Technologies Ltd.
//
// lcd_commands.h contains defines mapping onto the commands accepted by the
// Sitronix ST7637 LCD Controller/driver used on the RDB1768 development board.//
//
// Software License Agreement
//
// The software is owned by Code Red Technologies and/or its suppliers, and is
// protected under applicable copyright laws. All rights are reserved. Any
// use in violation of the foregoing restrictions may subject the user to criminal
// sanctions under applicable laws, as well as to civil liability for the breach
// of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
// CODE RED TECHNOLOGIES LTD.
#ifndef LCD_COMMANDS_H_
#define LCD_COMMANDS_H_
#define DD_NOP 0x00
#define DD_SWRESET 0x01 //SW reset the display
#define DD_SLPIN 0x10 //Sleep in and booster off
#define DD_SLPOUT 0x11 //Sleep out and booster on
#define DD_NORON 0x13 //Partial mode off (Normal mode on)
#define DD_DISPOFF 0x28 //Display Off
#define DD_DISPON 0x29 //Display On
#define DD_CASET 0x2a //Column address set
#define DD_RASET 0x2b //Row address set
#define DD_RAMWR 0x2c //Memory write
#define DD_MADCTR 0x36 //Memory Data Access Control
#define DD_COLORMOD 0x3a //Set the color mode for the display
#define DD_ColScanDir 0xb7 //Set the column scanning direction
#define DD_VopSet 0xc0 //LCD supply voltage set
#define DD_BiasSel 0xc3 //Bias selection
#define DD_BstMbpXSel 0xc4 //Booster setting
#define DD_AUTOLOADSET 0xd7 //Control auto load of ROM data
#define DD_EPCTIN 0xe0 //OTP control RD/WR
#define DD_EPREAD 0xe3 //OTP read
#define DD_EPCTOUT 0xe1 //OTP control cancel
#endif /*LCD_COMMANDS_H_*/

View File

@ -0,0 +1,190 @@
//*****************************************************************************
// +--+
// | ++----+
// +-++ |
// | |
// +-+--+ |
// | +--+--+
// +----+ Copyright (c) 2009 Code Red Technologies Ltd.
//
// lcd_driver.c contains the lowest level access routines for the Sitronix
// ST7637 LCD Controller/driver used on the RDB1768 development board.
//
//
// Software License Agreement
//
// The software is owned by Code Red Technologies and/or its suppliers, and is
// protected under applicable copyright laws. All rights are reserved. Any
// use in violation of the foregoing restrictions may subject the user to criminal
// sanctions under applicable laws, as well as to civil liability for the breach
// of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
// CODE RED TECHNOLOGIES LTD.
#include "NXP/LPC17xx/LPC17xx.h"
#include "lcd_driver.h"
#include "lcd_commands.h"
// Bits within GPIO port 2 used for LCD driver
#define LCD_CSB_PIN (1<<13)
#define LCD_A0_PIN (1<<8)
#define LCD_WR_PIN (1<<11)
#define LCD_RD_PIN (1<<12)
#define LCD_DATA_PIN 0xff
// Bit within GPIO port 3 used for LCD driver
#define LCD_RESB_PIN (1<<25)
// Bits to configure as outputs for driving LCD
#define LCD_PORT2_DIRECTIONS (LCD_CSB_PIN | LCD_A0_PIN | LCD_WR_PIN | LCD_RD_PIN | LCD_DATA_PIN)
#define LCD_PORT3_DIRECTIONS (LCD_RESB_PIN)
// Define names for GPIO port 2 and 3 registers to better indicate in code
// the operation being carried out on the LCD driver hardware.
#define LCD_DATA_CLR FIO2CLR
#define LCD_DATA_SET FIO2SET
#define LCD_CSB_CLR FIO2CLR
#define LCD_CSB_SET FIO2SET
#define LCD_RESB_CLR FIO3CLR
#define LCD_RESB_SET FIO3SET
#define LCD_A0_CLR FIO2CLR
#define LCD_A0_SET FIO2SET
#define LCD_WR_CLR FIO2CLR
#define LCD_WR_SET FIO2SET
#define LCD_RD_CLR FIO2CLR
#define LCD_RD_SET FIO2SET
// Routine to write data to LCD driver. Normally called in combination
// with LCDdriver_WriteCom() routine
void LCDdriver_WriteData(unsigned char LCD_Data)
{
LCD_DATA_CLR = LCD_DATA_PIN;
LCD_DATA_SET = LCD_Data;
LCD_CSB_CLR = LCD_CSB_PIN;
LCD_WR_CLR = LCD_WR_PIN;
LCD_WR_SET = LCD_WR_PIN;
LCD_CSB_SET = LCD_CSB_PIN;
}
// Routine to configure set LCD driver to accept particular command.
// A call to this routine will normally be followed by a call
// to LCDdriver_WriteData() to transfer appropriate parameters to driver.
void LCDdriver_WriteCom(unsigned char LCD_Command)
{
LCD_DATA_CLR = LCD_DATA_PIN;
LCD_DATA_SET = LCD_Command;
LCD_A0_CLR = LCD_A0_PIN;
LCD_CSB_CLR = LCD_CSB_PIN;
LCD_WR_CLR = LCD_WR_PIN;
LCD_WR_SET = LCD_WR_PIN;
LCD_CSB_SET = LCD_CSB_PIN;
LCD_A0_SET = LCD_A0_PIN;
}
// Function to add short delays in writing things to the LCD.
void ms_delay(int n)
{
volatile int d;
for (d=0; d<n*3000; d++){}
}
// Initialize GPIO connection to the LCD driver
void LCDdriver_ConfigGPIOtoLCD(void)
{
// set direction to outputs
FIO2DIR |= LCD_PORT2_DIRECTIONS;
FIO3DIR |= LCD_PORT3_DIRECTIONS;
// Set GPIO outputs connected to LCD to default values
LCD_CSB_SET = LCD_CSB_PIN;
LCD_A0_SET = LCD_A0_PIN;
LCD_WR_SET = LCD_WR_PIN;
LCD_RD_SET = LCD_RD_PIN;
LCD_RESB_SET = LCD_RESB_PIN;
LCD_DATA_CLR = 0xff; // data bus to zero
}
// Initialisation routine to set up LCD
void LCDdriver_initialisation(void)
{
int i; // temp loop variable
LCDdriver_ConfigGPIOtoLCD(); // Initialize the GPIO for the display
LCDdriver_WriteCom(DD_SWRESET); // SW reset
ms_delay(120); // Small delay
LCDdriver_WriteCom(DD_AUTOLOADSET); // disable auto loading of mask rom data
LCDdriver_WriteData(0xBF);
LCDdriver_WriteCom(DD_EPCTIN); // OTP control mode=read
LCDdriver_WriteData(0x00);
ms_delay(10); // Small delay
LCDdriver_WriteCom(DD_EPREAD); // Start the OTP read.
ms_delay(20); // Small delay
LCDdriver_WriteCom(DD_EPCTOUT); // Cancel the OTP read (20ms should have been enough)
LCDdriver_WriteCom(DD_DISPOFF); // display off
LCDdriver_WriteCom(DD_SLPOUT); // Exit sleep mode.
ms_delay(50); // Small delay
LCDdriver_WriteCom(DD_VopSet); // set LCD operating voltage to 14V.
LCDdriver_WriteData(0x04);
LCDdriver_WriteData(0x01);
LCDdriver_WriteCom(DD_BiasSel); // Select an LCD bias voltage ratio of 1/12.
LCDdriver_WriteData(0x00);
LCDdriver_WriteCom(DD_BstMbpXSel); // x8 booster circuit on
LCDdriver_WriteData(0x07);
LCDdriver_WriteCom(DD_ColScanDir); // Invert the column scan direction for the panel.
LCDdriver_WriteData(0xC0);
LCDdriver_WriteCom(DD_COLORMOD); // 16bpp, 5-6-5 data input mode.
LCDdriver_WriteData(0x05);
LCDdriver_WriteCom(DD_MADCTR); // mem scan direction
LCDdriver_WriteData(0x00);
LCDdriver_WriteCom(DD_DISPON); // display on
// Now Clear the Screen
LCDdriver_WriteCom(DD_CASET);
LCDdriver_WriteData(0x00);
LCDdriver_WriteData(0x7F);
LCDdriver_WriteCom(DD_RASET);
LCDdriver_WriteData(0x01);
LCDdriver_WriteData(0x80);
LCDdriver_WriteCom(DD_RAMWR);
for(i = 0; i < (128 * 128); i++)
{
LCDdriver_WriteData(0x00);
LCDdriver_WriteData(0x00);
}
LCDdriver_WriteCom(DD_NORON); // normal operation mode
}

View File

@ -0,0 +1,36 @@
//*****************************************************************************
// +--+
// | ++----+
// +-++ |
// | |
// +-+--+ |
// | +--+--+
// +----+ Copyright (c) 2009 Code Red Technologies Ltd.
//
// lcd_driver.h - Header file for driver for the lowest level access routines
// for the Sitronix ST7637 LCD Controller/driver used on the RDB1768
// development board.
//
// Software License Agreement
//
// The software is owned by Code Red Technologies and/or its suppliers, and is
// protected under applicable copyright laws. All rights are reserved. Any
// use in violation of the foregoing restrictions may subject the user to criminal
// sanctions under applicable laws, as well as to civil liability for the breach
// of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
// CODE RED TECHNOLOGIES LTD.
#ifndef LCD_DRIVER_H_
#define LCD_DRIVER_H_
void LCDdriver_WriteData(unsigned char LCD_Data);
void LCDdriver_WriteCom(unsigned char LCD_Command);
void LCDdriver_initialisation(void);
#endif /*LCD_DRIVER_H_*/

View File

@ -0,0 +1,673 @@
/*******************************************************************************************
Data table provides the bitmap data of each character.
To get the starting data offset of character 'A', you can use the following expression:
const unsigned char index = index_table['A'];
const unsigned int offset = offset_table[index];
const unsigned char *pData = data_table[offset];
*******************************************************************************************/
const unsigned char font_data_table[] = {
/* character 0x0020 (' '): (width=8, offset=0) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* character 0x0021 ('!'): (width=8, offset=15) */
0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18,
0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
/* character 0x0022 ('"'): (width=8, offset=30) */
0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* character 0x0023 ('#'): (width=8, offset=45) */
0x00, 0x00, 0x00, 0x36, 0x36, 0x7F, 0x36, 0x36,
0x36, 0x7F, 0x36, 0x36, 0x00, 0x00, 0x00,
/* character 0x0024 ('$'): (width=8, offset=60) */
0x00, 0x18, 0x18, 0x3C, 0x66, 0x60, 0x30, 0x18,
0x0C, 0x06, 0x66, 0x3C, 0x18, 0x18, 0x00,
/* character 0x0025 ('%'): (width=8, offset=75) */
0x00, 0x00, 0x70, 0xD8, 0xDA, 0x76, 0x0C, 0x18,
0x30, 0x6E, 0x5B, 0x1B, 0x0E, 0x00, 0x00,
/* character 0x0026 ('&'): (width=8, offset=90) */
0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x60,
0x6F, 0x66, 0x66, 0x3B, 0x00, 0x00, 0x00,
/* character 0x0027 ('''): (width=8, offset=105) */
0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* character 0x0028 ('('): (width=8, offset=120) */
0x00, 0x00, 0x00, 0x0C, 0x18, 0x18, 0x30, 0x30,
0x30, 0x30, 0x30, 0x18, 0x18, 0x0C, 0x00,
/* character 0x0029 (')'): (width=8, offset=135) */
0x00, 0x00, 0x00, 0x30, 0x18, 0x18, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x18, 0x18, 0x30, 0x00,
/* character 0x002A ('*'): (width=8, offset=150) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x1C, 0x7F,
0x1C, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
/* character 0x002B ('+'): (width=8, offset=165) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E,
0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
/* character 0x002C (','): (width=8, offset=180) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1C, 0x1C, 0x0C, 0x18, 0x00,
/* character 0x002D ('-'): (width=8, offset=195) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* character 0x002E ('.'): (width=8, offset=210) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x00,
/* character 0x002F ('/'): (width=8, offset=225) */
0x00, 0x00, 0x00, 0x06, 0x06, 0x0C, 0x0C, 0x18,
0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00,
/* character 0x0030 ('0'): (width=8, offset=240) */
0x00, 0x00, 0x00, 0x1E, 0x33, 0x37, 0x37, 0x33,
0x3B, 0x3B, 0x33, 0x1E, 0x00, 0x00, 0x00,
/* character 0x0031 ('1'): (width=8, offset=255) */
0x00, 0x00, 0x00, 0x0C, 0x1C, 0x7C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00,
/* character 0x0032 ('2'): (width=8, offset=270) */
0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x06, 0x0C,
0x18, 0x30, 0x60, 0x7E, 0x00, 0x00, 0x00,
/* character 0x0033 ('3'): (width=8, offset=285) */
0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x06, 0x1C,
0x06, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00,
/* character 0x0034 ('4'): (width=8, offset=300) */
0x00, 0x00, 0x00, 0x30, 0x30, 0x36, 0x36, 0x36,
0x66, 0x7F, 0x06, 0x06, 0x00, 0x00, 0x00,
/* character 0x0035 ('5'): (width=8, offset=315) */
0x00, 0x00, 0x00, 0x7E, 0x60, 0x60, 0x60, 0x7C,
0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00,
/* character 0x0036 ('6'): (width=8, offset=330) */
0x00, 0x00, 0x00, 0x1C, 0x18, 0x30, 0x7C, 0x66,
0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00,
/* character 0x0037 ('7'): (width=8, offset=345) */
0x00, 0x00, 0x00, 0x7E, 0x06, 0x0C, 0x0C, 0x18,
0x18, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
/* character 0x0038 ('8'): (width=8, offset=360) */
0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x76, 0x3C,
0x6E, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00,
/* character 0x0039 ('9'): (width=8, offset=375) */
0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66,
0x3E, 0x0C, 0x18, 0x38, 0x00, 0x00, 0x00,
/* character 0x003A (':'): (width=8, offset=390) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x00,
0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x00,
/* character 0x003B (';'): (width=8, offset=405) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x00,
0x00, 0x00, 0x1C, 0x1C, 0x0C, 0x18, 0x00,
/* character 0x003C ('<'): (width=8, offset=420) */
0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60,
0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00,
/* character 0x003D ('='): (width=8, offset=435) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00,
0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* character 0x003E ('>'): (width=8, offset=450) */
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06,
0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00,
/* character 0x003F ('?'): (width=8, offset=465) */
0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x0C, 0x18,
0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
/* character 0x0040 ('@'): (width=8, offset=480) */
0x00, 0x00, 0x00, 0x7E, 0xC3, 0xC3, 0xCF, 0xDB,
0xDB, 0xCF, 0xC0, 0x7F, 0x00, 0x00, 0x00,
/* character 0x0041 ('A'): (width=8, offset=495) */
0x00, 0x00, 0x00, 0x18, 0x3C, 0x66, 0x66, 0x66,
0x7E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
/* character 0x0042 ('B'): (width=8, offset=510) */
0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x7C,
0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00,
/* character 0x0043 ('C'): (width=8, offset=525) */
0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x60, 0x60,
0x60, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00,
/* character 0x0044 ('D'): (width=8, offset=540) */
0x00, 0x00, 0x00, 0x78, 0x6C, 0x66, 0x66, 0x66,
0x66, 0x66, 0x6C, 0x78, 0x00, 0x00, 0x00,
/* character 0x0045 ('E'): (width=8, offset=555) */
0x00, 0x00, 0x00, 0x7E, 0x60, 0x60, 0x60, 0x7C,
0x60, 0x60, 0x60, 0x7E, 0x00, 0x00, 0x00,
/* character 0x0046 ('F'): (width=8, offset=570) */
0x00, 0x00, 0x00, 0x7E, 0x60, 0x60, 0x60, 0x7C,
0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00,
/* character 0x0047 ('G'): (width=8, offset=585) */
0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x60, 0x60,
0x6E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00,
/* character 0x0048 ('H'): (width=8, offset=600) */
0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7E,
0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
/* character 0x0049 ('I'): (width=8, offset=615) */
0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00,
/* character 0x004A ('J'): (width=8, offset=630) */
0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00,
/* character 0x004B ('K'): (width=8, offset=645) */
0x00, 0x00, 0x00, 0x66, 0x66, 0x6C, 0x6C, 0x78,
0x6C, 0x6C, 0x66, 0x66, 0x00, 0x00, 0x00,
/* character 0x004C ('L'): (width=8, offset=660) */
0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60,
0x60, 0x60, 0x60, 0x7E, 0x00, 0x00, 0x00,
/* character 0x004D ('M'): (width=8, offset=675) */
0x00, 0x00, 0x00, 0x63, 0x63, 0x77, 0x6B, 0x6B,
0x6B, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00,
/* character 0x004E ('N'): (width=8, offset=690) */
0x00, 0x00, 0x00, 0x63, 0x63, 0x73, 0x7B, 0x6F,
0x67, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00,
/* character 0x004F ('O'): (width=8, offset=705) */
0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00,
/* character 0x0050 ('P'): (width=8, offset=720) */
0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x7C,
0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00,
/* character 0x0051 ('Q'): (width=8, offset=735) */
0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x3C, 0x0C, 0x06, 0x00,
/* character 0x0052 ('R'): (width=8, offset=750) */
0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x7C,
0x6C, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
/* character 0x0053 ('S'): (width=8, offset=765) */
0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x30, 0x18,
0x0C, 0x06, 0x66, 0x3C, 0x00, 0x00, 0x00,
/* character 0x0054 ('T'): (width=8, offset=780) */
0x00, 0x00, 0x00, 0x7E, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
/* character 0x0055 ('U'): (width=8, offset=795) */
0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00,
/* character 0x0056 ('V'): (width=8, offset=810) */
0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00,
/* character 0x0057 ('W'): (width=8, offset=825) */
0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x6B, 0x6B,
0x6B, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00,
/* character 0x0058 ('X'): (width=8, offset=840) */
0x00, 0x00, 0x00, 0x66, 0x66, 0x34, 0x18, 0x18,
0x2C, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
/* character 0x0059 ('Y'): (width=8, offset=855) */
0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
/* character 0x005A ('Z'): (width=8, offset=870) */
0x00, 0x00, 0x00, 0x7E, 0x06, 0x06, 0x0C, 0x18,
0x30, 0x60, 0x60, 0x7E, 0x00, 0x00, 0x00,
/* character 0x005B ('['): (width=8, offset=885) */
0x00, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C,
/* character 0x005C ('\'): (width=8, offset=900) */
0x00, 0x00, 0x00, 0x60, 0x60, 0x30, 0x30, 0x18,
0x18, 0x0C, 0x0C, 0x06, 0x06, 0x00, 0x00,
/* character 0x005D (']'): (width=8, offset=915) */
0x00, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C,
/* character 0x005E ('^'): (width=8, offset=930) */
0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* character 0x005F ('_'): (width=8, offset=945) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
/* character 0x0060 ('`'): (width=8, offset=960) */
0x00, 0x38, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* character 0x0061 ('a'): (width=8, offset=975) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x06, 0x06,
0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00,
/* character 0x0062 ('b'): (width=8, offset=990) */
0x00, 0x00, 0x00, 0x60, 0x60, 0x7C, 0x66, 0x66,
0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00,
/* character 0x0063 ('c'): (width=8, offset=1005) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60,
0x60, 0x60, 0x66, 0x3C, 0x00, 0x00, 0x00,
/* character 0x0064 ('d'): (width=8, offset=1020) */
0x00, 0x00, 0x00, 0x06, 0x06, 0x3E, 0x66, 0x66,
0x66, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00,
/* character 0x0065 ('e'): (width=8, offset=1035) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66,
0x7E, 0x60, 0x60, 0x3C, 0x00, 0x00, 0x00,
/* character 0x0066 ('f'): (width=8, offset=1050) */
0x00, 0x00, 0x00, 0x1E, 0x30, 0x30, 0x30, 0x7E,
0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
/* character 0x0067 ('g'): (width=8, offset=1065) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x66, 0x66,
0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x7C,
/* character 0x0068 ('h'): (width=8, offset=1080) */
0x00, 0x00, 0x00, 0x60, 0x60, 0x7C, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
/* character 0x0069 ('i'): (width=8, offset=1095) */
0x00, 0x00, 0x18, 0x18, 0x00, 0x78, 0x18, 0x18,
0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00,
/* character 0x006A ('j'): (width=8, offset=1110) */
0x00, 0x00, 0x0C, 0x0C, 0x00, 0x3C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x78,
/* character 0x006B ('k'): (width=8, offset=1125) */
0x00, 0x00, 0x00, 0x60, 0x60, 0x66, 0x66, 0x6C,
0x78, 0x6C, 0x66, 0x66, 0x00, 0x00, 0x00,
/* character 0x006C ('l'): (width=8, offset=1140) */
0x00, 0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00,
/* character 0x006D ('m'): (width=8, offset=1155) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x6B, 0x6B,
0x6B, 0x6B, 0x6B, 0x63, 0x00, 0x00, 0x00,
/* character 0x006E ('n'): (width=8, offset=1170) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
/* character 0x006F ('o'): (width=8, offset=1185) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66,
0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00,
/* character 0x0070 ('p'): (width=8, offset=1200) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66,
0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60,
/* character 0x0071 ('q'): (width=8, offset=1215) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x66, 0x66,
0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x06,
/* character 0x0072 ('r'): (width=8, offset=1230) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6E, 0x70,
0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00,
/* character 0x0073 ('s'): (width=8, offset=1245) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x60, 0x60,
0x3C, 0x06, 0x06, 0x7C, 0x00, 0x00, 0x00,
/* character 0x0074 ('t'): (width=8, offset=1260) */
0x00, 0x00, 0x00, 0x30, 0x30, 0x7E, 0x30, 0x30,
0x30, 0x30, 0x30, 0x1E, 0x00, 0x00, 0x00,
/* character 0x0075 ('u'): (width=8, offset=1275) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00,
/* character 0x0076 ('v'): (width=8, offset=1290) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66,
0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00,
/* character 0x0077 ('w'): (width=8, offset=1305) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x6B, 0x6B,
0x6B, 0x6B, 0x36, 0x36, 0x00, 0x00, 0x00,
/* character 0x0078 ('x'): (width=8, offset=1320) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3C,
0x18, 0x3C, 0x66, 0x66, 0x00, 0x00, 0x00,
/* character 0x0079 ('y'): (width=8, offset=1335) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x3C, 0x0C, 0x18, 0xF0,
/* character 0x007A ('z'): (width=8, offset=1350) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x06, 0x0C,
0x18, 0x30, 0x60, 0x7E, 0x00, 0x00, 0x00,
/* character 0x007B ('{'): (width=8, offset=1365) */
0x00, 0x00, 0x00, 0x0C, 0x18, 0x18, 0x18, 0x30,
0x60, 0x30, 0x18, 0x18, 0x18, 0x0C, 0x00,
/* character 0x007C ('|'): (width=8, offset=1380) */
0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* character 0x007D ('}'): (width=8, offset=1395) */
0x00, 0x00, 0x00, 0x30, 0x18, 0x18, 0x18, 0x0C,
0x06, 0x0C, 0x18, 0x18, 0x18, 0x30, 0x00,
/* character 0x007E ('~'): (width=8, offset=1410) */
0x00, 0x00, 0x00, 0x71, 0xDB, 0x8E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* character 0x007F (''): (width=8, offset=1425) */
0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,
0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00,
};
/*******************************************************************************************
Index table is used to find the mapping index of a character.
If you can find a simple mathematical expression for index mapping, you can use that.
If you do not have such a mathematical expression, this index table is just for you.
To get the index of character 'A', you can use the following expression:
const unsigned char index = index_table['A'];
*******************************************************************************************/
const unsigned char font_index_table[] = {
/* index hexcode decimal char */
/* ===== ======= ======= ==== */
0, /* 00 0 . */
0, /* 01 1 . */
0, /* 02 2 . */
0, /* 03 3 . */
0, /* 04 4 . */
0, /* 05 5 . */
0, /* 06 6 . */
0, /* 07 7 . */
0, /* 08 8 . */
0, /* 09 9 . */
0, /* 0A 10 . */
0, /* 0B 11 . */
0, /* 0C 12 . */
0, /* 0D 13 . */
0, /* 0E 14 . */
0, /* 0F 15 . */
0, /* 10 16 . */
0, /* 11 17 . */
0, /* 12 18 . */
0, /* 13 19 . */
0, /* 14 20 . */
0, /* 15 21 . */
0, /* 16 22 . */
0, /* 17 23 . */
0, /* 18 24 . */
0, /* 19 25 . */
0, /* 1A 26 . */
0, /* 1B 27 . */
0, /* 1C 28 . */
0, /* 1D 29 . */
0, /* 1E 30 . */
0, /* 1F 31 . */
0, /* 20 32 */
1, /* 21 33 ! */
2, /* 22 34 " */
3, /* 23 35 # */
4, /* 24 36 $ */
5, /* 25 37 % */
6, /* 26 38 & */
7, /* 27 39 ' */
8, /* 28 40 ( */
9, /* 29 41 ) */
10, /* 2A 42 * */
11, /* 2B 43 + */
12, /* 2C 44 , */
13, /* 2D 45 - */
14, /* 2E 46 . */
15, /* 2F 47 / */
16, /* 30 48 0 */
17, /* 31 49 1 */
18, /* 32 50 2 */
19, /* 33 51 3 */
20, /* 34 52 4 */
21, /* 35 53 5 */
22, /* 36 54 6 */
23, /* 37 55 7 */
24, /* 38 56 8 */
25, /* 39 57 9 */
26, /* 3A 58 : */
27, /* 3B 59 ; */
28, /* 3C 60 < */
29, /* 3D 61 = */
30, /* 3E 62 > */
31, /* 3F 63 ? */
32, /* 40 64 @ */
33, /* 41 65 A */
34, /* 42 66 B */
35, /* 43 67 C */
36, /* 44 68 D */
37, /* 45 69 E */
38, /* 46 70 F */
39, /* 47 71 G */
40, /* 48 72 H */
41, /* 49 73 I */
42, /* 4A 74 J */
43, /* 4B 75 K */
44, /* 4C 76 L */
45, /* 4D 77 M */
46, /* 4E 78 N */
47, /* 4F 79 O */
48, /* 50 80 P */
49, /* 51 81 Q */
50, /* 52 82 R */
51, /* 53 83 S */
52, /* 54 84 T */
53, /* 55 85 U */
54, /* 56 86 V */
55, /* 57 87 W */
56, /* 58 88 X */
57, /* 59 89 Y */
58, /* 5A 90 Z */
59, /* 5B 91 [ */
60, /* 5C 92 \ */
61, /* 5D 93 ] */
62, /* 5E 94 ^ */
63, /* 5F 95 _ */
64, /* 60 96 ` */
65, /* 61 97 a */
66, /* 62 98 b */
67, /* 63 99 c */
68, /* 64 100 d */
69, /* 65 101 e */
70, /* 66 102 f */
71, /* 67 103 g */
72, /* 68 104 h */
73, /* 69 105 i */
74, /* 6A 106 j */
75, /* 6B 107 k */
76, /* 6C 108 l */
77, /* 6D 109 m */
78, /* 6E 110 n */
79, /* 6F 111 o */
80, /* 70 112 p */
81, /* 71 113 q */
82, /* 72 114 r */
83, /* 73 115 s */
84, /* 74 116 t */
85, /* 75 117 u */
86, /* 76 118 v */
87, /* 77 119 w */
88, /* 78 120 x */
89, /* 79 121 y */
90, /* 7A 122 z */
91, /* 7B 123 { */
92, /* 7C 124 | */
93, /* 7D 125 } */
94, /* 7E 126 ~ */
95, /* 7F 127  */
0, /* 80 128 ? */
0, /* 81 129 <20> */
0, /* 82 130 ? */
0, /* 83 131 ? */
0, /* 84 132 ? */
0, /* 85 133 ? */
0, /* 86 134 ? */
0, /* 87 135 ? */
0, /* 88 136 ? */
0, /* 89 137 ? */
0, /* 8A 138 ? */
0, /* 8B 139 ? */
0, /* 8C 140 ? */
0, /* 8D 141 <20> */
0, /* 8E 142 ? */
0, /* 8F 143 <20> */
0, /* 90 144 <20> */
0, /* 91 145 ? */
0, /* 92 146 ? */
0, /* 93 147 ? */
0, /* 94 148 ? */
0, /* 95 149 ? */
0, /* 96 150 ? */
0, /* 97 151 ? */
0, /* 98 152 ? */
0, /* 99 153 ? */
0, /* 9A 154 ? */
0, /* 9B 155 ? */
0, /* 9C 156 ? */
0, /* 9D 157 <20> */
0, /* 9E 158 ? */
0, /* 9F 159 ? */
0, /* A0 160 <20> */
0, /* A1 161 <20> */
0, /* A2 162 <20> */
0, /* A3 163 <20> */
0, /* A4 164 <20> */
0, /* A5 165 <20> */
0, /* A6 166 <20> */
0, /* A7 167 <20> */
0, /* A8 168 <20> */
0, /* A9 169 <20> */
0, /* AA 170 <20> */
0, /* AB 171 <20> */
0, /* AC 172 <20> */
0, /* AD 173 <20> */
0, /* AE 174 <20> */
0, /* AF 175 <20> */
0, /* B0 176 <20> */
0, /* B1 177 <20> */
0, /* B2 178 <20> */
0, /* B3 179 <20> */
0, /* B4 180 <20> */
0, /* B5 181 <20> */
0, /* B6 182 <20> */
0, /* B7 183 <20> */
0, /* B8 184 <20> */
0, /* B9 185 <20> */
0, /* BA 186 <20> */
0, /* BB 187 <20> */
0, /* BC 188 <20> */
0, /* BD 189 <20> */
0, /* BE 190 <20> */
0, /* BF 191 <20> */
0, /* C0 192 <20> */
0, /* C1 193 <20> */
0, /* C2 194 <20> */
0, /* C3 195 <20> */
0, /* C4 196 <20> */
0, /* C5 197 <20> */
0, /* C6 198 <20> */
0, /* C7 199 <20> */
0, /* C8 200 <20> */
0, /* C9 201 <20> */
0, /* CA 202 <20> */
0, /* CB 203 <20> */
0, /* CC 204 <20> */
0, /* CD 205 <20> */
0, /* CE 206 <20> */
0, /* CF 207 <20> */
0, /* D0 208 <20> */
0, /* D1 209 <20> */
0, /* D2 210 <20> */
0, /* D3 211 <20> */
0, /* D4 212 <20> */
0, /* D5 213 <20> */
0, /* D6 214 <20> */
0, /* D7 215 <20> */
0, /* D8 216 <20> */
0, /* D9 217 <20> */
0, /* DA 218 <20> */
0, /* DB 219 <20> */
0, /* DC 220 <20> */
0, /* DD 221 <20> */
0, /* DE 222 <20> */
0, /* DF 223 <20> */
0, /* E0 224 <20> */
0, /* E1 225 <20> */
0, /* E2 226 <20> */
0, /* E3 227 <20> */
0, /* E4 228 <20> */
0, /* E5 229 <20> */
0, /* E6 230 <20> */
0, /* E7 231 <20> */
0, /* E8 232 <20> */
0, /* E9 233 <20> */
0, /* EA 234 <20> */
0, /* EB 235 <20> */
0, /* EC 236 <20> */
0, /* ED 237 <20> */
0, /* EE 238 <20> */
0, /* EF 239 <20> */
0, /* F0 240 <20> */
0, /* F1 241 <20> */
0, /* F2 242 <20> */
0, /* F3 243 <20> */
0, /* F4 244 <20> */
0, /* F5 245 <20> */
0, /* F6 246 <20> */
0, /* F7 247 <20> */
0, /* F8 248 <20> */
0, /* F9 249 <20> */
0, /* FA 250 <20> */
0, /* FB 251 <20> */
0, /* FC 252 <20> */
0, /* FD 253 <20> */
0, /* FE 254 <20> */
0, /* FF 255 <20> */
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,133 @@
/*
FreeRTOS.org V5.4.0 - Copyright (C) 2003-2009 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org 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 exception to the GPL is included to allow you to distribute a
combined work that includes FreeRTOS.org without being obliged to provide
the source code for any proprietary components. Alternative commercial
license and support terms are also available upon request. See the
licensing section of http://www.FreeRTOS.org for full details.
FreeRTOS.org 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 along
with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
* *
* This is a concise, step by step, 'hands on' guide that describes both *
* general multitasking concepts and FreeRTOS specifics. It presents and *
* explains numerous examples that are written using the FreeRTOS API. *
* Full source code for all the examples is provided in an accompanying *
* .zip file. *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
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.
*/
/* FreeRTOS.org includes. */
#include "FreeRTOS.h"
/* Demo application includes. */
#include "partest.h"
#define LED_2 ( 1UL << 24UL )
#define LED_3 ( 1UL << 25UL )
#define LED_4 ( 1UL << 28UL )
#define LED_5 ( 1UL << 29UL )
#define partstFIO1_BITS ( LED_2 | LED_3 | LED_4 | LED_5 )
#define partstNUM_LEDS ( 4 )
static unsigned long ulLEDs[] = { LED_3, LED_2, LED_5, LED_4 };
/*-----------------------------------------------------------
* Simple parallel port IO routines.
*-----------------------------------------------------------*/
void vParTestInitialise( void )
{
/* LEDs on port 1. */
GPIO1->FIODIR = partstFIO1_BITS;
/* Start will all LEDs off. */
GPIO1->FIOCLR = partstFIO1_BITS;
}
/*-----------------------------------------------------------*/
void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
{
if( uxLED < partstNUM_LEDS )
{
/* Set of clear the output. */
if( xValue )
{
GPIO1->FIOCLR = ulLEDs[ uxLED ];
}
else
{
GPIO1->FIOSET = ulLEDs[ uxLED ];
}
}
}
/*-----------------------------------------------------------*/
void vParTestToggleLED( unsigned portBASE_TYPE uxLED )
{
if( uxLED < partstNUM_LEDS )
{
if( GPIO1->FIOPIN & ulLEDs[ uxLED ] )
{
GPIO1->FIOCLR = ulLEDs[ uxLED ];
}
else
{
GPIO1->FIOSET = ulLEDs[ uxLED ];
}
}
}
/*-----------------------------------------------------------*/
unsigned portBASE_TYPE uxParTextGetLED( unsigned portBASE_TYPE uxLED )
{
if( uxLED < partstNUM_LEDS )
{
return ( GPIO1->FIOPIN & ulLEDs[ uxLED ] );
}
else
{
return 0;
}
}
/*-----------------------------------------------------------*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,312 @@
//*****************************************************************************
// +--+
// | ++----+
// +-++ |
// | |
// +-+--+ |
// | +--+--+
// +----+ Copyright (c) 2009 Code Red Technologies Ltd.
//
// Microcontroller Startup code for use with Red Suite
//
// Software License Agreement
//
// The software is owned by Code Red Technologies and/or its suppliers, and is
// protected under applicable copyright laws. All rights are reserved. Any
// use in violation of the foregoing restrictions may subject the user to criminal
// sanctions under applicable laws, as well as to civil liability for the breach
// of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
// CODE RED TECHNOLOGIES LTD.
//
//*****************************************************************************
#define WEAK __attribute__ ((weak))
#define ALIAS(f) __attribute__ ((weak, alias (#f)))
//*****************************************************************************
//
// Forward declaration of the default handlers.
//
//*****************************************************************************
void Reset_Handler(void);
void ResetISR(void) ALIAS(Reset_Handler);
static void NMI_Handler(void);
static void HardFault_Handler(void);
static void MemManage_Handler(void);
static void BusFault_Handler(void);
static void UsageFault_Handler(void);
static void DebugMon_Handler(void);
//*****************************************************************************
//
// Forward declaration of the specific IRQ handlers. These are aliased
// to the IntDefaultHandler, which is a 'forever' loop. When the application
// defines a handler (with the same name), this will automatically take
// precedence over these weak definitions
//
//*****************************************************************************
void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER0_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER1_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER2_IRQHandler(void) ALIAS(IntDefaultHandler);
void TIMER3_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);
void UART3_IRQHandler(void) ALIAS(IntDefaultHandler);
void PWM1_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2C2_IRQHandler(void) ALIAS(IntDefaultHandler);
void SPI_IRQHandler(void) ALIAS(IntDefaultHandler);
void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);
void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);
void PLL0_IRQHandler(void) ALIAS(IntDefaultHandler);
void RTC_IRQHandler(void) ALIAS(IntDefaultHandler);
void EINT0_IRQHandler(void) ALIAS(IntDefaultHandler);
void EINT1_IRQHandler(void) ALIAS(IntDefaultHandler);
void EINT2_IRQHandler(void) ALIAS(IntDefaultHandler);
void EINT3_IRQHandler(void) ALIAS(IntDefaultHandler);
void ADC_IRQHandler(void) ALIAS(IntDefaultHandler);
void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);
void USB_IRQHandler(void) ALIAS(IntDefaultHandler);
void CAN_IRQHandler(void) ALIAS(IntDefaultHandler);
void DMA_IRQHandler(void) ALIAS(IntDefaultHandler);
void I2S_IRQHandler(void) ALIAS(IntDefaultHandler);
void ENET_IRQHandler(void) ALIAS(IntDefaultHandler);
void RIT_IRQHandler(void) ALIAS(IntDefaultHandler);
void MCPWM_IRQHandler(void) ALIAS(IntDefaultHandler);
void QEI_IRQHandler(void) ALIAS(IntDefaultHandler);
void PLL1_IRQHandler(void) ALIAS(IntDefaultHandler);
extern void xPortSysTickHandler(void);
extern void xPortPendSVHandler(void);
extern void vPortSVCHandler( void );
extern void vEMAC_ISR( void );
//*****************************************************************************
//
// The entry point for the C++ library startup
//
//*****************************************************************************
extern WEAK void __libc_init_array(void);
//*****************************************************************************
//
// The entry point for the application.
// __main() is the entry point for redlib based applications
// main() is the entry point for newlib based applications
//
//*****************************************************************************
extern WEAK void __main(void);
extern WEAK void main(void);
//*****************************************************************************
//
// External declaration for the pointer to the stack top from the Linker Script
//
//*****************************************************************************
extern void _vStackTop;
//*****************************************************************************
//
// The vector table.
// This relies on the linker script to place at correct location in memory.
//
//*****************************************************************************
__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
{
// Core Level - CM3
(void *)&_vStackTop, // The initial stack pointer
Reset_Handler, // The reset handler
NMI_Handler, // The NMI handler
HardFault_Handler, // The hard fault handler
MemManage_Handler, // The MPU fault handler
BusFault_Handler, // The bus fault handler
UsageFault_Handler, // The usage fault handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
vPortSVCHandler, // SVCall handler
DebugMon_Handler, // Debug monitor handler
0, // Reserved
xPortPendSVHandler, // The PendSV handler
xPortSysTickHandler, // The SysTick handler
// Chip Level - LPC17
WDT_IRQHandler, // 16, 0x40 - WDT
TIMER0_IRQHandler, // 17, 0x44 - TIMER0
TIMER1_IRQHandler, // 18, 0x48 - TIMER1
TIMER2_IRQHandler, // 19, 0x4c - TIMER2
TIMER3_IRQHandler, // 20, 0x50 - TIMER3
UART0_IRQHandler, // 21, 0x54 - UART0
UART1_IRQHandler, // 22, 0x58 - UART1
UART2_IRQHandler, // 23, 0x5c - UART2
UART3_IRQHandler, // 24, 0x60 - UART3
PWM1_IRQHandler, // 25, 0x64 - PWM1
I2C0_IRQHandler, // 26, 0x68 - I2C0
I2C1_IRQHandler, // 27, 0x6c - I2C1
I2C2_IRQHandler, // 28, 0x70 - I2C2
SPI_IRQHandler, // 29, 0x74 - SPI
SSP0_IRQHandler, // 30, 0x78 - SSP0
SSP1_IRQHandler, // 31, 0x7c - SSP1
PLL0_IRQHandler, // 32, 0x80 - PLL0 (Main PLL)
RTC_IRQHandler, // 33, 0x84 - RTC
EINT0_IRQHandler, // 34, 0x88 - EINT0
EINT1_IRQHandler, // 35, 0x8c - EINT1
EINT2_IRQHandler, // 36, 0x90 - EINT2
EINT3_IRQHandler, // 37, 0x94 - EINT3
ADC_IRQHandler, // 38, 0x98 - ADC
BOD_IRQHandler, // 39, 0x9c - BOD
USB_IRQHandler, // 40, 0xA0 - USB
CAN_IRQHandler, // 41, 0xa4 - CAN
DMA_IRQHandler, // 42, 0xa8 - GP DMA
I2S_IRQHandler, // 43, 0xac - I2S
vEMAC_ISR, // Ethernet.
RIT_IRQHandler, // 45, 0xb4 - RITINT
MCPWM_IRQHandler, // 46, 0xb8 - Motor Control PWM
QEI_IRQHandler, // 47, 0xbc - Quadrature Encoder
PLL1_IRQHandler, // 48, 0xc0 - PLL1 (USB PLL)
};
//*****************************************************************************
//
// The following are constructs created by the linker, indicating where the
// the "data" and "bss" segments reside in memory. The initializers for the
// for the "data" segment resides immediately following the "text" segment.
//
//*****************************************************************************
extern unsigned long _etext;
extern unsigned long _data;
extern unsigned long _edata;
extern unsigned long _bss;
extern unsigned long _ebss;
//*****************************************************************************
// Reset entry point for your code.
// Sets up a simple runtime environment and initializes the C/C++
// library.
//
//*****************************************************************************
void Reset_Handler(void)
{
unsigned long *pulSrc, *pulDest;
//
// Copy the data segment initializers from flash to SRAM.
//
pulSrc = &_etext;
for(pulDest = &_data; pulDest < &_edata; )
{
*pulDest++ = *pulSrc++;
}
//
// Zero fill the bss segment. This is done with inline assembly since this
// will clear the value of pulDest if it is not kept in a register.
//
__asm(" ldr r0, =_bss\n"
" ldr r1, =_ebss\n"
" mov r2, #0\n"
" .thumb_func\n"
"zero_loop:\n"
" cmp r0, r1\n"
" it lt\n"
" strlt r2, [r0], #4\n"
" blt zero_loop");
//
// Call C++ library initilisation, if present
//
if (__libc_init_array)
__libc_init_array() ;
//
// Call the application's entry point.
// __main() is the entry point for redlib based applications (which calls main())
// main() is the entry point for newlib based applications
//
if (__main)
__main() ;
else
main() ;
//
// main() shouldn't return, but if it does, we'll just enter an infinite loop
//
while (1) {
;
}
}
//*****************************************************************************
//
// This is the code that gets called when the processor receives a NMI. This
// simply enters an infinite loop, preserving the system state for examination
// by a debugger.
//
//*****************************************************************************
static void NMI_Handler(void)
{
while(1)
{
}
}
static void HardFault_Handler(void)
{
while(1)
{
}
}
static void MemManage_Handler(void)
{
while(1)
{
}
}
static void BusFault_Handler(void)
{
while(1)
{
}
}
static void UsageFault_Handler(void)
{
while(1)
{
}
}
static void DebugMon_Handler(void)
{
while(1)
{
}
}
//*****************************************************************************
//
// Processor ends up here if an unexpected interrupt occurs or a handler
// is not present in the application code.
//
//*****************************************************************************
static void IntDefaultHandler(void)
{
//
// Go into an infinite loop.
//
while(1)
{
}
}

View File

@ -0,0 +1,339 @@
/*
FreeRTOS.org V5.4.0 - Copyright (C) 2003-2009 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org 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 exception to the GPL is included to allow you to distribute a
combined work that includes FreeRTOS.org without being obliged to provide
the source code for any proprietary components. Alternative commercial
license and support terms are also available upon request. See the
licensing section of http://www.FreeRTOS.org for full details.
FreeRTOS.org 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 along
with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
* *
* This is a concise, step by step, 'hands on' guide that describes both *
* general multitasking concepts and FreeRTOS specifics. It presents and *
* explains numerous examples that are written using the FreeRTOS API. *
* Full source code for all the examples is provided in an accompanying *
* .zip file. *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
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.
*/
/*
* Creates all the demo application tasks, then starts the scheduler. The WEB
* documentation provides more details of the standard demo application tasks
* (which just exist to test the kernel port and provide an example of how to use
* each FreeRTOS API function).
*
* In addition to the standard demo tasks, the following tasks and tests are
* defined and/or created within this file:
*
* "Check" hook - This only executes fully every five seconds from the tick
* hook. Its main function is to check that all the standard demo tasks are
* still operational. The status can be viewed using on the Task Stats page
* served by the WEB server.
*
* "uIP" task - This is the task that handles the uIP stack. All TCP/IP
* processing is performed in this task.
*/
/* Standard includes. */
#include "stdio.h"
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Demo app includes. */
#include "BlockQ.h"
#include "integer.h"
#include "blocktim.h"
#include "flash.h"
#include "partest.h"
#include "semtest.h"
#include "PollQ.h"
#include "GenQTest.h"
#include "QPeek.h"
#include "recmutex.h"
/* Red Suite includes. */
#include "lcd_driver.h"
#include "lcd.h"
/*-----------------------------------------------------------*/
/* The time between cycles of the 'check' functionality (defined within the
tick hook. */
#define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS )
/* Task priorities. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainUIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* The WEB server has a larger stack as it utilises stack hungry string
handling library calls. */
#define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 )
/* The message displayed by the WEB server when all tasks are executing
without an error being reported. */
#define mainPASS_STATUS_MESSAGE "All tasks are executing without error."
/*-----------------------------------------------------------*/
/*
* Configure the hardware for the demo.
*/
static void prvSetupHardware( void );
/*
* The task that handles the uIP stack. All TCP/IP processing is performed in
* this task.
*/
extern void vuIP_Task( void *pvParameters );
/*
* Simply returns the current status message for display on served WEB pages.
*/
char *pcGetTaskStatusMessage( void );
/*-----------------------------------------------------------*/
/* Holds the status message displayed by the WEB server. */
static char *pcStatusMessage = mainPASS_STATUS_MESSAGE;
/*-----------------------------------------------------------*/
int main( void )
{
char cIPAddress[ 16 ]; /* Enough space for "xxx.xxx.xxx.xxx\0". */
/* Configure the hardware for use by this demo. */
prvSetupHardware();
/* Start the standard demo tasks. These are just here to exercise the
kernel port and provide examples of how the FreeRTOS API can be used. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartQueuePeekTasks();
vStartRecursiveMutexTasks();
vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
/* Display the IP address, then create the uIP task. The WEB server runs
in this task. */
LCDdriver_initialisation();
LCD_PrintString( 5, 10, "FreeRTOS.org", 14, COLOR_GREEN);
sprintf( cIPAddress, "%d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
LCD_PrintString( 5, 30, cIPAddress, 14, COLOR_RED);
xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL );
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
task. The idle task is created within vTaskStartScheduler(). */
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
static unsigned portLONG ulTicksSinceLastDisplay = 0;
/* Called from every tick interrupt as described in the comments at the top
of this file.
Have enough ticks passed to make it time to perform our health status
check again? */
ulTicksSinceLastDisplay++;
if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
{
/* Reset the counter so these checks run again in mainCHECK_DELAY
ticks time. */
ulTicksSinceLastDisplay = 0;
/* Has an error been found in any task? */
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "An error has been detected in the Generic Queue test/demo.";
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "An error has been detected in the Peek Queue test/demo.";
}
else if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
pcStatusMessage = "An error has been detected in the Block Queue test/demo.";
}
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "An error has been detected in the Block Time test/demo.";
}
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "An error has been detected in the Semaphore test/demo.";
}
else if( xArePollingQueuesStillRunning() != pdTRUE )
{
pcStatusMessage = "An error has been detected in the Poll Queue test/demo.";
}
else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
pcStatusMessage = "An error has been detected in the Int Math test/demo.";
}
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "An error has been detected in the Mutex test/demo.";
}
}
}
/*-----------------------------------------------------------*/
char *pcGetTaskStatusMessage( void )
{
/* Not bothered about a critical section here. */
return pcStatusMessage;
}
/*-----------------------------------------------------------*/
void prvSetupHardware( void )
{
/* Disable peripherals power. */
SC->PCONP = 0;
/* Enable GPIO power. */
SC->PCONP = PCONP_PCGPIO;
/* Disable TPIU. */
PINCON->PINSEL10 = 0;
/* Disconnect the main PLL. */
SC->PLL0CON &= ~PLLCON_PLLC;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
while ((SC->PLL0STAT & PLLSTAT_PLLC) != 0);
/* Turn off the main PLL. */
SC->PLL0CON &= ~PLLCON_PLLE;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
while ((SC->PLL0STAT & PLLSTAT_PLLE) != 0);
/* No CPU clock divider. */
SC->CCLKCFG = 0;
/* OSCEN. */
SC->SCS = 0x20;
while ((SC->SCS & 0x40) == 0);
/* Use main oscillator. */
SC->CLKSRCSEL = 1;
SC->PLL0CFG = (PLLCFG_MUL16 | PLLCFG_DIV1);
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
/* Activate the PLL by turning it on then feeding the correct
sequence of bytes. */
SC->PLL0CON = PLLCON_PLLE;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
/* 6x CPU clock divider (64 MHz) */
SC->CCLKCFG = 5;
/* Wait for the PLL to lock. */
while ((SC->PLL0STAT & PLLSTAT_PLOCK) == 0);
/* Connect the PLL. */
SC->PLL0CON = PLLCON_PLLC | PLLCON_PLLE;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
/* Setup the peripheral bus to be the same as the PLL output (64 MHz). */
SC->PCLKSEL0 = 0x05555555;
/* Configure the LEDs. */
vParTestInitialise();
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName )
{
/* This function will get called if a task overflows its stack. */
( void ) pxTask;
( void ) pcTaskName;
for( ;; );
}
/*-----------------------------------------------------------*/
void vConfigureTimerForRunTimeStats( void )
{
const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
/* This function configures a timer that is used as the time base when
collecting run time statistical information - basically the percentage
of CPU time that each task is utilising. It is called automatically when
the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set
to 1). */
/* Power up and feed the timer. */
SC->PCONP |= 0x02UL;
SC->PCLKSEL0 = (SC->PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
/* Reset Timer 0 */
TIM0->TCR = TCR_COUNT_RESET;
/* Just count up. */
TIM0->CTCR = CTCR_CTM_TIMER;
/* Prescale to a frequency that is good enough to get a decent resolution,
but not too fast so as to overflow all the time. */
TIM0->PR = ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;
/* Start the counter. */
TIM0->TCR = TCR_COUNT_ENABLE;
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,293 @@
/*
Copyright 2001, 2002 Georges Menie (www.menie.org)
stdarg version contributed by Christian Ettinger
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
putchar is the only external dependency for this file,
if you have a working putchar, leave it commented out.
If not, uncomment the define below and
replace outbyte(c) by your own function call.
*/
#define putchar(c) c
#include <stdarg.h>
static void printchar(char **str, int c)
{
//extern int putchar(int c);
if (str) {
**str = (char)c;
++(*str);
}
else
{
(void)putchar(c);
}
}
#define PAD_RIGHT 1
#define PAD_ZERO 2
static int prints(char **out, const char *string, int width, int pad)
{
register int pc = 0, padchar = ' ';
if (width > 0) {
register int len = 0;
register const char *ptr;
for (ptr = string; *ptr; ++ptr) ++len;
if (len >= width) width = 0;
else width -= len;
if (pad & PAD_ZERO) padchar = '0';
}
if (!(pad & PAD_RIGHT)) {
for ( ; width > 0; --width) {
printchar (out, padchar);
++pc;
}
}
for ( ; *string ; ++string) {
printchar (out, *string);
++pc;
}
for ( ; width > 0; --width) {
printchar (out, padchar);
++pc;
}
return pc;
}
/* the following should be enough for 32 bit int */
#define PRINT_BUF_LEN 12
static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
{
char print_buf[PRINT_BUF_LEN];
register char *s;
register int t, neg = 0, pc = 0;
register unsigned int u = (unsigned int)i;
if (i == 0) {
print_buf[0] = '0';
print_buf[1] = '\0';
return prints (out, print_buf, width, pad);
}
if (sg && b == 10 && i < 0) {
neg = 1;
u = (unsigned int)-i;
}
s = print_buf + PRINT_BUF_LEN-1;
*s = '\0';
while (u) {
t = (unsigned int)u % b;
if( t >= 10 )
t += letbase - '0' - 10;
*--s = (char)(t + '0');
u /= b;
}
if (neg) {
if( width && (pad & PAD_ZERO) ) {
printchar (out, '-');
++pc;
--width;
}
else {
*--s = '-';
}
}
return pc + prints (out, s, width, pad);
}
static int print( char **out, const char *format, va_list args )
{
register int width, pad;
register int pc = 0;
char scr[2];
for (; *format != 0; ++format) {
if (*format == '%') {
++format;
width = pad = 0;
if (*format == '\0') break;
if (*format == '%') goto out;
if (*format == '-') {
++format;
pad = PAD_RIGHT;
}
while (*format == '0') {
++format;
pad |= PAD_ZERO;
}
for ( ; *format >= '0' && *format <= '9'; ++format) {
width *= 10;
width += *format - '0';
}
if( *format == 's' ) {
register char *s = (char *)va_arg( args, int );
pc += prints (out, s?s:"(null)", width, pad);
continue;
}
if( *format == 'd' ) {
pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');
continue;
}
if( *format == 'x' ) {
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');
continue;
}
if( *format == 'X' ) {
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');
continue;
}
if( *format == 'u' ) {
pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');
continue;
}
if( *format == 'c' ) {
/* char are converted to int then pushed on the stack */
scr[0] = (char)va_arg( args, int );
scr[1] = '\0';
pc += prints (out, scr, width, pad);
continue;
}
}
else {
out:
printchar (out, *format);
++pc;
}
}
if (out) **out = '\0';
va_end( args );
return pc;
}
int printf(const char *format, ...)
{
va_list args;
va_start( args, format );
return print( 0, format, args );
}
int sprintf(char *out, const char *format, ...)
{
va_list args;
va_start( args, format );
return print( &out, format, args );
}
int snprintf( char *buf, unsigned int count, const char *format, ... )
{
va_list args;
( void ) count;
va_start( args, format );
return print( &buf, format, args );
}
#ifdef TEST_PRINTF
int main(void)
{
char *ptr = "Hello world!";
char *np = 0;
int i = 5;
unsigned int bs = sizeof(int)*8;
int mi;
char buf[80];
mi = (1 << (bs-1)) + 1;
printf("%s\n", ptr);
printf("printf test\n");
printf("%s is null pointer\n", np);
printf("%d = 5\n", i);
printf("%d = - max int\n", mi);
printf("char %c = 'a'\n", 'a');
printf("hex %x = ff\n", 0xff);
printf("hex %02x = 00\n", 0);
printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
printf("%d %s(s)%", 0, "message");
printf("\n");
printf("%d %s(s) with %%\n", 0, "message");
sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);
sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);
sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);
sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);
sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);
sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);
sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);
sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);
return 0;
}
/*
* if you compile this file with
* gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
* you will get a normal warning:
* printf.c:214: warning: spurious trailing `%' in format
* this line is testing an invalid % at the end of the format string.
*
* this should display (on 32bit int machine) :
*
* Hello world!
* printf test
* (null) is null pointer
* 5 = 5
* -2147483647 = - max int
* char a = 'a'
* hex ff = ff
* hex 00 = 00
* signed -3 = unsigned 4294967293 = hex fffffffd
* 0 message(s)
* 0 message(s) with %
* justif: "left "
* justif: " right"
* 3: 0003 zero padded
* 3: 3 left justif.
* 3: 3 right justif.
* -3: -003 zero padded
* -3: -3 left justif.
* -3: -3 right justif.
*/
#endif
/* To keep linker happy. */
int write( int i, char* c, int n)
{
(void)i;
(void)n;
(void)c;
return 0;
}

View File

@ -0,0 +1,78 @@
/*
* GENERATED FILE - DO NOT EDIT
* (C) Code Red Technologies Ltd, 2008-9
* Generated C linker script file for LPC1768
* (created from nxp_lpc13_c.ld (v2.0.11 (200907061347)) on Thu Jul 09 12:44:31 BST 2009)
*/
INCLUDE "rtosdemo_rdb1768_Debug_lib.ld "
INCLUDE "rtosdemo_rdb1768_Debug_mem.ld "
ENTRY(ResetISR)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
*(.rodata*)
} > FLASH
/* for exception handling/unwind - some Newlib functions (in common with C++ and STDC++) use this. */
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
_etext = .;
.data : AT (__exidx_end)
{
_data = .;
*(vtable)
*(.data*)
_edata = .;
} > SRAM
/* zero initialized data */
.bss :
{
_bss = .;
*(.bss*)
*(COMMON)
_ebss = .;
} > SRAM
/* Where we put the heap with cr_clib */
.cr_heap :
{
end = .;
_pvHeapStart = .;
} > SRAM
/*
Note: (ref: M0000066)
Moving the stack down by 16 is to work around a GDB bug.
This space can be reclaimed for Production Builds.
*/
_vStackTop = _vRamTop - 16;
.ETHRAM :
{
} > AHBRAM0
.USBRAM :
{
} > AHBRAM1
}

View File

@ -0,0 +1,8 @@
/*
* GENERATED FILE - DO NOT EDIT
* (C) Code Red Technologies Ltd, 2008-9
* Generated linker script library include file for Newlib (none)
* (created from newlib_none_c.ld (v2.0.11 (200907061347)) on Thu Jul 09 13:02:36 BST 2009)
*/
GROUP(libgcc.a libc.a)

View File

@ -0,0 +1,16 @@
/*
* GENERATED FILE - DO NOT EDIT
* (C) Code Red Technologies Ltd, 2008-9
* Generated linker script include file for
* (created from LinkMemoryTemplate (v2.0.11 (200907061347)) on Thu Jul 09 12:44:31 BST 2009)
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x0 LENGTH = 0x80000
SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000
AHBSRAM0 : ORIGIN = 0x2007c000, LENGTH = 0x4000
AHBSRAM1 : ORIGIN = 0x20080000, LENGTH = 0x4000
}
_vRamTop = 0x10000000 + 0x8000;

View File

@ -0,0 +1,82 @@
/* Don't need anything here. */
#include <stdlib.h>
#include <sys/stat.h>
int _read_r (struct _reent *r, int file, char * ptr, int len)
{
( void ) r;
( void ) file;
( void ) ptr;
( void ) len;
return -1;
}
/***************************************************************************/
int _lseek_r (struct _reent *r, int file, int ptr, int dir)
{
( void ) r;
( void ) file;
( void ) ptr;
( void ) dir;
return 0;
}
/***************************************************************************/
int _write_r (struct _reent *r, int file, char * ptr, int len)
{
( void ) r;
( void ) file;
( void ) ptr;
( void ) len;
return 0;
}
/***************************************************************************/
int _close_r (struct _reent *r, int file)
{
( void ) r;
( void ) file;
return 0;
}
/***************************************************************************/
caddr_t _sbrk_r (struct _reent *r, int incr)
{
( void ) r;
( void ) incr;
return 0;
}
/***************************************************************************/
int _fstat_r (struct _reent *r, int file, struct stat * st)
{
( void ) r;
( void ) file;
( void ) st;
return 0;
}
/***************************************************************************/
int _isatty_r(struct _reent *r, int fd)
{
( void ) r;
( void ) fd;
return 0;
}

View File

@ -0,0 +1,40 @@
/******************************************************************************
* @file: system_LPC17xx.h
* @purpose: CMSIS Cortex-M3 Device Peripheral Access Layer Header File
* for the NXP LPC17xx Device Series
* @version: V1.0
* @date: 25. Nov. 2008
*----------------------------------------------------------------------------
*
* Copyright (C) 2008 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-M3
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __SYSTEM_LPC17xx_H
#define __SYSTEM_LPC17xx_H
extern uint32_t SystemFrequency; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemFrequency variable.
*/
extern void SystemInit (void);
#endif

View File

@ -0,0 +1,111 @@
/*
* @file: EthDev.h
* @purpose: Ethernet Device Definitions
* @version: V1.10
* @date: 24. Feb. 2009
*----------------------------------------------------------------------------
*
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-M3
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
*/
#ifndef _ETHDEV__H
#define _ETHDEV__H
#ifndef NULL
#define NULL 0
#endif
/*----------------------------------------------------------------------------
Ethernet Device Defines
*----------------------------------------------------------------------------*/
#define EthDev_ADDR_SIZE 6 /*!< Ethernet Address size in bytes */
#define EthDev_MTU_SIZE 1514 /*!< Maximum Transmission Unit */
/*----------------------------------------------------------------------------
Ethernet Device Configuration and Control Command Defines
*----------------------------------------------------------------------------*/
typedef enum {
EthDev_LINK_DOWN = 0, /*!< Ethernet link not established */
EthDev_LINK_UP = 1, /*!< Ethernet link established */
} EthDev_LINK;
typedef enum {
EthDev_SPEED_10M = 0, /*!< 10.0 Mbps link speed */
EthDev_SPEED_100M = 1, /*!< 100.0 Mbps link speed */
EthDev_SPEED_1000M = 2, /*!< 1.0 Gbps link speed */
} EthDev_SPEED;
typedef enum {
EthDev_DUPLEX_HALF = 0, /*!< Link half duplex */
EthDev_DUPLEX_FULL = 1, /*!< Link full duplex */
} EthDev_DUPLEX;
typedef enum {
EthDev_MODE_AUTO = 0,
EthDev_MODE_10M_FULL = 1,
EthDev_MODE_10M_HALF = 2,
EthDev_MODE_100M_FULL = 3,
EthDev_MODE_100M_HALF = 4,
EthDev_MODE_1000M_FULL = 5,
EthDev_MODE_1000M_HALF = 6,
} EthDev_MODE;
typedef struct {
EthDev_LINK Link : 1;
EthDev_DUPLEX Duplex : 1;
EthDev_SPEED Speed : 2;
} EthDev_STATUS;
/*----------------------------------------------------------------------------
Ethernet Device IO Block Structure
*----------------------------------------------------------------------------*/
typedef struct {
/* Initialized by the user application before call to Init. */
EthDev_MODE Mode;
unsigned char HwAddr[EthDev_ADDR_SIZE];
void *(*RxFrame) (int size);
void (*RxFrameReady) (int size);
/* Initialized by Ethernet driver. */
int (*Init) (void);
int (*UnInit) (void);
int (*SetMCFilter)(int NumHwAddr, unsigned char *pHwAddr);
int (*TxFrame) (void *pData, int size);
void (*Lock) (void);
void (*UnLock) (void);
EthDev_STATUS (*LinkChk) (void);
} EthDev_IOB;
/*
* Look for received data. If data is found then uip_buf is assigned to the
* new data and the length of the data is returned. If no data is found then
* uip_buf is not updated and 0 is returned.
*/
unsigned long ulGetEMACRxData( void );
/*
* Send usTxDataLen bytes from uip_buf.
*/
void vSendEMACTxData( unsigned short usTxDataLen );
/*
* Prepare the Ethernet hardware ready for TCP/IP comms.
*/
long lEMACInit(void);
#endif

View File

@ -0,0 +1,331 @@
/*
* @file: EthDev_LPC17xx.h
* @purpose: Ethernet Device Definitions for NXP LPC17xx
* @version: V0.01
* @date: 14. May 2009
*----------------------------------------------------------------------------
*
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-M3
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
*/
#ifndef __ETHDEV_LPC17XX_H
#define __ETHDEV_LPC17XX_H
#include <stdint.h>
/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */
#define NUM_RX_FRAG 3 /* Num.of RX Fragments. */
#define NUM_TX_FRAG 2 /* Num.of TX Fragments. */
#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */
#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */
typedef struct { /* RX Descriptor struct */
uint32_t Packet;
uint32_t Ctrl;
} RX_DESC_TypeDef;
typedef struct { /* RX Status struct */
uint32_t Info;
uint32_t HashCRC;
} RX_STAT_TypeDef;
typedef struct { /* TX Descriptor struct */
uint32_t Packet;
uint32_t Ctrl;
} TX_DESC_TypeDef;
typedef struct { /* TX Status struct */
uint32_t Info;
} TX_STAT_TypeDef;
/* EMAC variables located in AHB SRAM bank 1*/
#define AHB_SRAM_BANK1_BASE 0x2007c000UL
#define RX_DESC_BASE (AHB_SRAM_BANK1_BASE )
#define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_DESC_TypeDef */
#define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_STAT_TypeDef */
#define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*(2*4)) /* 2 * uint32_t, see TX_DESC_TypeDef */
#define ETH_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*(1*4)) /* 1 * uint32_t, see TX_STAT_TypeDef */
/* RX and TX descriptor and status definitions. */
#define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i))
#define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i))
#define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i))
#define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i))
#define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i))
#define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i))
#define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i))
#define ETH_BUF(i) ( ETH_BUF_BASE + ETH_FRAG_SIZE*i )
#define ETH_NUM_BUFFERS ( NUM_TX_FRAG + NUM_RX_FRAG + 1 ) /* There are in fact 2 more buffers than descriptors as the two Tx descriptors use the same buffer to speed up the uip Tx. */
/* MAC Configuration Register 1 */
#define MAC1_REC_EN 0x00000001 /* Receive Enable */
#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */
#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */
#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */
#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */
#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */
#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */
#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */
#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */
#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */
#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */
/* MAC Configuration Register 2 */
#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */
#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */
#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */
#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */
#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */
#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */
#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */
#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */
#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */
#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */
#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */
#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */
#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */
/* Back-to-Back Inter-Packet-Gap Register */
#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */
#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */
/* Non Back-to-Back Inter-Packet-Gap Register */
#define IPGR_DEF 0x00000012 /* Recommended value */
/* Collision Window/Retry Register */
#define CLRT_DEF 0x0000370F /* Default value */
/* PHY Support Register */
#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */
#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */
/* Test Register */
#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */
#define TEST_TST_PAUSE 0x00000002 /* Test Pause */
#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */
/* MII Management Configuration Register */
#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */
#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */
#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */
#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */
/* MII Management Command Register */
#define MCMD_READ 0x00000001 /* MII Read */
#define MCMD_SCAN 0x00000002 /* MII Scan continuously */
#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */
#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */
/* MII Management Address Register */
#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */
#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */
/* MII Management Indicators Register */
#define MIND_BUSY 0x00000001 /* MII is Busy */
#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */
#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */
#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */
/* Command Register */
#define CR_RX_EN 0x00000001 /* Enable Receive */
#define CR_TX_EN 0x00000002 /* Enable Transmit */
#define CR_REG_RES 0x00000008 /* Reset Host Registers */
#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */
#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */
#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */
#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */
#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */
#define CR_RMII 0x00000200 /* Reduced MII Interface */
#define CR_FULL_DUP 0x00000400 /* Full Duplex */
/* Status Register */
#define SR_RX_EN 0x00000001 /* Enable Receive */
#define SR_TX_EN 0x00000002 /* Enable Transmit */
/* Transmit Status Vector 0 Register */
#define TSV0_CRC_ERR 0x00000001 /* CRC error */
#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */
#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */
#define TSV0_DONE 0x00000008 /* Tramsmission Completed */
#define TSV0_MCAST 0x00000010 /* Multicast Destination */
#define TSV0_BCAST 0x00000020 /* Broadcast Destination */
#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */
#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */
#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */
#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */
#define TSV0_GIANT 0x00000400 /* Giant Frame */
#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */
#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */
#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */
#define TSV0_PAUSE 0x20000000 /* Pause Frame */
#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */
#define TSV0_VLAN 0x80000000 /* VLAN Frame */
/* Transmit Status Vector 1 Register */
#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */
#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */
/* Receive Status Vector Register */
#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */
#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */
#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */
#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */
#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */
#define RSV_CRC_ERR 0x00100000 /* CRC Error */
#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */
#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */
#define RSV_REC_OK 0x00800000 /* Frame Received OK */
#define RSV_MCAST 0x01000000 /* Multicast Frame */
#define RSV_BCAST 0x02000000 /* Broadcast Frame */
#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */
#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */
#define RSV_PAUSE 0x10000000 /* Pause Frame */
#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */
#define RSV_VLAN 0x40000000 /* VLAN Frame */
/* Flow Control Counter Register */
#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */
#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */
/* Flow Control Status Register */
#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */
/* Receive Filter Control Register */
#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */
#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */
#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */
#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */
#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/
#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */
#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */
#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */
/* Receive Filter WoL Status/Clear Registers */
#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */
#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */
#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */
#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */
#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */
#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */
#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */
#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */
/* Interrupt Status/Enable/Clear/Set Registers */
#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */
#define INT_RX_ERR 0x00000002 /* Receive Error */
#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */
#define INT_RX_DONE 0x00000008 /* Receive Done */
#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */
#define INT_TX_ERR 0x00000020 /* Transmit Error */
#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */
#define INT_TX_DONE 0x00000080 /* Transmit Done */
#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */
#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */
/* Power Down Register */
#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */
/* RX Descriptor Control Word */
#define RCTRL_SIZE 0x000007FF /* Buffer size mask */
#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */
/* RX Status Hash CRC Word */
#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */
#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */
/* RX Status Information Word */
#define RINFO_SIZE 0x000007FF /* Data size in bytes */
#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */
#define RINFO_VLAN 0x00080000 /* VLAN Frame */
#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */
#define RINFO_MCAST 0x00200000 /* Multicast Frame */
#define RINFO_BCAST 0x00400000 /* Broadcast Frame */
#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */
#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */
#define RINFO_LEN_ERR 0x02000000 /* Length Error */
#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */
#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */
#define RINFO_OVERRUN 0x10000000 /* Receive overrun */
#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */
#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */
#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */
#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | \
RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN)
/* TX Descriptor Control Word */
#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */
#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */
#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */
#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */
#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */
#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */
#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */
/* TX Status Information Word */
#define TINFO_COL_CNT 0x01E00000 /* Collision Count */
#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */
#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */
#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */
#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */
#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */
#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */
#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */
/* ENET Device Revision ID */
#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */
/* DP83848C PHY Registers */
#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */
#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */
#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */
#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */
#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */
#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */
#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */
#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */
/* PHY Extended Registers */
#define PHY_REG_STS 0x10 /* Status Register */
#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */
#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */
#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */
#define PHY_REG_RECR 0x15 /* Receive Error Counter */
#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */
#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */
#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */
#define PHY_REG_PHYCR 0x19 /* PHY Control Register */
#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */
#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */
#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */
#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */
#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */
#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */
#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */
#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */
#define PHY_AUTO_NEG_COMPLETE 0x0020 /* Auto negotiation have finished. */
#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */
#define DP83848C_ID 0x20005C90 /* PHY Identifier */
#endif
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2006, 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 uIP TCP/IP stack
*
* $Id: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $
*/
#ifndef __CLOCK_ARCH_H__
#define __CLOCK_ARCH_H__
#include "FreeRTOS.h"
typedef unsigned long clock_time_t;
#define CLOCK_CONF_SECOND configTICK_RATE_HZ
#endif /* __CLOCK_ARCH_H__ */

View File

@ -0,0 +1,88 @@
/**
* \defgroup clock Clock interface
*
* The clock interface is the interface between the \ref timer "timer library"
* and the platform specific clock functionality. The clock
* interface must be implemented for each platform that uses the \ref
* timer "timer library".
*
* The clock interface does only one this: it measures time. The clock
* interface provides a macro, CLOCK_SECOND, which corresponds to one
* second of system time.
*
* \sa \ref timer "Timer library"
*
* @{
*/
/*
* Copyright (c) 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. 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 uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $
*/
#ifndef __CLOCK_H__
#define __CLOCK_H__
#include "clock-arch.h"
/**
* Initialize the clock library.
*
* This function initializes the clock library and should be called
* from the main() function of the system.
*
*/
void clock_init(void);
/**
* Get the current clock time.
*
* This function returns the current system clock time.
*
* \return The current clock time, measured in system ticks.
*/
clock_time_t clock_time(void);
/**
* A second, measured in system clock time.
*
* \hideinitializer
*/
#ifdef CLOCK_CONF_SECOND
#define CLOCK_SECOND CLOCK_CONF_SECOND
#else
#define CLOCK_SECOND (clock_time_t)32
#endif
#endif /* __CLOCK_H__ */
/** @} */

View File

@ -0,0 +1,602 @@
/*
FreeRTOS.org V5.4.0 - Copyright (C) 2003-2009 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org 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 exception to the GPL is included to allow you to distribute a
combined work that includes FreeRTOS.org without being obliged to provide
the source code for any proprietary components. Alternative commercial
license and support terms are also available upon request. See the
licensing section of http://www.FreeRTOS.org for full details.
FreeRTOS.org 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 along
with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
* *
* This is a concise, step by step, 'hands on' guide that describes both *
* general multitasking concepts and FreeRTOS specifics. It presents and *
* explains numerous examples that are written using the FreeRTOS API. *
* Full source code for all the examples is provided in an accompanying *
* .zip file. *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
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.
*/
/* Originally adapted from file written by Andreas Dannenberg. Supplied with permission. */
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* Hardware specific includes. */
#include "EthDev_LPC17xx.h"
/* Time to wait between each inspection of the link status. */
#define emacWAIT_FOR_LINK_TO_ESTABLISH ( 500 / portTICK_RATE_MS )
/* Short delay used in several places during the initialisation process. */
#define emacSHORT_DELAY ( 2 )
/* Hardware specific bit definitions. */
#define emacLINK_ESTABLISHED ( 0x0001 )
#define emacFULL_DUPLEX_ENABLED ( 0x0004 )
#define emac10BASE_T_MODE ( 0x0002 )
#define emacPINSEL2_VALUE 0x50150105
/* If no buffers are available, then wait this long before looking again.... */
#define emacBUFFER_WAIT_DELAY ( 3 / portTICK_RATE_MS )
/* ...and don't look more than this many times. */
#define emacBUFFER_WAIT_ATTEMPTS ( 30 )
/* Index to the Tx descriptor that is always used first for every Tx. The second
descriptor is then used to re-send in order to speed up the uIP Tx process. */
#define emacTX_DESC_INDEX ( 0 )
/*-----------------------------------------------------------*/
/*
* Configure both the Rx and Tx descriptors during the init process.
*/
static void prvInitDescriptors( void );
/*
* Setup the IO and peripherals required for Ethernet communication.
*/
static void prvSetupEMACHardware( void );
/*
* Control the auto negotiate process.
*/
static void prvConfigurePHY( void );
/*
* Wait for a link to be established, then setup the PHY according to the link
* parameters.
*/
static long prvSetupLinkStatus( void );
/*
* Search the pool of buffers to find one that is free. If a buffer is found
* mark it as in use before returning its address.
*/
static unsigned char *prvGetNextBuffer( void );
/*
* Return an allocated buffer to the pool of free buffers.
*/
static void prvReturnBuffer( unsigned char *pucBuffer );
/*
* Send lValue to the lPhyReg within the PHY.
*/
static long prvWritePHY( long lPhyReg, long lValue );
/*
* Read a value from ucPhyReg within the PHY. *plStatus will be set to
* pdFALSE if there is an error.
*/
static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus );
/*-----------------------------------------------------------*/
/* The semaphore used to wake the uIP task when data arrives. */
extern xSemaphoreHandle xEMACSemaphore;
/* Each ucBufferInUse index corresponds to a position in the pool of buffers.
If the index contains a 1 then the buffer within pool is in use, if it
contains a 0 then the buffer is free. */
static unsigned char ucBufferInUse[ ETH_NUM_BUFFERS ] = { pdFALSE };
/* The uip_buffer is not a fixed array, but instead gets pointed to the buffers
allocated within this file. */
unsigned char * uip_buf;
/* Store the length of the data being sent so the data can be sent twice. The
value will be set back to 0 once the data has been sent twice. */
static unsigned short usSendLen = 0;
/*-----------------------------------------------------------*/
long lEMACInit( void )
{
long lReturn = pdPASS;
unsigned long ulID1, ulID2;
/* Reset peripherals, configure port pins and registers. */
prvSetupEMACHardware();
/* Check the PHY part number is as expected. */
ulID1 = prvReadPHY( PHY_REG_IDR1, &lReturn );
ulID2 = prvReadPHY( PHY_REG_IDR2, &lReturn );
if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) == DP83848C_ID )
{
/* Set the Ethernet MAC Address registers */
EMAC->SA0 = ( configMAC_ADDR0 << 8 ) | configMAC_ADDR1;
EMAC->SA1 = ( configMAC_ADDR2 << 8 ) | configMAC_ADDR3;
EMAC->SA2 = ( configMAC_ADDR4 << 8 ) | configMAC_ADDR5;
/* Initialize Tx and Rx DMA Descriptors */
prvInitDescriptors();
/* Receive broadcast and perfect match packets */
EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;
/* Setup the PHY. */
prvConfigurePHY();
}
else
{
lReturn = pdFAIL;
}
/* Check the link status. */
if( lReturn == pdPASS )
{
lReturn = prvSetupLinkStatus();
}
if( lReturn == pdPASS )
{
/* Initialise uip_buf to ensure it points somewhere valid. */
uip_buf = prvGetNextBuffer();
/* Reset all interrupts */
EMAC->IntClear = ( INT_RX_OVERRUN | INT_RX_ERR | INT_RX_FIN | INT_RX_DONE | INT_TX_UNDERRUN | INT_TX_ERR | INT_TX_FIN | INT_TX_DONE | INT_SOFT_INT | INT_WAKEUP );
/* Enable receive and transmit mode of MAC Ethernet core */
EMAC->Command |= ( CR_RX_EN | CR_TX_EN );
EMAC->MAC1 |= MAC1_REC_EN;
}
return lReturn;
}
/*-----------------------------------------------------------*/
static unsigned char *prvGetNextBuffer( void )
{
long x;
unsigned char *pucReturn = NULL;
unsigned long ulAttempts = 0;
while( pucReturn == NULL )
{
/* Look through the buffers to find one that is not in use by
anything else. */
for( x = 0; x < ETH_NUM_BUFFERS; x++ )
{
if( ucBufferInUse[ x ] == pdFALSE )
{
ucBufferInUse[ x ] = pdTRUE;
pucReturn = ( unsigned char * ) ETH_BUF( x );
break;
}
}
/* Was a buffer found? */
if( pucReturn == NULL )
{
ulAttempts++;
if( ulAttempts >= emacBUFFER_WAIT_ATTEMPTS )
{
break;
}
/* Wait then look again. */
vTaskDelay( emacBUFFER_WAIT_DELAY );
}
}
return pucReturn;
}
/*-----------------------------------------------------------*/
static void prvInitDescriptors( void )
{
long x, lNextBuffer = 0;
for( x = 0; x < NUM_RX_FRAG; x++ )
{
/* Allocate the next Ethernet buffer to this descriptor. */
RX_DESC_PACKET( x ) = ETH_BUF( lNextBuffer );
RX_DESC_CTRL( x ) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 );
RX_STAT_INFO( x ) = 0;
RX_STAT_HASHCRC( x ) = 0;
/* The Ethernet buffer is now in use. */
ucBufferInUse[ lNextBuffer ] = pdTRUE;
lNextBuffer++;
}
/* Set EMAC Receive Descriptor Registers. */
EMAC->RxDescriptor = RX_DESC_BASE;
EMAC->RxStatus = RX_STAT_BASE;
EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1;
/* Rx Descriptors Point to 0 */
EMAC->RxConsumeIndex = 0;
/* A buffer is not allocated to the Tx descriptors until they are actually
used. */
for( x = 0; x < NUM_TX_FRAG; x++ )
{
TX_DESC_PACKET( x ) = ( unsigned long ) NULL;
TX_DESC_CTRL( x ) = 0;
TX_STAT_INFO( x ) = 0;
}
/* Set EMAC Transmit Descriptor Registers. */
EMAC->TxDescriptor = TX_DESC_BASE;
EMAC->TxStatus = TX_STAT_BASE;
EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1;
/* Tx Descriptors Point to 0 */
EMAC->TxProduceIndex = 0;
}
/*-----------------------------------------------------------*/
static void prvSetupEMACHardware( void )
{
unsigned short us;
long x, lDummy;
/* Enable P1 Ethernet Pins. */
PINCON->PINSEL2 = emacPINSEL2_VALUE;
PINCON->PINSEL3 = ( PINCON->PINSEL3 & ~0x0000000F ) | 0x00000005;
/* Power Up the EMAC controller. */
SC->PCONP |= PCONP_PCENET;
vTaskDelay( emacSHORT_DELAY );
/* Reset all EMAC internal modules. */
EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;
EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;
/* A short delay after reset. */
vTaskDelay( emacSHORT_DELAY );
/* Initialize MAC control registers. */
EMAC->MAC1 = MAC1_PASS_ALL;
EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
EMAC->MAXF = ETH_MAX_FLEN;
EMAC->CLRT = CLRT_DEF;
EMAC->IPGR = IPGR_DEF;
/* Enable Reduced MII interface. */
EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM;
/* Reset Reduced MII Logic. */
EMAC->SUPP = SUPP_RES_RMII;
vTaskDelay( emacSHORT_DELAY );
EMAC->SUPP = 0;
/* Put the PHY in reset mode */
prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII );
prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII );
/* Wait for hardware reset to end. */
for( x = 0; x < 100; x++ )
{
vTaskDelay( emacSHORT_DELAY * 5 );
us = prvReadPHY( PHY_REG_BMCR, &lDummy );
if( !( us & MCFG_RES_MII ) )
{
/* Reset complete */
break;
}
}
}
/*-----------------------------------------------------------*/
static void prvConfigurePHY( void )
{
unsigned short us;
long x, lDummy;
/* Auto negotiate the configuration. */
if( prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) )
{
vTaskDelay( emacSHORT_DELAY * 5 );
for( x = 0; x < 10; x++ )
{
us = prvReadPHY( PHY_REG_BMSR, &lDummy );
if( us & PHY_AUTO_NEG_COMPLETE )
{
break;
}
vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH );
}
}
}
/*-----------------------------------------------------------*/
static long prvSetupLinkStatus( void )
{
long lReturn = pdFAIL, x;
unsigned short usLinkStatus;
/* Wait with timeout for the link to be established. */
for( x = 0; x < 10; x++ )
{
usLinkStatus = prvReadPHY( PHY_REG_STS, &lReturn );
if( usLinkStatus & emacLINK_ESTABLISHED )
{
/* Link is established. */
lReturn = pdPASS;
break;
}
vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH );
}
if( lReturn == pdPASS )
{
/* Configure Full/Half Duplex mode. */
if( usLinkStatus & emacFULL_DUPLEX_ENABLED )
{
/* Full duplex is enabled. */
EMAC->MAC2 |= MAC2_FULL_DUP;
EMAC->Command |= CR_FULL_DUP;
EMAC->IPGT = IPGT_FULL_DUP;
}
else
{
/* Half duplex mode. */
EMAC->IPGT = IPGT_HALF_DUP;
}
/* Configure 100MBit/10MBit mode. */
if( usLinkStatus & emac10BASE_T_MODE )
{
/* 10MBit mode. */
EMAC->SUPP = 0;
}
else
{
/* 100MBit mode. */
EMAC->SUPP = SUPP_SPEED;
}
}
return lReturn;
}
/*-----------------------------------------------------------*/
static void prvReturnBuffer( unsigned char *pucBuffer )
{
unsigned long ul;
/* Return a buffer to the pool of free buffers. */
for( ul = 0; ul < ETH_NUM_BUFFERS; ul++ )
{
if( ETH_BUF( ul ) == ( unsigned long ) pucBuffer )
{
ucBufferInUse[ ul ] = pdFALSE;
break;
}
}
}
/*-----------------------------------------------------------*/
unsigned long ulGetEMACRxData( void )
{
unsigned long ulLen = 0;
long lIndex;
if( EMAC->RxProduceIndex != EMAC->RxConsumeIndex )
{
/* Mark the current buffer as free as uip_buf is going to be set to
the buffer that contains the received data. */
prvReturnBuffer( uip_buf );
ulLen = ( RX_STAT_INFO( EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3;
uip_buf = ( unsigned char * ) RX_DESC_PACKET( EMAC->RxConsumeIndex );
/* Allocate a new buffer to the descriptor. */
RX_DESC_PACKET( EMAC->RxConsumeIndex ) = ( unsigned long ) prvGetNextBuffer();
/* Move the consume index onto the next position, ensuring it wraps to
the beginning at the appropriate place. */
lIndex = EMAC->RxConsumeIndex;
lIndex++;
if( lIndex >= NUM_RX_FRAG )
{
lIndex = 0;
}
EMAC->RxConsumeIndex = lIndex;
}
return ulLen;
}
/*-----------------------------------------------------------*/
void vSendEMACTxData( unsigned short usTxDataLen )
{
unsigned long ulAttempts = 0UL;
/* Check to see if the Tx descriptor is free, indicated by its buffer being
NULL. */
while( TX_DESC_PACKET( emacTX_DESC_INDEX ) != ( unsigned long ) NULL )
{
/* Wait for the Tx descriptor to become available. */
vTaskDelay( emacBUFFER_WAIT_DELAY );
ulAttempts++;
if( ulAttempts > emacBUFFER_WAIT_ATTEMPTS )
{
/* Something has gone wrong as the Tx descriptor is still in use.
Clear it down manually, the data it was sending will probably be
lost. */
prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
break;
}
}
/* Setup the Tx descriptor for transmission. Remember the length of the
data being sent so the second descriptor can be used to send it again from
within the ISR. */
usSendLen = usTxDataLen;
TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) uip_buf;
TX_DESC_CTRL( emacTX_DESC_INDEX ) = ( usTxDataLen | TCTRL_LAST | TCTRL_INT );
EMAC->TxProduceIndex = ( emacTX_DESC_INDEX + 1 );
/* uip_buf is being sent by the Tx descriptor. Allocate a new buffer. */
uip_buf = prvGetNextBuffer();
}
/*-----------------------------------------------------------*/
static long prvWritePHY( long lPhyReg, long lValue )
{
const long lMaxTime = 10;
long x;
EMAC->MADR = DP83848C_DEF_ADR | lPhyReg;
EMAC->MWTD = lValue;
x = 0;
for( x = 0; x < lMaxTime; x++ )
{
if( ( EMAC->MIND & MIND_BUSY ) == 0 )
{
/* Operation has finished. */
break;
}
vTaskDelay( emacSHORT_DELAY );
}
if( x < lMaxTime )
{
return pdPASS;
}
else
{
return pdFAIL;
}
}
/*-----------------------------------------------------------*/
static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus )
{
long x;
const long lMaxTime = 10;
EMAC->MADR = DP83848C_DEF_ADR | ucPhyReg;
EMAC->MCMD = MCMD_READ;
for( x = 0; x < lMaxTime; x++ )
{
/* Operation has finished. */
if( ( EMAC->MIND & MIND_BUSY ) == 0 )
{
break;
}
vTaskDelay( emacSHORT_DELAY );
}
EMAC->MCMD = 0;
if( x >= lMaxTime )
{
*plStatus = pdFAIL;
}
return( EMAC->MRDD );
}
/*-----------------------------------------------------------*/
void vEMAC_ISR( void )
{
unsigned long ulStatus;
long lHigherPriorityTaskWoken = pdFALSE;
ulStatus = EMAC->IntStatus;
/* Clear the interrupt. */
EMAC->IntClear = ulStatus;
if( ulStatus & INT_RX_DONE )
{
/* Ensure the uIP task is not blocked as data has arrived. */
xSemaphoreGiveFromISR( xEMACSemaphore, &lHigherPriorityTaskWoken );
}
if( ulStatus & INT_TX_DONE )
{
if( usSendLen > 0 )
{
/* Send the data again, using the second descriptor. As there are
only two descriptors the index is set back to 0. */
TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX );
TX_DESC_CTRL( ( emacTX_DESC_INDEX + 1 ) ) = ( usSendLen | TCTRL_LAST | TCTRL_INT );
EMAC->TxProduceIndex = ( emacTX_DESC_INDEX );
/* This is the second Tx so set usSendLen to 0 to indicate that the
Tx descriptors will be free again. */
usSendLen = 0UL;
}
else
{
/* The Tx buffer is no longer required. */
prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) );
TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) NULL;
}
}
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}

View File

@ -0,0 +1,35 @@
http_http "http://"
http_200 "200 "
http_301 "301 "
http_302 "302 "
http_get "GET "
http_10 "HTTP/1.0"
http_11 "HTTP/1.1"
http_content_type "content-type: "
http_texthtml "text/html"
http_location "location: "
http_host "host: "
http_crnl "\r\n"
http_index_html "/index.html"
http_404_html "/404.html"
http_referer "Referer:"
http_header_200 "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n"
http_header_404 "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n"
http_content_type_plain "Content-type: text/plain\r\n\r\n"
http_content_type_html "Content-type: text/html\r\n\r\n"
http_content_type_css "Content-type: text/css\r\n\r\n"
http_content_type_text "Content-type: text/text\r\n\r\n"
http_content_type_png "Content-type: image/png\r\n\r\n"
http_content_type_gif "Content-type: image/gif\r\n\r\n"
http_content_type_jpg "Content-type: image/jpeg\r\n\r\n"
http_content_type_binary "Content-type: application/octet-stream\r\n\r\n"
http_html ".html"
http_shtml ".shtml"
http_htm ".htm"
http_css ".css"
http_png ".png"
http_gif ".gif"
http_jpg ".jpg"
http_text ".txt"
http_txt ".txt"

View File

@ -0,0 +1,102 @@
const char http_http[8] =
/* "http://" */
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
const char http_200[5] =
/* "200 " */
{0x32, 0x30, 0x30, 0x20, };
const char http_301[5] =
/* "301 " */
{0x33, 0x30, 0x31, 0x20, };
const char http_302[5] =
/* "302 " */
{0x33, 0x30, 0x32, 0x20, };
const char http_get[5] =
/* "GET " */
{0x47, 0x45, 0x54, 0x20, };
const char http_10[9] =
/* "HTTP/1.0" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, };
const char http_11[9] =
/* "HTTP/1.1" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, };
const char http_content_type[15] =
/* "content-type: " */
{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, };
const char http_texthtml[10] =
/* "text/html" */
{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, };
const char http_location[11] =
/* "location: " */
{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, };
const char http_host[7] =
/* "host: " */
{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, };
const char http_crnl[3] =
/* "\r\n" */
{0xd, 0xa, };
const char http_index_html[12] =
/* "/index.html" */
{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_404_html[10] =
/* "/404.html" */
{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_referer[9] =
/* "Referer:" */
{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, };
const char http_header_200[84] =
/* "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
const char http_header_404[91] =
/* "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
const char http_content_type_plain[29] =
/* "Content-type: text/plain\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_html[28] =
/* "Content-type: text/html\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_css [27] =
/* "Content-type: text/css\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_text[28] =
/* "Content-type: text/text\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_png [28] =
/* "Content-type: image/png\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_gif [28] =
/* "Content-type: image/gif\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_jpg [29] =
/* "Content-type: image/jpeg\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_binary[43] =
/* "Content-type: application/octet-stream\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, };
const char http_html[6] =
/* ".html" */
{0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_shtml[7] =
/* ".shtml" */
{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, };
const char http_htm[5] =
/* ".htm" */
{0x2e, 0x68, 0x74, 0x6d, };
const char http_css[5] =
/* ".css" */
{0x2e, 0x63, 0x73, 0x73, };
const char http_png[5] =
/* ".png" */
{0x2e, 0x70, 0x6e, 0x67, };
const char http_gif[5] =
/* ".gif" */
{0x2e, 0x67, 0x69, 0x66, };
const char http_jpg[5] =
/* ".jpg" */
{0x2e, 0x6a, 0x70, 0x67, };
const char http_text[5] =
/* ".txt" */
{0x2e, 0x74, 0x78, 0x74, };
const char http_txt[5] =
/* ".txt" */
{0x2e, 0x74, 0x78, 0x74, };

View File

@ -0,0 +1,34 @@
extern const char http_http[8];
extern const char http_200[5];
extern const char http_301[5];
extern const char http_302[5];
extern const char http_get[5];
extern const char http_10[9];
extern const char http_11[9];
extern const char http_content_type[15];
extern const char http_texthtml[10];
extern const char http_location[11];
extern const char http_host[7];
extern const char http_crnl[3];
extern const char http_index_html[12];
extern const char http_404_html[10];
extern const char http_referer[9];
extern const char http_header_200[84];
extern const char http_header_404[91];
extern const char http_content_type_plain[29];
extern const char http_content_type_html[28];
extern const char http_content_type_css [27];
extern const char http_content_type_text[28];
extern const char http_content_type_png [28];
extern const char http_content_type_gif [28];
extern const char http_content_type_jpg [29];
extern const char http_content_type_binary[43];
extern const char http_html[6];
extern const char http_shtml[7];
extern const char http_htm[5];
extern const char http_css[5];
extern const char http_png[5];
extern const char http_gif[5];
extern const char http_jpg[5];
extern const char http_text[5];
extern const char http_txt[5];

View File

@ -0,0 +1,304 @@
/**
* \addtogroup httpd
* @{
*/
/**
* \file
* Web server script interface
* \author
* Adam Dunkels <adam@sics.se>
*
*/
/*
* Copyright (c) 2001-2006, Adam Dunkels.
* 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 uIP TCP/IP stack.
*
* $Id: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $
*
*/
#include "uip.h"
#include "psock.h"
#include "httpd.h"
#include "httpd-cgi.h"
#include "httpd-fs.h"
#include <stdio.h>
#include <string.h>
HTTPD_CGI_CALL(file, "file-stats", file_stats);
HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats);
HTTPD_CGI_CALL(net, "net-stats", net_stats);
HTTPD_CGI_CALL(rtos, "rtos-stats", rtos_stats );
HTTPD_CGI_CALL(run, "run-time", run_time );
HTTPD_CGI_CALL(io, "led-io", led_io );
static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, &rtos, &run, &io, NULL };
/*---------------------------------------------------------------------------*/
static
PT_THREAD(nullfunction(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
( void ) ptr;
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
httpd_cgifunction
httpd_cgi(char *name)
{
const struct httpd_cgi_call **f;
/* Find the matching name in the table, return the function. */
for(f = calls; *f != NULL; ++f) {
if(strncmp((*f)->name, name, strlen((*f)->name)) == 0) {
return (*f)->function;
}
}
return nullfunction;
}
/*---------------------------------------------------------------------------*/
static unsigned short
generate_file_stats(void *arg)
{
char *f = (char *)arg;
return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f));
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(file_stats(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1);
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static const char closed[] = /* "CLOSED",*/
{0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0};
static const char syn_rcvd[] = /* "SYN-RCVD",*/
{0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56,
0x44, 0};
static const char syn_sent[] = /* "SYN-SENT",*/
{0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e,
0x54, 0};
static const char established[] = /* "ESTABLISHED",*/
{0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48,
0x45, 0x44, 0};
static const char fin_wait_1[] = /* "FIN-WAIT-1",*/
{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
0x54, 0x2d, 0x31, 0};
static const char fin_wait_2[] = /* "FIN-WAIT-2",*/
{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
0x54, 0x2d, 0x32, 0};
static const char closing[] = /* "CLOSING",*/
{0x43, 0x4c, 0x4f, 0x53, 0x49,
0x4e, 0x47, 0};
static const char time_wait[] = /* "TIME-WAIT,"*/
{0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41,
0x49, 0x54, 0};
static const char last_ack[] = /* "LAST-ACK"*/
{0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43,
0x4b, 0};
static const char *states[] = {
closed,
syn_rcvd,
syn_sent,
established,
fin_wait_1,
fin_wait_2,
closing,
time_wait,
last_ack};
static unsigned short
generate_tcp_stats(void *arg)
{
struct uip_conn *conn;
struct httpd_state *s = (struct httpd_state *)arg;
conn = &uip_conns[s->count];
return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
"<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n",
htons(conn->lport),
htons(conn->ripaddr[0]) >> 8,
htons(conn->ripaddr[0]) & 0xff,
htons(conn->ripaddr[1]) >> 8,
htons(conn->ripaddr[1]) & 0xff,
htons(conn->rport),
states[conn->tcpstateflags & UIP_TS_MASK],
conn->nrtx,
conn->timer,
(uip_outstanding(conn))? '*':' ',
(uip_stopped(conn))? '!':' ');
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
( void ) ptr;
for(s->count = 0; s->count < UIP_CONNS; ++s->count) {
if((uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {
PSOCK_GENERATOR_SEND(&s->sout, generate_tcp_stats, s);
}
}
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static unsigned short
generate_net_stats(void *arg)
{
struct httpd_state *s = (struct httpd_state *)arg;
return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
"%5u\n", ((uip_stats_t *)&uip_stat)[s->count]);
}
static
PT_THREAD(net_stats(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
( void ) ptr;
#if UIP_STATISTICS
for(s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t);
++s->count) {
PSOCK_GENERATOR_SEND(&s->sout, generate_net_stats, s);
}
#endif /* UIP_STATISTICS */
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
extern void vTaskList( signed char *pcWriteBuffer );
extern char *pcGetTaskStatusMessage( void );
static char cCountBuf[ 128 ];
long lRefreshCount = 0;
static unsigned short
generate_rtos_stats(void *arg)
{
( void ) arg;
lRefreshCount++;
sprintf( cCountBuf, "<p><br>Refresh count = %d<p><br>%s", (int)lRefreshCount, pcGetTaskStatusMessage() );
vTaskList( uip_appdata );
strcat( uip_appdata, cCountBuf );
return strlen( uip_appdata );
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(rtos_stats(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
( void ) ptr;
PSOCK_GENERATOR_SEND(&s->sout, generate_rtos_stats, NULL);
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
char *pcStatus;
unsigned long ulString;
static unsigned short generate_io_state( void *arg )
{
extern long uxParTextGetLED( unsigned long ulLED );
const unsigned long ulLEDNo = 3;
( void ) arg;
if( uxParTextGetLED( ulLEDNo ) == 0 )
{
pcStatus = "";
}
else
{
pcStatus = "checked";
}
sprintf( uip_appdata,
"<input type=\"checkbox\" name=\"LED0\" value=\"1\" %s>LED<p><p>", pcStatus );
return strlen( uip_appdata );
}
/*---------------------------------------------------------------------------*/
extern void vTaskGetRunTimeStats( signed char *pcWriteBuffer );
static unsigned short
generate_runtime_stats(void *arg)
{
( void ) arg;
lRefreshCount++;
sprintf( cCountBuf, "<p><br>Refresh count = %d", (int)lRefreshCount );
vTaskGetRunTimeStats( uip_appdata );
strcat( uip_appdata, cCountBuf );
return strlen( uip_appdata );
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(run_time(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
( void ) ptr;
PSOCK_GENERATOR_SEND(&s->sout, generate_runtime_stats, NULL);
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static PT_THREAD(led_io(struct httpd_state *s, char *ptr))
{
PSOCK_BEGIN(&s->sout);
( void ) ptr;
PSOCK_GENERATOR_SEND(&s->sout, generate_io_state, NULL);
PSOCK_END(&s->sout);
}
/** @} */

View File

@ -0,0 +1,84 @@
/**
* \addtogroup httpd
* @{
*/
/**
* \file
* Web server script interface header file
* \author
* Adam Dunkels <adam@sics.se>
*
*/
/*
* Copyright (c) 2001, Adam Dunkels.
* 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 uIP TCP/IP stack.
*
* $Id: httpd-cgi.h,v 1.2 2006/06/11 21:46:38 adam Exp $
*
*/
#ifndef __HTTPD_CGI_H__
#define __HTTPD_CGI_H__
#include "psock.h"
#include "httpd.h"
typedef PT_THREAD((* httpd_cgifunction)(struct httpd_state *, char *));
httpd_cgifunction httpd_cgi(char *name);
struct httpd_cgi_call {
const char *name;
const httpd_cgifunction function;
};
/**
* \brief HTTPD CGI function declaration
* \param name The C variable name of the function
* \param str The string name of the function, used in the script file
* \param function A pointer to the function that implements it
*
* This macro is used for declaring a HTTPD CGI
* function. This function is then added to the list of
* HTTPD CGI functions with the httpd_cgi_add() function.
*
* \hideinitializer
*/
#define HTTPD_CGI_CALL(name, str, function) \
static PT_THREAD(function(struct httpd_state *, char *)); \
static const struct httpd_cgi_call name = {str, function}
void httpd_cgi_init(void);
#endif /* __HTTPD_CGI_H__ */
/** @} */

View File

@ -0,0 +1,132 @@
/*
* 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>
*
* $Id: httpd-fs.c,v 1.1 2006/06/07 09:13:08 adam Exp $
*/
#include "httpd.h"
#include "httpd-fs.h"
#include "httpd-fsdata.h"
#ifndef NULL
#define NULL 0
#endif /* NULL */
#include "httpd-fsdata.c"
#if HTTPD_FS_STATISTICS
static u16_t count[HTTPD_FS_NUMFILES];
#endif /* HTTPD_FS_STATISTICS */
/*-----------------------------------------------------------------------------------*/
static u8_t
httpd_fs_strcmp(const char *str1, const char *str2)
{
u8_t i;
i = 0;
loop:
if(str2[i] == 0 ||
str1[i] == '\r' ||
str1[i] == '\n') {
return 0;
}
if(str1[i] != str2[i]) {
return 1;
}
++i;
goto loop;
}
/*-----------------------------------------------------------------------------------*/
int
httpd_fs_open(const char *name, struct httpd_fs_file *file)
{
#if HTTPD_FS_STATISTICS
u16_t i = 0;
#endif /* HTTPD_FS_STATISTICS */
struct httpd_fsdata_file_noconst *f;
for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;
f != NULL;
f = (struct httpd_fsdata_file_noconst *)f->next) {
if(httpd_fs_strcmp(name, f->name) == 0) {
file->data = f->data;
file->len = f->len;
#if HTTPD_FS_STATISTICS
++count[i];
#endif /* HTTPD_FS_STATISTICS */
return 1;
}
#if HTTPD_FS_STATISTICS
++i;
#endif /* HTTPD_FS_STATISTICS */
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
void
httpd_fs_init(void)
{
#if HTTPD_FS_STATISTICS
u16_t i;
for(i = 0; i < HTTPD_FS_NUMFILES; i++) {
count[i] = 0;
}
#endif /* HTTPD_FS_STATISTICS */
}
/*-----------------------------------------------------------------------------------*/
#if HTTPD_FS_STATISTICS
u16_t httpd_fs_count
(char *name)
{
struct httpd_fsdata_file_noconst *f;
u16_t i;
i = 0;
for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;
f != NULL;
f = (struct httpd_fsdata_file_noconst *)f->next) {
if(httpd_fs_strcmp(name, f->name) == 0) {
return count[i];
}
++i;
}
return 0;
}
#endif /* HTTPD_FS_STATISTICS */
/*-----------------------------------------------------------------------------------*/

View File

@ -0,0 +1,57 @@
/*
* 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>
*
* $Id: httpd-fs.h,v 1.1 2006/06/07 09:13:08 adam Exp $
*/
#ifndef __HTTPD_FS_H__
#define __HTTPD_FS_H__
#define HTTPD_FS_STATISTICS 1
struct httpd_fs_file {
char *data;
int len;
};
/* file must be allocated by caller and will be filled in
by the function. */
int httpd_fs_open(const char *name, struct httpd_fs_file *file);
#ifdef HTTPD_FS_STATISTICS
#if HTTPD_FS_STATISTICS == 1
u16_t httpd_fs_count(char *name);
#endif /* HTTPD_FS_STATISTICS */
#endif /* HTTPD_FS_STATISTICS */
void httpd_fs_init(void);
#endif /* __HTTPD_FS_H__ */

View File

@ -0,0 +1,8 @@
<html>
<body bgcolor="white">
<center>
<h1>404 - file not found</h1>
<h3>Go <a href="/">here</a> instead.</h3>
</center>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org uIP WEB server demo</title>
</head>
<BODY onLoad="window.setTimeout(&quot;location.href='index.shtml'&quot;,100)">
<font face="arial">
Loading index.shtml. Click <a href="index.shtml">here</a> if not automatically redirected.
</font>
</font>
</body>
</html>

View File

@ -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 uIP 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="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS.org Homepage</a> <b>|</b> <a href="io.shtml">IO</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>

View File

@ -0,0 +1,28 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org uIP WEB server demo</title>
</head>
<BODY>
<font face="arial">
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS.org Homepage</a> <b>|</b> <a href="io.shtml">IO</a>
<br><p>
<hr>
<b>LED and LCD IO</b><br>
<p>
Use the check box to turn on or off the LED, enter text to display on the OLED display, then click "Update IO".
<p>
<form name="aForm" action="/io.shtml" method="get">
%! led-io
<p>
<input type="submit" value="Update IO">
</form>
<br><p>
</font>
</body>
</html>

View File

@ -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 uIP 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="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS.org Homepage</a> <b>|</b> <a href="io.shtml">IO</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-time
</pre></font>
</font>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org uIP WEB server demo</title>
</head>
<BODY>
<font face="arial">
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS.org Homepage</a> <b>|</b> <a href="io.shtml">IO</a>
<br><p>
<hr>
<br><p>
<h2>Network statistics</h2>
<table width="300" border="0">
<tr><td align="left"><font face="courier"><pre>
IP Packets dropped
Packets received
Packets sent
IP errors IP version/header length
IP length, high byte
IP length, low byte
IP fragments
Header checksum
Wrong protocol
ICMP Packets dropped
Packets received
Packets sent
Type errors
TCP Packets dropped
Packets received
Packets sent
Checksum errors
Data packets without ACKs
Resets
Retransmissions
No connection avaliable
Connection attempts to closed ports
</pre></font></td><td><pre>%! net-stats
</pre></table>
</font>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org uIP WEB server demo</title>
</head>
<BODY>
<font face="arial">
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS.org Homepage</a> <b>|</b> <a href="io.shtml">IO</a>
<br><p>
<hr>
<br>
<h2>Network connections</h2>
<p>
<table>
<tr><th>Local</th><th>Remote</th><th>State</th><th>Retransmissions</th><th>Timer</th><th>Flags</th></tr>
%! tcp-connections
</pre></font>
</font>
</body>
</html>

View File

@ -0,0 +1,557 @@
static const char data_404_html[] = {
/* /404.html */
0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x20, 0x20, 0x3c,
0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c,
0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22,
0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x63, 0x65, 0x6e,
0x74, 0x65, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d,
0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20,
0x66, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e,
0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33,
0x3e, 0x47, 0x6f, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65,
0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x68, 0x65, 0x72, 0x65,
0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65,
0x61, 0x64, 0x2e, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65,
0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64,
0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
0};
static const char data_index_html[] = {
/* /index.html */
0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20,
0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49,
0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f,
0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20,
0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45,
0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72,
0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34,
0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64,
0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f,
0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42,
0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65,
0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x20, 0x6f,
0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x6e,
0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d,
0x65, 0x6f, 0x75, 0x74, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74,
0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x69, 0x6e, 0x64, 0x65,
0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x27, 0x26, 0x71,
0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x31, 0x30, 0x30, 0x29, 0x22,
0x3e, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61,
0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22,
0x3e, 0xa, 0x4c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20,
0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d,
0x6c, 0x2e, 0x20, 0x20, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x20,
0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69,
0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c,
0x22, 0x3e, 0x68, 0x65, 0x72, 0x65, 0x3c, 0x2f, 0x61, 0x3e,
0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x75,
0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c,
0x79, 0x20, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
0x65, 0x64, 0x2e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74,
0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa,
0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f,
0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0xa, 0};
static const char data_index_shtml[] = {
/* /index.shtml */
0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,
0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20,
0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49,
0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f,
0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20,
0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45,
0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72,
0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34,
0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64,
0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f,
0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42,
0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65,
0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x20, 0x6f,
0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x6e,
0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d,
0x65, 0x6f, 0x75, 0x74, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74,
0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x69, 0x6e, 0x64, 0x65,
0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x27, 0x26, 0x71,
0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x32, 0x30, 0x30, 0x30, 0x29,
0x22, 0x3e, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66,
0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c,
0x22, 0x3e, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68,
0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20,
0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20,
0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c,
0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75,
0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d,
0x6c, 0x22, 0x3e, 0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d,
0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61,
0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e,
0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22,
0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d,
0x6c, 0x22, 0x3e, 0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61,
0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e,
0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68,
0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73,
0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61,
0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e,
0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22,
0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e,
0x6f, 0x72, 0x67, 0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65,
0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48,
0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61,
0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e,
0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22,
0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e,
0x49, 0x4f, 0x3c, 0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72,
0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa,
0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68,
0x32, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x73, 0x74, 0x61,
0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68,
0x32, 0x3e, 0xa, 0x50, 0x61, 0x67, 0x65, 0x20, 0x77, 0x69,
0x6c, 0x6c, 0x20, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x32, 0x20, 0x73,
0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x2e, 0x3c, 0x70, 0x3e,
0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63,
0x65, 0x3d, 0x22, 0x63, 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72,
0x22, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0x54, 0x61, 0x73,
0x6b, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x20, 0x50, 0x72,
0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x20, 0x53, 0x74,
0x61, 0x63, 0x6b, 0x9, 0x23, 0x3c, 0x62, 0x72, 0x3e, 0x2a,
0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3c, 0x62, 0x72,
0x3e, 0xa, 0x25, 0x21, 0x20, 0x72, 0x74, 0x6f, 0x73, 0x2d,
0x73, 0x74, 0x61, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72,
0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa,
0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c, 0x2f,
0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74,
0x6d, 0x6c, 0x3e, 0xa, 0xa, 0};
static const char data_io_shtml[] = {
/* /io.shtml */
0x2f, 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,
0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20,
0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49,
0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f,
0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20,
0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45,
0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72,
0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34,
0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64,
0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f,
0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42,
0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65,
0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x3e, 0xa,
0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65,
0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xa,
0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69,
0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c,
0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61,
0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e,
0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68,
0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69,
0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e,
0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53,
0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c,
0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61,
0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e,
0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c,
0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f,
0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d,
0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c,
0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74,
0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72,
0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67,
0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f,
0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, 0x6f, 0x6d, 0x65,
0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c,
0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e,
0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c,
0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70,
0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, 0x3c, 0x62, 0x3e,
0x4c, 0x45, 0x44, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x4c, 0x43,
0x44, 0x20, 0x49, 0x4f, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x62,
0x72, 0x3e, 0xa, 0xa, 0x3c, 0x70, 0x3e, 0xa, 0xa, 0x55,
0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x65,
0x63, 0x6b, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x74, 0x6f, 0x20,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x72,
0x20, 0x6f, 0x66, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4c,
0x45, 0x44, 0x2c, 0x20, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20,
0x74, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x69,
0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x6f, 0x6e, 0x20, 0x74,
0x68, 0x65, 0x20, 0x4f, 0x4c, 0x45, 0x44, 0x20, 0x64, 0x69,
0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x65,
0x6e, 0x20, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x22, 0x55,
0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x49, 0x4f, 0x22, 0x2e,
0xa, 0xa, 0xa, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x66, 0x6f,
0x72, 0x6d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61,
0x46, 0x6f, 0x72, 0x6d, 0x22, 0x20, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x3d, 0x22, 0x2f, 0x69, 0x6f, 0x2e, 0x73, 0x68,
0x74, 0x6d, 0x6c, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f,
0x64, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, 0x3e, 0xa, 0x25,
0x21, 0x20, 0x6c, 0x65, 0x64, 0x2d, 0x69, 0x6f, 0xa, 0x3c,
0x70, 0x3e, 0xa, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20,
0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d,
0x69, 0x74, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d,
0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x49, 0x4f,
0x22, 0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e,
0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c,
0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c, 0x2f, 0x62,
0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
0x6c, 0x3e, 0xa, 0xa, 0};
static const char data_runtime_shtml[] = {
/* /runtime.shtml */
0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,
0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20,
0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49,
0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f,
0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20,
0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45,
0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72,
0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34,
0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64,
0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f,
0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42,
0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65,
0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x20, 0x6f,
0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x6e,
0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d,
0x65, 0x6f, 0x75, 0x74, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74,
0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x72, 0x75, 0x6e, 0x74,
0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x27,
0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x32, 0x30, 0x30,
0x30, 0x29, 0x22, 0x3e, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74,
0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69,
0x61, 0x6c, 0x22, 0x3e, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72,
0x65, 0x66, 0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e,
0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x61, 0x73,
0x6b, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61,
0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e,
0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22,
0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68,
0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x52, 0x75, 0x6e, 0x20, 0x54,
0x69, 0x6d, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c,
0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f,
0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68,
0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x43, 0x50, 0x20, 0x53,
0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c,
0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70,
0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x43, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c,
0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f,
0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
0x77, 0x77, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, 0x74, 0x6f,
0x73, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x22, 0x3e, 0x46, 0x72,
0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 0x72, 0x67,
0x20, 0x48, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x3c,
0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f,
0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
0x3d, 0x22, 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c,
0x22, 0x3e, 0x49, 0x4f, 0x3c, 0x2f, 0x61, 0x3e, 0xa, 0x3c,
0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, 0x72,
0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa,
0x3c, 0x68, 0x32, 0x3e, 0x52, 0x75, 0x6e, 0x2d, 0x74, 0x69,
0x6d, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74,
0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0xa, 0x50,
0x61, 0x67, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x72,
0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x20, 0x65, 0x76, 0x65,
0x72, 0x79, 0x20, 0x32, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e,
0x64, 0x73, 0x2e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x66, 0x6f,
0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x63,
0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x70,
0x72, 0x65, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41,
0x62, 0x73, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x25, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x3c,
0x62, 0x72, 0x3e, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0x2a, 0x2a, 0x2a, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x25, 0x21,
0x20, 0x72, 0x75, 0x6e, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0xa,
0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f,
0x6e, 0x74, 0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74,
0x3e, 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0xa, 0};
static const char data_stats_shtml[] = {
/* /stats.shtml */
0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,
0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20,
0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49,
0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f,
0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20,
0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45,
0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72,
0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34,
0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64,
0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f,
0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42,
0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65,
0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x3e, 0xa,
0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65,
0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xa,
0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69,
0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c,
0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61,
0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e,
0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68,
0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69,
0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e,
0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53,
0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c,
0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61,
0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e,
0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c,
0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f,
0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d,
0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c,
0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74,
0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72,
0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67,
0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f,
0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, 0x6f, 0x6d, 0x65,
0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c,
0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e,
0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c,
0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70,
0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, 0x3c, 0x62, 0x72,
0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, 0x32, 0x3e, 0x4e,
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x73, 0x74, 0x61,
0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68,
0x32, 0x3e, 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20,
0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x33, 0x30, 0x30,
0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22,
0x30, 0x22, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74,
0x64, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c,
0x65, 0x66, 0x74, 0x22, 0x3e, 0x3c, 0x66, 0x6f, 0x6e, 0x74,
0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x75,
0x72, 0x69, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x70, 0x72, 0x65,
0x3e, 0xa, 0x49, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65,
0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64,
0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64,
0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x49, 0x50, 0x20,
0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x20, 0x20, 0x20, 0x20,
0x49, 0x50, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6c, 0x65,
0x6e, 0x67, 0x74, 0x68, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50,
0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x68,
0x69, 0x67, 0x68, 0x20, 0x62, 0x79, 0x74, 0x65, 0xa, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x49, 0x50, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74,
0x68, 0x2c, 0x20, 0x6c, 0x6f, 0x77, 0x20, 0x62, 0x79, 0x74,
0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x66, 0x72,
0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xa, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x68,
0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0xa, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x63, 0x6f, 0x6c, 0xa, 0x49, 0x43, 0x4d, 0x50, 0x9,
0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65,
0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64,
0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64,
0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x54, 0x79, 0x70, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72,
0x73, 0xa, 0x54, 0x43, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65,
0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64,
0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64,
0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, 0x65,
0x72, 0x72, 0x6f, 0x72, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44,
0x61, 0x74, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20,
0x41, 0x43, 0x4b, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65,
0x73, 0x65, 0x74, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65,
0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69,
0x6f, 0x6e, 0x73, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20,
0x4e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x20, 0x61, 0x76, 0x61, 0x6c, 0x69, 0x61,
0x62, 0x6c, 0x65, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20,
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x20,
0x74, 0x6f, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x20,
0x70, 0x6f, 0x72, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72,
0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x3c,
0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x70,
0x72, 0x65, 0x3e, 0x25, 0x21, 0x20, 0x6e, 0x65, 0x74, 0x2d,
0x73, 0x74, 0x61, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72,
0x65, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e,
0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c,
0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
0x74, 0x6d, 0x6c, 0x3e, 0xa, 0};
static const char data_tcp_shtml[] = {
/* /tcp.shtml */
0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0,
0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20,
0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49,
0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f,
0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20,
0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45,
0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72,
0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34,
0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64,
0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa,
0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20,
0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f,
0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42,
0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65,
0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x3e, 0xa,
0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65,
0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xa,
0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69,
0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c,
0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61,
0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e,
0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68,
0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69,
0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e,
0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53,
0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c,
0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61,
0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e,
0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c,
0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f,
0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66,
0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d,
0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c,
0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74,
0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72,
0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67,
0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f,
0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, 0x6f, 0x6d, 0x65,
0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c,
0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61,
0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e,
0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c,
0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70,
0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, 0x3c, 0x62, 0x72,
0x3e, 0xa, 0x3c, 0x68, 0x32, 0x3e, 0x4e, 0x65, 0x74, 0x77,
0x6f, 0x72, 0x6b, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e,
0xa, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c,
0x65, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x68,
0x3e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x3c, 0x2f, 0x74, 0x68,
0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x6d, 0x6f, 0x74,
0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e,
0x53, 0x74, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e,
0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e,
0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3c,
0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, 0x69,
0x6d, 0x65, 0x72, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74,
0x68, 0x3e, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, 0x74,
0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25, 0x21,
0x20, 0x74, 0x63, 0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa, 0x3c, 0x2f, 0x70,
0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e,
0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c,
0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
0x74, 0x6d, 0x6c, 0x3e, 0xa, 0xa, 0};
const struct httpd_fsdata_file file_404_html[] = {{NULL, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10, 0}};
const struct httpd_fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12, 0}};
const struct httpd_fsdata_file file_index_shtml[] = {{file_index_html, data_index_shtml, data_index_shtml + 13, sizeof(data_index_shtml) - 13, 0}};
const struct httpd_fsdata_file file_io_shtml[] = {{file_index_shtml, data_io_shtml, data_io_shtml + 10, sizeof(data_io_shtml) - 10, 0}};
const struct httpd_fsdata_file file_runtime_shtml[] = {{file_io_shtml, data_runtime_shtml, data_runtime_shtml + 15, sizeof(data_runtime_shtml) - 15, 0}};
const struct httpd_fsdata_file file_stats_shtml[] = {{file_runtime_shtml, data_stats_shtml, data_stats_shtml + 13, sizeof(data_stats_shtml) - 13, 0}};
const struct httpd_fsdata_file file_tcp_shtml[] = {{file_stats_shtml, data_tcp_shtml, data_tcp_shtml + 11, sizeof(data_tcp_shtml) - 11, 0}};
#define HTTPD_FS_ROOT file_tcp_shtml
#define HTTPD_FS_NUMFILES 7

View File

@ -0,0 +1,64 @@
/*
* 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>
*
* $Id: httpd-fsdata.h,v 1.1 2006/06/07 09:13:08 adam Exp $
*/
#ifndef __HTTPD_FSDATA_H__
#define __HTTPD_FSDATA_H__
#include "uip.h"
struct httpd_fsdata_file {
const struct httpd_fsdata_file *next;
const char *name;
const char *data;
const int len;
#ifdef HTTPD_FS_STATISTICS
#if HTTPD_FS_STATISTICS == 1
u16_t count;
#endif /* HTTPD_FS_STATISTICS */
#endif /* HTTPD_FS_STATISTICS */
};
struct httpd_fsdata_file_noconst {
struct httpd_fsdata_file *next;
char *name;
char *data;
int len;
#ifdef HTTPD_FS_STATISTICS
#if HTTPD_FS_STATISTICS == 1
u16_t count;
#endif /* HTTPD_FS_STATISTICS */
#endif /* HTTPD_FS_STATISTICS */
};
#endif /* __HTTPD_FSDATA_H__ */

View File

@ -0,0 +1,346 @@
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup httpd Web server
* @{
* The uIP web server is a very simplistic implementation of an HTTP
* server. It can serve web pages and files from a read-only ROM
* filesystem, and provides a very small scripting language.
*/
/**
* \file
* Web server
* \author
* Adam Dunkels <adam@sics.se>
*/
/*
* Copyright (c) 2004, Adam Dunkels.
* 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 uIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: httpd.c,v 1.2 2006/06/11 21:46:38 adam Exp $
*/
#include "uip.h"
#include "httpd.h"
#include "httpd-fs.h"
#include "httpd-cgi.h"
#include "http-strings.h"
#include <string.h>
#define STATE_WAITING 0
#define STATE_OUTPUT 1
#define ISO_nl 0x0a
#define ISO_space 0x20
#define ISO_bang 0x21
#define ISO_percent 0x25
#define ISO_period 0x2e
#define ISO_slash 0x2f
#define ISO_colon 0x3a
/*---------------------------------------------------------------------------*/
static unsigned short
generate_part_of_file(void *state)
{
struct httpd_state *s = (struct httpd_state *)state;
if(s->file.len > uip_mss()) {
s->len = uip_mss();
} else {
s->len = s->file.len;
}
memcpy(uip_appdata, s->file.data, s->len);
return s->len;
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_file(struct httpd_state *s))
{
PSOCK_BEGIN(&s->sout);
do {
PSOCK_GENERATOR_SEND(&s->sout, generate_part_of_file, s);
s->file.len -= s->len;
s->file.data += s->len;
} while(s->file.len > 0);
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_part_of_file(struct httpd_state *s))
{
PSOCK_BEGIN(&s->sout);
PSOCK_SEND(&s->sout, s->file.data, s->len);
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static void
next_scriptstate(struct httpd_state *s)
{
char *p;
p = strchr(s->scriptptr, ISO_nl) + 1;
s->scriptlen -= (unsigned short)(p - s->scriptptr);
s->scriptptr = p;
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_script(struct httpd_state *s))
{
char *ptr;
PT_BEGIN(&s->scriptpt);
while(s->file.len > 0) {
/* Check if we should start executing a script. */
if(*s->file.data == ISO_percent &&
*(s->file.data + 1) == ISO_bang) {
s->scriptptr = s->file.data + 3;
s->scriptlen = s->file.len - 3;
if(*(s->scriptptr - 1) == ISO_colon) {
httpd_fs_open(s->scriptptr + 1, &s->file);
PT_WAIT_THREAD(&s->scriptpt, send_file(s));
} else {
PT_WAIT_THREAD(&s->scriptpt,
httpd_cgi(s->scriptptr)(s, s->scriptptr));
}
next_scriptstate(s);
/* The script is over, so we reset the pointers and continue
sending the rest of the file. */
s->file.data = s->scriptptr;
s->file.len = s->scriptlen;
} else {
/* See if we find the start of script marker in the block of HTML
to be sent. */
if(s->file.len > uip_mss()) {
s->len = uip_mss();
} else {
s->len = s->file.len;
}
if(*s->file.data == ISO_percent) {
ptr = strchr(s->file.data + 1, ISO_percent);
} else {
ptr = strchr(s->file.data, ISO_percent);
}
if(ptr != NULL &&
ptr != s->file.data) {
s->len = (int)(ptr - s->file.data);
if(s->len >= uip_mss()) {
s->len = uip_mss();
}
}
PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s));
s->file.data += s->len;
s->file.len -= s->len;
}
}
PT_END(&s->scriptpt);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr))
{
char *ptr;
PSOCK_BEGIN(&s->sout);
PSOCK_SEND_STR(&s->sout, statushdr);
ptr = strrchr(s->filename, ISO_period);
if(ptr == NULL) {
PSOCK_SEND_STR(&s->sout, http_content_type_binary);
} else if(strncmp(http_html, ptr, 5) == 0 ||
strncmp(http_shtml, ptr, 6) == 0) {
PSOCK_SEND_STR(&s->sout, http_content_type_html);
} else if(strncmp(http_css, ptr, 4) == 0) {
PSOCK_SEND_STR(&s->sout, http_content_type_css);
} else if(strncmp(http_png, ptr, 4) == 0) {
PSOCK_SEND_STR(&s->sout, http_content_type_png);
} else if(strncmp(http_gif, ptr, 4) == 0) {
PSOCK_SEND_STR(&s->sout, http_content_type_gif);
} else if(strncmp(http_jpg, ptr, 4) == 0) {
PSOCK_SEND_STR(&s->sout, http_content_type_jpg);
} else {
PSOCK_SEND_STR(&s->sout, http_content_type_plain);
}
PSOCK_END(&s->sout);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_output(struct httpd_state *s))
{
char *ptr;
PT_BEGIN(&s->outputpt);
if(!httpd_fs_open(s->filename, &s->file)) {
httpd_fs_open(http_404_html, &s->file);
strcpy(s->filename, http_404_html);
PT_WAIT_THREAD(&s->outputpt,
send_headers(s,
http_header_404));
PT_WAIT_THREAD(&s->outputpt,
send_file(s));
} else {
PT_WAIT_THREAD(&s->outputpt,
send_headers(s,
http_header_200));
ptr = strchr(s->filename, ISO_period);
if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0) {
PT_INIT(&s->scriptpt);
PT_WAIT_THREAD(&s->outputpt, handle_script(s));
} else {
PT_WAIT_THREAD(&s->outputpt,
send_file(s));
}
}
PSOCK_CLOSE(&s->sout);
PT_END(&s->outputpt);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(struct httpd_state *s))
{
PSOCK_BEGIN(&s->sin);
PSOCK_READTO(&s->sin, ISO_space);
if(strncmp(s->inputbuf, http_get, 4) != 0) {
PSOCK_CLOSE_EXIT(&s->sin);
}
PSOCK_READTO(&s->sin, ISO_space);
if(s->inputbuf[0] != ISO_slash) {
PSOCK_CLOSE_EXIT(&s->sin);
}
if(s->inputbuf[1] == ISO_space) {
strncpy(s->filename, http_index_html, sizeof(s->filename));
} else {
s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
/* Process any form input being sent to the server. */
{
extern void vApplicationProcessFormInput( char *pcInputString );
vApplicationProcessFormInput( s->inputbuf );
}
strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
}
/* httpd_log_file(uip_conn->ripaddr, s->filename);*/
s->state = STATE_OUTPUT;
while(1) {
PSOCK_READTO(&s->sin, ISO_nl);
if(strncmp(s->inputbuf, http_referer, 8) == 0) {
s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
/* httpd_log(&s->inputbuf[9]);*/
}
}
PSOCK_END(&s->sin);
}
/*---------------------------------------------------------------------------*/
static void
handle_connection(struct httpd_state *s)
{
handle_input(s);
if(s->state == STATE_OUTPUT) {
handle_output(s);
}
}
/*---------------------------------------------------------------------------*/
void
httpd_appcall(void)
{
struct httpd_state *s = (struct httpd_state *)&(uip_conn->appstate);
if(uip_closed() || uip_aborted() || uip_timedout()) {
} else if(uip_connected()) {
PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1);
PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1);
PT_INIT(&s->outputpt);
s->state = STATE_WAITING;
/* timer_set(&s->timer, CLOCK_SECOND * 100);*/
s->timer = 0;
handle_connection(s);
} else if(s != NULL) {
if(uip_poll()) {
++s->timer;
if(s->timer >= 20) {
uip_abort();
}
} else {
s->timer = 0;
}
handle_connection(s);
} else {
uip_abort();
}
}
/*---------------------------------------------------------------------------*/
/**
* \brief Initialize the web server
*
* This function initializes the web server and should be
* called at system boot-up.
*/
void
httpd_init(void)
{
uip_listen(HTONS(80));
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2001-2005, Adam Dunkels.
* 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 uIP TCP/IP stack.
*
* $Id: httpd.h,v 1.2 2006/06/11 21:46:38 adam Exp $
*
*/
#ifndef __HTTPD_H__
#define __HTTPD_H__
#include "psock.h"
#include "httpd-fs.h"
struct httpd_state {
unsigned char timer;
struct psock sin, sout;
struct pt outputpt, scriptpt;
char inputbuf[50];
char filename[20];
char state;
struct httpd_fs_file file;
int len;
char *scriptptr;
int scriptlen;
unsigned short count;
};
void httpd_init(void);
void httpd_appcall(void);
void httpd_log(char *msg);
void httpd_log_file(u16_t *requester, char *file);
#endif /* __HTTPD_H__ */

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2004-2005, 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 uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
/**
* \addtogroup lc
* @{
*/
/**
* \file
* Implementation of local continuations based on switch() statment
* \author Adam Dunkels <adam@sics.se>
*
* This implementation of local continuations uses the C switch()
* statement to resume execution of a function somewhere inside the
* function's body. The implementation is based on the fact that
* switch() statements are able to jump directly into the bodies of
* control structures such as if() or while() statmenets.
*
* This implementation borrows heavily from Simon Tatham's coroutines
* implementation in C:
* http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
*/
#ifndef __LC_SWITCH_H__
#define __LC_SWTICH_H__
/* WARNING! lc implementation using switch() does not work if an
LC_SET() is done within another switch() statement! */
/** \hideinitializer */
typedef unsigned short lc_t;
#define LC_INIT(s) s = 0;
#define LC_RESUME(s) switch(s) { case 0:
#define LC_SET(s) s = __LINE__; case __LINE__:
#define LC_END(s) }
#endif /* __LC_SWITCH_H__ */
/** @} */

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2004-2005, 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 uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
/**
* \addtogroup pt
* @{
*/
/**
* \defgroup lc Local continuations
* @{
*
* Local continuations form the basis for implementing protothreads. A
* local continuation can be <i>set</i> in a specific function to
* capture the state of the function. After a local continuation has
* been set can be <i>resumed</i> in order to restore the state of the
* function at the point where the local continuation was set.
*
*
*/
/**
* \file lc.h
* Local continuations
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifdef DOXYGEN
/**
* Initialize a local continuation.
*
* This operation initializes the local continuation, thereby
* unsetting any previously set continuation state.
*
* \hideinitializer
*/
#define LC_INIT(lc)
/**
* Set a local continuation.
*
* The set operation saves the state of the function at the point
* where the operation is executed. As far as the set operation is
* concerned, the state of the function does <b>not</b> include the
* call-stack or local (automatic) variables, but only the program
* counter and such CPU registers that needs to be saved.
*
* \hideinitializer
*/
#define LC_SET(lc)
/**
* Resume a local continuation.
*
* The resume operation resumes a previously set local continuation, thus
* restoring the state in which the function was when the local
* continuation was set. If the local continuation has not been
* previously set, the resume operation does nothing.
*
* \hideinitializer
*/
#define LC_RESUME(lc)
/**
* Mark the end of local continuation usage.
*
* The end operation signifies that local continuations should not be
* used any more in the function. This operation is not needed for
* most implementations of local continuation, but is required by a
* few implementations.
*
* \hideinitializer
*/
#define LC_END(lc)
/**
* \var typedef lc_t;
*
* The local continuation type.
*
* \hideinitializer
*/
#endif /* DOXYGEN */
#ifndef __LC_H__
#define __LC_H__
#ifdef LC_CONF_INCLUDE
#include LC_CONF_INCLUDE
#else
#include "lc-switch.h"
#endif /* LC_CONF_INCLUDE */
#endif /* __LC_H__ */
/** @} */
/** @} */

View File

@ -0,0 +1,78 @@
#!/usr/bin/perl
open(OUTPUT, "> httpd-fsdata.c");
chdir("httpd-fs");
opendir(DIR, ".");
@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
closedir(DIR);
foreach $file (@files) {
if(-d $file && $file !~ /^\./) {
print "Processing directory $file\n";
opendir(DIR, $file);
@newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
closedir(DIR);
printf "Adding files @newfiles\n";
@files = (@files, map { $_ = "$file/$_" } @newfiles);
next;
}
}
foreach $file (@files) {
if(-f $file) {
print "Adding file $file\n";
open(FILE, $file) || die "Could not open file $file\n";
$file =~ s-^-/-;
$fvar = $file;
$fvar =~ s-/-_-g;
$fvar =~ s-\.-_-g;
# for AVR, add PROGMEM here
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 "0};\n\n");
close(FILE);
push(@fvars, $fvar);
push(@pfiles, $file);
}
}
for($i = 0; $i < @fvars; $i++) {
$file = $pfiles[$i];
$fvar = $fvars[$i];
if($i == 0) {
$prevfile = "NULL";
} else {
$prevfile = "file" . $fvars[$i - 1];
}
print(OUTPUT "const struct httpd_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 HTTPD_FS_ROOT file$fvars[$i - 1]\n\n");
print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n");

View File

@ -0,0 +1,40 @@
#!/usr/bin/perl
sub stringify {
my $name = shift(@_);
open(OUTPUTC, "> $name.c");
open(OUTPUTH, "> $name.h");
open(FILE, "$name");
while(<FILE>) {
if(/(.+) "(.+)"/) {
$var = $1;
$data = $2;
$datan = $data;
$datan =~ s/\\r/\r/g;
$datan =~ s/\\n/\n/g;
$datan =~ s/\\01/\01/g;
$datan =~ s/\\0/\0/g;
printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1);
printf(OUTPUTC "/* \"$data\" */\n");
printf(OUTPUTC "{");
for($j = 0; $j < length($datan); $j++) {
printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1)));
}
printf(OUTPUTC "};\n");
printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1);
}
}
close(OUTPUTC);
close(OUTPUTH);
}
stringify("http-strings");
exit 0;

View File

@ -0,0 +1,339 @@
/*
* Copyright (c) 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. 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 uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
#include <stdio.h>
#include <string.h>
#include "uipopt.h"
#include "psock.h"
#include "uip.h"
#define STATE_NONE 0
#define STATE_ACKED 1
#define STATE_READ 2
#define STATE_BLOCKED_NEWDATA 3
#define STATE_BLOCKED_CLOSE 4
#define STATE_BLOCKED_SEND 5
#define STATE_DATA_SENT 6
/*
* Return value of the buffering functions that indicates that a
* buffer was not filled by incoming data.
*
*/
#define BUF_NOT_FULL 0
#define BUF_NOT_FOUND 0
/*
* Return value of the buffering functions that indicates that a
* buffer was completely filled by incoming data.
*
*/
#define BUF_FULL 1
/*
* Return value of the buffering functions that indicates that an
* end-marker byte was found.
*
*/
#define BUF_FOUND 2
/*---------------------------------------------------------------------------*/
static void
buf_setup(struct psock_buf *buf,
u8_t *bufptr, u16_t bufsize)
{
buf->ptr = bufptr;
buf->left = bufsize;
}
/*---------------------------------------------------------------------------*/
static u8_t
buf_bufdata(struct psock_buf *buf, u16_t len,
u8_t **dataptr, u16_t *datalen)
{
( void ) len;
if(*datalen < buf->left) {
memcpy(buf->ptr, *dataptr, *datalen);
buf->ptr += *datalen;
buf->left -= *datalen;
*dataptr += *datalen;
*datalen = 0;
return BUF_NOT_FULL;
} else if(*datalen == buf->left) {
memcpy(buf->ptr, *dataptr, *datalen);
buf->ptr += *datalen;
buf->left = 0;
*dataptr += *datalen;
*datalen = 0;
return BUF_FULL;
} else {
memcpy(buf->ptr, *dataptr, buf->left);
buf->ptr += buf->left;
*datalen -= buf->left;
*dataptr += buf->left;
buf->left = 0;
return BUF_FULL;
}
}
/*---------------------------------------------------------------------------*/
static u8_t
buf_bufto(register struct psock_buf *buf, u8_t endmarker,
register u8_t **dataptr, register u16_t *datalen)
{
u8_t c;
while(buf->left > 0 && *datalen > 0) {
c = *buf->ptr = **dataptr;
++*dataptr;
++buf->ptr;
--*datalen;
--buf->left;
if(c == endmarker) {
return BUF_FOUND;
}
}
if(*datalen == 0) {
return BUF_NOT_FOUND;
}
while(*datalen > 0) {
c = **dataptr;
--*datalen;
++*dataptr;
if(c == endmarker) {
return BUF_FOUND | BUF_FULL;
}
}
return BUF_FULL;
}
/*---------------------------------------------------------------------------*/
static char
send_data(register struct psock *s)
{
if(s->state != STATE_DATA_SENT || uip_rexmit()) {
if(s->sendlen > uip_mss()) {
uip_send(s->sendptr, uip_mss());
} else {
uip_send(s->sendptr, s->sendlen);
}
s->state = STATE_DATA_SENT;
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static char
data_acked(register struct psock *s)
{
if(s->state == STATE_DATA_SENT && uip_acked()) {
if(s->sendlen > uip_mss()) {
s->sendlen -= uip_mss();
s->sendptr += uip_mss();
} else {
s->sendptr += s->sendlen;
s->sendlen = 0;
}
s->state = STATE_ACKED;
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_send(register struct psock *s, const char *buf,
unsigned int len))
{
PT_BEGIN(&s->psockpt);
/* If there is no data to send, we exit immediately. */
if(len == 0) {
PT_EXIT(&s->psockpt);
}
/* Save the length of and a pointer to the data that is to be
sent. */
s->sendptr = (unsigned char*)buf;
s->sendlen = len;
s->state = STATE_NONE;
/* We loop here until all data is sent. The s->sendlen variable is
updated by the data_sent() function. */
while(s->sendlen > 0) {
/*
* The condition for this PT_WAIT_UNTIL is a little tricky: the
* protothread will wait here until all data has been acknowledged
* (data_acked() returns true) and until all data has been sent
* (send_data() returns true). The two functions data_acked() and
* send_data() must be called in succession to ensure that all
* data is sent. Therefore the & operator is used instead of the
* && operator, which would cause only the data_acked() function
* to be called when it returns false.
*/
PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
}
s->state = STATE_NONE;
PT_END(&s->psockpt);
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_generator_send(register struct psock *s,
unsigned short (*generate)(void *), void *arg))
{
PT_BEGIN(&s->psockpt);
/* Ensure that there is a generator function to call. */
if(generate == NULL) {
PT_EXIT(&s->psockpt);
}
/* Call the generator function to generate the data in the
uip_appdata buffer. */
s->sendlen = generate(arg);
s->sendptr = uip_appdata;
s->state = STATE_NONE;
do {
/* Call the generator function again if we are called to perform a
retransmission. */
if(uip_rexmit()) {
generate(arg);
}
/* Wait until all data is sent and acknowledged. */
PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
} while(s->sendlen > 0);
s->state = STATE_NONE;
PT_END(&s->psockpt);
}
/*---------------------------------------------------------------------------*/
u16_t
psock_datalen(struct psock *psock)
{
return psock->bufsize - psock->buf.left;
}
/*---------------------------------------------------------------------------*/
char
psock_newdata(struct psock *s)
{
if(s->readlen > 0) {
/* There is data in the uip_appdata buffer that has not yet been
read with the PSOCK_READ functions. */
return 1;
} else if(s->state == STATE_READ) {
/* All data in uip_appdata buffer already consumed. */
s->state = STATE_BLOCKED_NEWDATA;
return 0;
} else if(uip_newdata()) {
/* There is new data that has not been consumed. */
return 1;
} else {
/* There is no new data. */
return 0;
}
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_readto(register struct psock *psock, unsigned char c))
{
PT_BEGIN(&psock->psockpt);
buf_setup(&psock->buf, (unsigned char*)psock->bufptr, psock->bufsize);
/* XXX: Should add buf_checkmarker() before do{} loop, if
incoming data has been handled while waiting for a write. */
do {
if(psock->readlen == 0) {
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
psock->state = STATE_READ;
psock->readptr = (u8_t *)uip_appdata;
psock->readlen = uip_datalen();
}
} while((buf_bufto(&psock->buf, c,
&psock->readptr,
&psock->readlen) & BUF_FOUND) == 0);
if(psock_datalen(psock) == 0) {
psock->state = STATE_NONE;
PT_RESTART(&psock->psockpt);
}
PT_END(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_readbuf(register struct psock *psock))
{
PT_BEGIN(&psock->psockpt);
buf_setup(&psock->buf, (unsigned char * ) psock->bufptr, psock->bufsize);
/* XXX: Should add buf_checkmarker() before do{} loop, if
incoming data has been handled while waiting for a write. */
do {
if(psock->readlen == 0) {
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
printf("Waited for newdata\n");
psock->state = STATE_READ;
psock->readptr = (u8_t *)uip_appdata;
psock->readlen = uip_datalen();
}
} while(buf_bufdata(&psock->buf, psock->bufsize,
&psock->readptr,
&psock->readlen) != BUF_FULL);
if(psock_datalen(psock) == 0) {
psock->state = STATE_NONE;
PT_RESTART(&psock->psockpt);
}
PT_END(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/
void
psock_init(register struct psock *psock, char *buffer, unsigned int buffersize)
{
psock->state = STATE_NONE;
psock->readlen = 0;
psock->bufptr = buffer;
psock->bufsize = buffersize;
buf_setup(&psock->buf, (unsigned char*) buffer, buffersize);
PT_INIT(&psock->pt);
PT_INIT(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,380 @@
/*
* Copyright (c) 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. 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 uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $
*/
/**
* \defgroup psock Protosockets library
* @{
*
* The protosocket library provides an interface to the uIP stack that is
* similar to the traditional BSD socket interface. Unlike programs
* written for the ordinary uIP event-driven interface, programs
* written with the protosocket library are executed in a sequential
* fashion and does not have to be implemented as explicit state
* machines.
*
* Protosockets only work with TCP connections.
*
* The protosocket library uses \ref pt protothreads to provide
* sequential control flow. This makes the protosockets lightweight in
* terms of memory, but also means that protosockets inherits the
* functional limitations of protothreads. Each protosocket lives only
* within a single function. Automatic variables (stack variables) are
* not retained across a protosocket library function call.
*
* \note Because the protosocket library uses protothreads, local
* variables will not always be saved across a call to a protosocket
* library function. It is therefore advised that local variables are
* used with extreme care.
*
* The protosocket library provides functions for sending data without
* having to deal with retransmissions and acknowledgements, as well
* as functions for reading data without having to deal with data
* being split across more than one TCP segment.
*
* Because each protosocket runs as a protothread, the protosocket has to be
* started with a call to PSOCK_BEGIN() at the start of the function
* in which the protosocket is used. Similarly, the protosocket protothread can
* be terminated by a call to PSOCK_EXIT().
*
*/
/**
* \file
* Protosocket library header file
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PSOCK_H__
#define __PSOCK_H__
#include "uipopt.h"
#include "pt.h"
/*
* The structure that holds the state of a buffer.
*
* This structure holds the state of a uIP buffer. The structure has
* no user-visible elements, but is used through the functions
* provided by the library.
*
*/
struct psock_buf {
u8_t *ptr;
unsigned short left;
};
/**
* The representation of a protosocket.
*
* The protosocket structrure is an opaque structure with no user-visible
* elements.
*/
struct psock {
struct pt pt, psockpt; /* Protothreads - one that's using the psock
functions, and one that runs inside the
psock functions. */
const u8_t *sendptr; /* Pointer to the next data to be sent. */
u8_t *readptr; /* Pointer to the next data to be read. */
char *bufptr; /* Pointer to the buffer used for buffering
incoming data. */
u16_t sendlen; /* The number of bytes left to be sent. */
u16_t readlen; /* The number of bytes left to be read. */
struct psock_buf buf; /* The structure holding the state of the
input buffer. */
unsigned int bufsize; /* The size of the input buffer. */
unsigned char state; /* The state of the protosocket. */
};
void psock_init(struct psock *psock, char *buffer, unsigned int buffersize);
/**
* Initialize a protosocket.
*
* This macro initializes a protosocket and must be called before the
* protosocket is used. The initialization also specifies the input buffer
* for the protosocket.
*
* \param psock (struct psock *) A pointer to the protosocket to be
* initialized
*
* \param buffer (char *) A pointer to the input buffer for the
* protosocket.
*
* \param buffersize (unsigned int) The size of the input buffer.
*
* \hideinitializer
*/
#define PSOCK_INIT(psock, buffer, buffersize) \
psock_init(psock, buffer, buffersize)
/**
* Start the protosocket protothread in a function.
*
* This macro starts the protothread associated with the protosocket and
* must come before other protosocket calls in the function it is used.
*
* \param psock (struct psock *) A pointer to the protosocket to be
* started.
*
* \hideinitializer
*/
#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))
PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len));
/**
* Send data.
*
* This macro sends data over a protosocket. The protosocket protothread blocks
* until all data has been sent and is known to have been received by
* the remote end of the TCP connection.
*
* \param psock (struct psock *) A pointer to the protosocket over which
* data is to be sent.
*
* \param data (char *) A pointer to the data that is to be sent.
*
* \param datalen (unsigned int) The length of the data that is to be
* sent.
*
* \hideinitializer
*/
#define PSOCK_SEND(psock, data, datalen) \
PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen))
/**
* \brief Send a null-terminated string.
* \param psock Pointer to the protosocket.
* \param str The string to be sent.
*
* This function sends a null-terminated string over the
* protosocket.
*
* \hideinitializer
*/
#define PSOCK_SEND_STR(psock, str) \
PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str)))
PT_THREAD(psock_generator_send(struct psock *psock,
unsigned short (*f)(void *), void *arg));
/**
* \brief Generate data with a function and send it
* \param psock Pointer to the protosocket.
* \param generator Pointer to the generator function
* \param arg Argument to the generator function
*
* This function generates data and sends it over the
* protosocket. This can be used to dynamically generate
* data for a transmission, instead of generating the data
* in a buffer beforehand. This function reduces the need for
* buffer memory. The generator function is implemented by
* the application, and a pointer to the function is given
* as an argument with the call to PSOCK_GENERATOR_SEND().
*
* The generator function should place the generated data
* directly in the uip_appdata buffer, and return the
* length of the generated data. The generator function is
* called by the protosocket layer when the data first is
* sent, and once for every retransmission that is needed.
*
* \hideinitializer
*/
#define PSOCK_GENERATOR_SEND(psock, generator, arg) \
PT_WAIT_THREAD(&((psock)->pt), \
psock_generator_send(psock, generator, arg))
/**
* Close a protosocket.
*
* This macro closes a protosocket and can only be called from within the
* protothread in which the protosocket lives.
*
* \param psock (struct psock *) A pointer to the protosocket that is to
* be closed.
*
* \hideinitializer
*/
#define PSOCK_CLOSE(psock) uip_close()
PT_THREAD(psock_readbuf(struct psock *psock));
/**
* Read data until the buffer is full.
*
* This macro will block waiting for data and read the data into the
* input buffer specified with the call to PSOCK_INIT(). Data is read
* until the buffer is full..
*
* \param psock (struct psock *) A pointer to the protosocket from which
* data should be read.
*
* \hideinitializer
*/
#define PSOCK_READBUF(psock) \
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))
PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
/**
* Read data up to a specified character.
*
* This macro will block waiting for data and read the data into the
* input buffer specified with the call to PSOCK_INIT(). Data is only
* read until the specifieed character appears in the data stream.
*
* \param psock (struct psock *) A pointer to the protosocket from which
* data should be read.
*
* \param c (char) The character at which to stop reading.
*
* \hideinitializer
*/
#define PSOCK_READTO(psock, c) \
PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c))
/**
* The length of the data that was previously read.
*
* This macro returns the length of the data that was previously read
* using PSOCK_READTO() or PSOCK_READ().
*
* \param psock (struct psock *) A pointer to the protosocket holding the data.
*
* \hideinitializer
*/
#define PSOCK_DATALEN(psock) psock_datalen(psock)
u16_t psock_datalen(struct psock *psock);
/**
* Exit the protosocket's protothread.
*
* This macro terminates the protothread of the protosocket and should
* almost always be used in conjunction with PSOCK_CLOSE().
*
* \sa PSOCK_CLOSE_EXIT()
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt))
/**
* Close a protosocket and exit the protosocket's protothread.
*
* This macro closes a protosocket and exits the protosocket's protothread.
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_CLOSE_EXIT(psock) \
do { \
PSOCK_CLOSE(psock); \
PSOCK_EXIT(psock); \
} while(0)
/**
* Declare the end of a protosocket's protothread.
*
* This macro is used for declaring that the protosocket's protothread
* ends. It must always be used together with a matching PSOCK_BEGIN()
* macro.
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_END(psock) PT_END(&((psock)->pt))
char psock_newdata(struct psock *s);
/**
* Check if new data has arrived on a protosocket.
*
* This macro is used in conjunction with the PSOCK_WAIT_UNTIL()
* macro to check if data has arrived on a protosocket.
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_NEWDATA(psock) psock_newdata(psock)
/**
* Wait until a condition is true.
*
* This macro blocks the protothread until the specified condition is
* true. The macro PSOCK_NEWDATA() can be used to check if new data
* arrives when the protosocket is waiting.
*
* Typically, this macro is used as follows:
*
\code
PT_THREAD(thread(struct psock *s, struct timer *t))
{
PSOCK_BEGIN(s);
PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t));
if(PSOCK_NEWDATA(s)) {
PSOCK_READTO(s, '\n');
} else {
handle_timed_out(s);
}
PSOCK_END(s);
}
\endcode
*
* \param psock (struct psock *) A pointer to the protosocket.
* \param condition The condition to wait for.
*
* \hideinitializer
*/
#define PSOCK_WAIT_UNTIL(psock, condition) \
PT_WAIT_UNTIL(&((psock)->pt), (condition));
#define PSOCK_WAIT_THREAD(psock, condition) \
PT_WAIT_THREAD(&((psock)->pt), (condition))
#endif /* __PSOCK_H__ */
/** @} */

View File

@ -0,0 +1,323 @@
/*
* Copyright (c) 2004-2005, 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 uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
/**
* \addtogroup pt
* @{
*/
/**
* \file
* Protothreads implementation.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PT_H__
#define __PT_H__
#include "lc.h"
struct pt {
lc_t lc;
};
#define PT_WAITING 0
#define PT_EXITED 1
#define PT_ENDED 2
#define PT_YIELDED 3
/**
* \name Initialization
* @{
*/
/**
* Initialize a protothread.
*
* Initializes a protothread. Initialization must be done prior to
* starting to execute the protothread.
*
* \param pt A pointer to the protothread control structure.
*
* \sa PT_SPAWN()
*
* \hideinitializer
*/
#define PT_INIT(pt) LC_INIT((pt)->lc)
/** @} */
/**
* \name Declaration and definition
* @{
*/
/**
* Declaration of a protothread.
*
* This macro is used to declare a protothread. All protothreads must
* be declared with this macro.
*
* \param name_args The name and arguments of the C function
* implementing the protothread.
*
* \hideinitializer
*/
#define PT_THREAD(name_args) char name_args
/**
* Declare the start of a protothread inside the C function
* implementing the protothread.
*
* This macro is used to declare the starting point of a
* protothread. It should be placed at the start of the function in
* which the protothread runs. All C statements above the PT_BEGIN()
* invokation will be executed each time the protothread is scheduled.
*
* \param pt A pointer to the protothread control structure.
*
* \hideinitializer
*/
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
/**
* Declare the end of a protothread.
*
* This macro is used for declaring that a protothread ends. It must
* always be used together with a matching PT_BEGIN() macro.
*
* \param pt A pointer to the protothread control structure.
*
* \hideinitializer
*/
#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
PT_INIT(pt); return PT_ENDED; }
/** @} */
/**
* \name Blocked wait
* @{
*/
/**
* Block and wait until condition is true.
*
* This macro blocks the protothread until the specified condition is
* true.
*
* \param pt A pointer to the protothread control structure.
* \param condition The condition.
*
* \hideinitializer
*/
#define PT_WAIT_UNTIL(pt, condition) \
do { \
LC_SET((pt)->lc); \
if(!(condition)) { \
return PT_WAITING; \
} \
} while(0)
/**
* Block and wait while condition is true.
*
* This function blocks and waits while condition is true. See
* PT_WAIT_UNTIL().
*
* \param pt A pointer to the protothread control structure.
* \param cond The condition.
*
* \hideinitializer
*/
#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
/** @} */
/**
* \name Hierarchical protothreads
* @{
*/
/**
* Block and wait until a child protothread completes.
*
* This macro schedules a child protothread. The current protothread
* will block until the child protothread completes.
*
* \note The child protothread must be manually initialized with the
* PT_INIT() function before this function is used.
*
* \param pt A pointer to the protothread control structure.
* \param thread The child protothread with arguments
*
* \sa PT_SPAWN()
*
* \hideinitializer
*/
#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
/**
* Spawn a child protothread and wait until it exits.
*
* This macro spawns a child protothread and waits until it exits. The
* macro can only be used within a protothread.
*
* \param pt A pointer to the protothread control structure.
* \param child A pointer to the child protothread's control structure.
* \param thread The child protothread with arguments
*
* \hideinitializer
*/
#define PT_SPAWN(pt, child, thread) \
do { \
PT_INIT((child)); \
PT_WAIT_THREAD((pt), (thread)); \
} while(0)
/** @} */
/**
* \name Exiting and restarting
* @{
*/
/**
* Restart the protothread.
*
* This macro will block and cause the running protothread to restart
* its execution at the place of the PT_BEGIN() call.
*
* \param pt A pointer to the protothread control structure.
*
* \hideinitializer
*/
#define PT_RESTART(pt) \
do { \
PT_INIT(pt); \
return PT_WAITING; \
} while(0)
/**
* Exit the protothread.
*
* This macro causes the protothread to exit. If the protothread was
* spawned by another protothread, the parent protothread will become
* unblocked and can continue to run.
*
* \param pt A pointer to the protothread control structure.
*
* \hideinitializer
*/
#define PT_EXIT(pt) \
do { \
PT_INIT(pt); \
return PT_EXITED; \
} while(0)
/** @} */
/**
* \name Calling a protothread
* @{
*/
/**
* Schedule a protothread.
*
* This function shedules a protothread. The return value of the
* function is non-zero if the protothread is running or zero if the
* protothread has exited.
*
* \param f The call to the C function implementing the protothread to
* be scheduled
*
* \hideinitializer
*/
#define PT_SCHEDULE(f) ((f) == PT_WAITING)
/** @} */
/**
* \name Yielding from a protothread
* @{
*/
/**
* Yield from the current protothread.
*
* This function will yield the protothread, thereby allowing other
* processing to take place in the system.
*
* \param pt A pointer to the protothread control structure.
*
* \hideinitializer
*/
#define PT_YIELD(pt) \
do { \
PT_YIELD_FLAG = 0; \
LC_SET((pt)->lc); \
if(PT_YIELD_FLAG == 0) { \
return PT_YIELDED; \
} \
} while(0)
/**
* \brief Yield from the protothread until a condition occurs.
* \param pt A pointer to the protothread control structure.
* \param cond The condition.
*
* This function will yield the protothread, until the
* specified condition evaluates to true.
*
*
* \hideinitializer
*/
#define PT_YIELD_UNTIL(pt, cond) \
do { \
PT_YIELD_FLAG = 0; \
LC_SET((pt)->lc); \
if((PT_YIELD_FLAG == 0) || !(cond)) { \
return PT_YIELDED; \
} \
} while(0)
/** @} */
#endif /* __PT_H__ */
/** @} */

View File

@ -0,0 +1,127 @@
/**
* \addtogroup timer
* @{
*/
/**
* \file
* Timer library implementation.
* \author
* Adam Dunkels <adam@sics.se>
*/
/*
* Copyright (c) 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. 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 uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $
*/
#include "clock.h"
#include "timer.h"
/*---------------------------------------------------------------------------*/
/**
* Set a timer.
*
* This function is used to set a timer for a time sometime in the
* future. The function timer_expired() will evaluate to true after
* the timer has expired.
*
* \param t A pointer to the timer
* \param interval The interval before the timer expires.
*
*/
void
timer_set(struct timer *t, clock_time_t interval)
{
t->interval = interval;
t->start = clock_time();
}
/*---------------------------------------------------------------------------*/
/**
* Reset the timer with the same interval.
*
* This function resets the timer with the same interval that was
* given to the timer_set() function. The start point of the interval
* is the exact time that the timer last expired. Therefore, this
* function will cause the timer to be stable over time, unlike the
* timer_rester() function.
*
* \param t A pointer to the timer.
*
* \sa timer_restart()
*/
void
timer_reset(struct timer *t)
{
t->start += t->interval;
}
/*---------------------------------------------------------------------------*/
/**
* Restart the timer from the current point in time
*
* This function restarts a timer with the same interval that was
* given to the timer_set() function. The timer will start at the
* current time.
*
* \note A periodic timer will drift if this function is used to reset
* it. For preioric timers, use the timer_reset() function instead.
*
* \param t A pointer to the timer.
*
* \sa timer_reset()
*/
void
timer_restart(struct timer *t)
{
t->start = clock_time();
}
/*---------------------------------------------------------------------------*/
/**
* Check if a timer has expired.
*
* This function tests if a timer has expired and returns true or
* false depending on its status.
*
* \param t A pointer to the timer
*
* \return Non-zero if the timer has expired, zero otherwise.
*
*/
int
timer_expired(struct timer *t)
{
return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -0,0 +1,86 @@
/**
* \defgroup timer Timer library
*
* The timer library provides functions for setting, resetting and
* restarting timers, and for checking if a timer has expired. An
* application must "manually" check if its timers have expired; this
* is not done automatically.
*
* A timer is declared as a \c struct \c timer and all access to the
* timer is made by a pointer to the declared timer.
*
* \note The timer library uses the \ref clock "Clock library" to
* measure time. Intervals should be specified in the format used by
* the clock library.
*
* @{
*/
/**
* \file
* Timer library header file.
* \author
* Adam Dunkels <adam@sics.se>
*/
/*
* Copyright (c) 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. 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 uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $
*/
#ifndef __TIMER_H__
#define __TIMER_H__
#include "clock.h"
/**
* A timer.
*
* This structure is used for declaring a timer. The timer must be set
* with timer_set() before it can be used.
*
* \hideinitializer
*/
struct timer {
clock_time_t start;
clock_time_t interval;
};
void timer_set(struct timer *t, clock_time_t interval);
void timer_reset(struct timer *t);
void timer_restart(struct timer *t);
int timer_expired(struct timer *t);
#endif /* __TIMER_H__ */
/** @} */

View File

@ -0,0 +1,270 @@
/*
FreeRTOS.org V5.4.0 - Copyright (C) 2003-2009 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org 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 exception to the GPL is included to allow you to distribute a
combined work that includes FreeRTOS.org without being obliged to provide
the source code for any proprietary components. Alternative commercial
license and support terms are also available upon request. See the
licensing section of http://www.FreeRTOS.org for full details.
FreeRTOS.org 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 along
with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
***************************************************************************
* *
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
* *
* This is a concise, step by step, 'hands on' guide that describes both *
* general multitasking concepts and FreeRTOS specifics. It presents and *
* explains numerous examples that are written using the FreeRTOS API. *
* Full source code for all the examples is provided in an accompanying *
* .zip file. *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
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>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* uip includes. */
#include "uip.h"
#include "uip_arp.h"
#include "httpd.h"
#include "timer.h"
#include "clock-arch.h"
/* Demo includes. */
#include "EthDev_LPC17xx.h"
#include "EthDev.h"
#include "ParTest.h"
/*-----------------------------------------------------------*/
/* How long to wait before attempting to connect the MAC again. */
#define uipINIT_WAIT ( 100 / portTICK_RATE_MS )
/* Shortcut to the header within the Rx buffer. */
#define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])
/* Standard constant. */
#define uipTOTAL_FRAME_HEADER_SIZE 54
/*-----------------------------------------------------------*/
/*
* Setup the MAC address in the MAC itself, and in the uIP stack.
*/
static void prvSetMACAddress( void );
/*
* Port functions required by the uIP stack.
*/
void clock_init( void );
clock_time_t clock_time( void );
/*-----------------------------------------------------------*/
/* The semaphore used by the ISR to wake the uIP task. */
xSemaphoreHandle xEMACSemaphore = NULL;
/*-----------------------------------------------------------*/
void clock_init(void)
{
/* This is done when the scheduler starts. */
}
/*-----------------------------------------------------------*/
clock_time_t clock_time( void )
{
return xTaskGetTickCount();
}
/*-----------------------------------------------------------*/
void vuIP_Task( void *pvParameters )
{
portBASE_TYPE i;
uip_ipaddr_t xIPAddr;
struct timer periodic_timer, arp_timer;
extern void ( vEMAC_ISR_Wrapper )( void );
( void ) pvParameters;
/* Initialise the uIP stack. */
timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );
timer_set( &arp_timer, configTICK_RATE_HZ * 10 );
uip_init();
uip_ipaddr( xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
uip_sethostaddr( xIPAddr );
uip_ipaddr( xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );
uip_setnetmask( xIPAddr );
httpd_init();
/* Create the semaphore used to wake the uIP task. */
vSemaphoreCreateBinary( xEMACSemaphore );
/* Initialise the MAC. */
while( lEMACInit() != pdPASS )
{
vTaskDelay( uipINIT_WAIT );
}
portENTER_CRITICAL();
{
EMAC->IntEnable = ( INT_RX_DONE | INT_TX_DONE );
/* Set the interrupt priority to the max permissible to cause some
interrupt nesting. */
NVIC_SetPriority( ENET_IRQn, configMAX_SYSCALL_INTERRUPT_PRIORITY );
/* Enable the interrupt. */
NVIC_EnableIRQ( ENET_IRQn );
prvSetMACAddress();
}
portEXIT_CRITICAL();
for( ;; )
{
/* Is there received data ready to be processed? */
uip_len = ulGetEMACRxData();
if( ( uip_len > 0 ) && ( uip_buf != NULL ) )
{
/* Standard uIP loop taken from the uIP manual. */
if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
{
uip_arp_ipin();
uip_input();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if( uip_len > 0 )
{
uip_arp_out();
vSendEMACTxData( uip_len );
}
}
else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
{
uip_arp_arpin();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if( uip_len > 0 )
{
vSendEMACTxData( uip_len );
}
}
}
else
{
if( timer_expired( &periodic_timer ) && ( uip_buf != NULL ) )
{
timer_reset( &periodic_timer );
for( i = 0; i < UIP_CONNS; i++ )
{
uip_periodic( i );
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if( uip_len > 0 )
{
uip_arp_out();
vSendEMACTxData( uip_len );
}
}
/* Call the ARP timer function every 10 seconds. */
if( timer_expired( &arp_timer ) )
{
timer_reset( &arp_timer );
uip_arp_timer();
}
}
else
{
/* We did not receive a packet, and there was no periodic
processing to perform. Block for a fixed period. If a packet
is received during this period we will be woken by the ISR
giving us the Semaphore. */
xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );
}
}
}
}
/*-----------------------------------------------------------*/
static void prvSetMACAddress( void )
{
struct uip_eth_addr xAddr;
/* Configure the MAC address in the uIP stack. */
xAddr.addr[ 0 ] = configMAC_ADDR0;
xAddr.addr[ 1 ] = configMAC_ADDR1;
xAddr.addr[ 2 ] = configMAC_ADDR2;
xAddr.addr[ 3 ] = configMAC_ADDR3;
xAddr.addr[ 4 ] = configMAC_ADDR4;
xAddr.addr[ 5 ] = configMAC_ADDR5;
uip_setethaddr( xAddr );
}
/*-----------------------------------------------------------*/
void vApplicationProcessFormInput( portCHAR *pcInputString )
{
char *c;
const unsigned long ulLEDNo = 3;
/* Process the form input sent by the IO page of the served HTML. */
c = strstr( pcInputString, "?" );
if( c )
{
/* Turn LED's on or off in accordance with the check box status. */
if( strstr( c, "LED0=1" ) != NULL )
{
/* Set LED7. */
vParTestSetLED( ulLEDNo, pdFALSE );
}
else
{
/* Clear LED7. */
vParTestSetLED( ulLEDNo, pdTRUE );
}
}
}

View File

@ -0,0 +1,159 @@
/**
* \addtogroup uipopt
* @{
*/
/**
* \name Project-specific configuration options
* @{
*
* uIP has a number of configuration options that can be overridden
* for each project. These are kept in a project-specific uip-conf.h
* file and all configuration names have the prefix UIP_CONF.
*/
/*
* Copyright (c) 2006, 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 uIP TCP/IP stack
*
* $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
*/
/**
* \file
* An example uIP configuration file
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __UIP_CONF_H__
#define __UIP_CONF_H__
#include <stdint.h>
#define UIP_CONF_EXTERNAL_BUFFER
/**
* 8 bit datatype
*
* This typedef defines the 8-bit type used throughout uIP.
*
* \hideinitializer
*/
typedef uint8_t u8_t;
/**
* 16 bit datatype
*
* This typedef defines the 16-bit type used throughout uIP.
*
* \hideinitializer
*/
typedef uint16_t u16_t;
/**
* Statistics datatype
*
* This typedef defines the dataype used for keeping statistics in
* uIP.
*
* \hideinitializer
*/
typedef unsigned short uip_stats_t;
/**
* Maximum number of TCP connections.
*
* \hideinitializer
*/
#define UIP_CONF_MAX_CONNECTIONS 40
/**
* Maximum number of listening TCP ports.
*
* \hideinitializer
*/
#define UIP_CONF_MAX_LISTENPORTS 40
/**
* uIP buffer size.
*
* \hideinitializer
*/
#define UIP_CONF_BUFFER_SIZE 1480
/**
* CPU byte order.
*
* \hideinitializer
*/
#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN
/**
* Logging on or off
*
* \hideinitializer
*/
#define UIP_CONF_LOGGING 0
/**
* UDP support on or off
*
* \hideinitializer
*/
#define UIP_CONF_UDP 0
/**
* UDP checksums on or off
*
* \hideinitializer
*/
#define UIP_CONF_UDP_CHECKSUMS 1
/**
* uIP statistics on or off
*
* \hideinitializer
*/
#define UIP_CONF_STATISTICS 1
/* Here we include the header file for the application(s) we use in
our project. */
/*#include "smtp.h"*/
/*#include "hello-world.h"*/
/*#include "telnetd.h"*/
#include "webserver.h"
/*#include "dhcpc.h"*/
/*#include "resolv.h"*/
/*#include "webclient.h"*/
#endif /* __UIP_CONF_H__ */
/** @} */
/** @} */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,138 @@
/**
* \addtogroup uip
* {@
*/
/**
* \defgroup uiparch Architecture specific uIP functions
* @{
*
* The functions in the architecture specific module implement the IP
* check sum and 32-bit additions.
*
* The IP checksum calculation is the most computationally expensive
* operation in the TCP/IP stack and it therefore pays off to
* implement this in efficient assembler. The purpose of the uip-arch
* module is to let the checksum functions to be implemented in
* architecture specific assembler.
*
*/
/**
* \file
* Declarations of architecture specific functions.
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 2001, Adam Dunkels.
* 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 uIP TCP/IP stack.
*
* $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $
*
*/
#ifndef __UIP_ARCH_H__
#define __UIP_ARCH_H__
#include "uip.h"
/**
* Carry out a 32-bit addition.
*
* Because not all architectures for which uIP is intended has native
* 32-bit arithmetic, uIP uses an external C function for doing the
* required 32-bit additions in the TCP protocol processing. This
* function should add the two arguments and place the result in the
* global variable uip_acc32.
*
* \note The 32-bit integer pointed to by the op32 parameter and the
* result in the uip_acc32 variable are in network byte order (big
* endian).
*
* \param op32 A pointer to a 4-byte array representing a 32-bit
* integer in network byte order (big endian).
*
* \param op16 A 16-bit integer in host byte order.
*/
void uip_add32(u8_t *op32, u16_t op16);
/**
* Calculate the Internet checksum over a buffer.
*
* The Internet checksum is the one's complement of the one's
* complement sum of all 16-bit words in the buffer.
*
* See RFC1071.
*
* \note This function is not called in the current version of uIP,
* but future versions might make use of it.
*
* \param buf A pointer to the buffer over which the checksum is to be
* computed.
*
* \param len The length of the buffer over which the checksum is to
* be computed.
*
* \return The Internet checksum of the buffer.
*/
u16_t uip_chksum(u16_t *buf, u16_t len);
/**
* Calculate the IP header checksum of the packet header in uip_buf.
*
* The IP header checksum is the Internet checksum of the 20 bytes of
* the IP header.
*
* \return The IP header checksum of the IP header in the uip_buf
* buffer.
*/
u16_t uip_ipchksum(void);
/**
* Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
*
* The TCP checksum is the Internet checksum of data contents of the
* TCP segment, and a pseudo-header as defined in RFC793.
*
* \note The uip_appdata pointer that points to the packet data may
* point anywhere in memory, so it is not possible to simply calculate
* the Internet checksum of the contents of the uip_buf buffer.
*
* \return The TCP checksum of the TCP segment in uip_buf and pointed
* to by uip_appdata.
*/
u16_t uip_tcpchksum(void);
u16_t uip_udpchksum(void);
/** @} */
/** @} */
#endif /* __UIP_ARCH_H__ */

View File

@ -0,0 +1,439 @@
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup uiparp uIP Address Resolution Protocol
* @{
*
* The Address Resolution Protocol ARP is used for mapping between IP
* addresses and link level addresses such as the Ethernet MAC
* addresses. ARP uses broadcast queries to ask for the link level
* address of a known IP address and the host which is configured with
* the IP address for which the query was meant, will respond with its
* link level address.
*
* \note This ARP implementation only supports Ethernet.
*/
/**
* \file
* Implementation of the ARP Address Resolution Protocol.
* \author Adam Dunkels <adam@dunkels.com>
*
*/
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* 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 uIP TCP/IP stack.
*
* $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $
*
*/
#include "uip_arp.h"
#include <string.h>
#ifdef __ICCARM__
#pragma pack(1)
#endif
struct arp_hdr {
struct uip_eth_hdr ethhdr;
u16_t hwtype;
u16_t protocol;
u8_t hwlen;
u8_t protolen;
u16_t opcode;
struct uip_eth_addr shwaddr;
u16_t sipaddr[2];
struct uip_eth_addr dhwaddr;
u16_t dipaddr[2];
} PACK_STRUCT_END;
#ifdef __ICCARM__
#pragma pack()
#endif
#ifdef __ICCARM__
#pragma pack(1)
#endif
struct ethip_hdr {
struct uip_eth_hdr ethhdr;
/* IP header. */
u8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
u16_t ipchksum;
u16_t srcipaddr[2],
destipaddr[2];
} PACK_STRUCT_END;
#ifdef __ICCARM__
#pragma pack()
#endif
#define ARP_REQUEST 1
#define ARP_REPLY 2
#define ARP_HWTYPE_ETH 1
struct arp_entry {
u16_t ipaddr[2];
struct uip_eth_addr ethaddr;
u8_t time;
};
static const struct uip_eth_addr broadcast_ethaddr =
{{0xff,0xff,0xff,0xff,0xff,0xff}};
static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
static u16_t ipaddr[2];
static u8_t i, c;
static u8_t arptime;
static u8_t tmpage;
#define BUF ((struct arp_hdr *)&uip_buf[0])
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
/*-----------------------------------------------------------------------------------*/
/**
* Initialize the ARP module.
*
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_init(void)
{
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
memset(arp_table[i].ipaddr, 0, 4);
}
}
/*-----------------------------------------------------------------------------------*/
/**
* Periodic ARP processing function.
*
* This function performs periodic timer processing in the ARP module
* and should be called at regular intervals. The recommended interval
* is 10 seconds between the calls.
*
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_timer(void)
{
struct arp_entry *tabptr;
++arptime;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
arptime - tabptr->time >= UIP_ARP_MAXAGE) {
memset(tabptr->ipaddr, 0, 4);
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
{
register struct arp_entry *tabptr;
/* Walk through the ARP mapping table and try to find an entry to
update. If none is found, the IP -> MAC address mapping is
inserted in the ARP table. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
/* Only check those entries that are actually in use. */
if(tabptr->ipaddr[0] != 0 &&
tabptr->ipaddr[1] != 0) {
/* Check if the source IP address of the incoming packet matches
the IP address in this ARP table entry. */
if(ipaddr[0] == tabptr->ipaddr[0] &&
ipaddr[1] == tabptr->ipaddr[1]) {
/* An old entry found, update this and return. */
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
return;
}
}
}
/* If we get here, no existing ARP table entry was found, so we
create one. */
/* First, we try to find an unused entry in the ARP table. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(tabptr->ipaddr[0] == 0 &&
tabptr->ipaddr[1] == 0) {
break;
}
}
/* If no unused entry is found, we try to find the oldest entry and
throw it away. */
if(i == UIP_ARPTAB_SIZE) {
tmpage = 0;
c = 0;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(arptime - tabptr->time > tmpage) {
tmpage = arptime - tabptr->time;
c = i;
}
}
i = c;
tabptr = &arp_table[i];
}
/* Now, i is the ARP table entry which we will fill with the new
information. */
memcpy(tabptr->ipaddr, ipaddr, 4);
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
}
/*-----------------------------------------------------------------------------------*/
/**
* ARP processing for incoming IP packets
*
* This function should be called by the device driver when an IP
* packet has been received. The function will check if the address is
* in the ARP cache, and if so the ARP cache entry will be
* refreshed. If no ARP cache entry was found, a new one is created.
*
* This function expects an IP packet with a prepended Ethernet header
* in the uip_buf[] buffer, and the length of the packet in the global
* variable uip_len.
*/
/*-----------------------------------------------------------------------------------*/
#if 1
void
uip_arp_ipin(void)
{
uip_len -= sizeof(struct uip_eth_hdr);
/* Only insert/update an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
(uip_hostaddr[0] & uip_netmask[0])) {
return;
}
if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
(uip_hostaddr[1] & uip_netmask[1])) {
return;
}
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
return;
}
#endif /* 0 */
/*-----------------------------------------------------------------------------------*/
/**
* ARP processing for incoming ARP packets.
*
* This function should be called by the device driver when an ARP
* packet has been received. The function will act differently
* depending on the ARP packet type: if it is a reply for a request
* that we previously sent out, the ARP cache will be filled in with
* the values from the ARP reply. If the incoming ARP packet is an ARP
* request for our IP address, an ARP reply packet is created and put
* into the uip_buf[] buffer.
*
* When the function returns, the value of the global variable uip_len
* indicates whether the device driver should send out a packet or
* not. If uip_len is zero, no packet should be sent. If uip_len is
* non-zero, it contains the length of the outbound packet that is
* present in the uip_buf[] buffer.
*
* This function expects an ARP packet with a prepended Ethernet
* header in the uip_buf[] buffer, and the length of the packet in the
* global variable uip_len.
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_arpin(void)
{
if(uip_len < sizeof(struct arp_hdr)) {
uip_len = 0;
return;
}
uip_len = 0;
switch(BUF->opcode) {
case HTONS(ARP_REQUEST):
/* ARP request. If it asked for our address, we send out a
reply. */
if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
/* First, we register the one who made the request in our ARP
table, since it is likely that we will do more communication
with this host in the future. */
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
/* The reply opcode is 2. */
BUF->opcode = HTONS(2);
memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
BUF->dipaddr[0] = BUF->sipaddr[0];
BUF->dipaddr[1] = BUF->sipaddr[1];
BUF->sipaddr[0] = uip_hostaddr[0];
BUF->sipaddr[1] = uip_hostaddr[1];
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
uip_len = sizeof(struct arp_hdr);
}
break;
case HTONS(ARP_REPLY):
/* ARP reply. We insert or update the ARP table if it was meant
for us. */
if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
}
break;
}
return;
}
/*-----------------------------------------------------------------------------------*/
/**
* Prepend Ethernet header to an outbound IP packet and see if we need
* to send out an ARP request.
*
* This function should be called before sending out an IP packet. The
* function checks the destination IP address of the IP packet to see
* what Ethernet MAC address that should be used as a destination MAC
* address on the Ethernet.
*
* If the destination IP address is in the local network (determined
* by logical ANDing of netmask and our IP address), the function
* checks the ARP cache to see if an entry for the destination IP
* address is found. If so, an Ethernet header is prepended and the
* function returns. If no ARP cache entry is found for the
* destination IP address, the packet in the uip_buf[] is replaced by
* an ARP request packet for the IP address. The IP packet is dropped
* and it is assumed that they higher level protocols (e.g., TCP)
* eventually will retransmit the dropped packet.
*
* If the destination IP address is not on the local network, the IP
* address of the default router is used instead.
*
* When the function returns, a packet is present in the uip_buf[]
* buffer, and the length of the packet is in the global variable
* uip_len.
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_out(void)
{
struct arp_entry *tabptr;
/* Find the destination IP address in the ARP table and construct
the Ethernet header. If the destination IP addres isn't on the
local network, we use the default router's IP address instead.
If not ARP table entry is found, we overwrite the original IP
packet with an ARP request for the IP address. */
/* First check if destination is a local broadcast. */
if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
} else {
/* Check if the destination address is on the local network. */
if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
/* Destination address was not on the local network, so we need to
use the default router's IP address instead of the destination
address when determining the MAC address. */
uip_ipaddr_copy(ipaddr, uip_draddr);
} else {
/* Else, we use the destination IP address. */
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
}
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
break;
}
}
if(i == UIP_ARPTAB_SIZE) {
/* The destination address was not in our ARP table, so we
overwrite the IP packet with an ARP request. */
memset(BUF->ethhdr.dest.addr, 0xff, 6);
memset(BUF->dhwaddr.addr, 0x00, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
uip_ipaddr_copy(BUF->dipaddr, ipaddr);
uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
BUF->protocol = HTONS(UIP_ETHTYPE_IP);
BUF->hwlen = 6;
BUF->protolen = 4;
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
uip_len = sizeof(struct arp_hdr);
return;
}
/* Build an ethernet header. */
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
}
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
uip_len += sizeof(struct uip_eth_hdr);
}
/*-----------------------------------------------------------------------------------*/
/** @} */
/** @} */

View File

@ -0,0 +1,152 @@
/**
* \addtogroup uip
* @{
*/
/**
* \addtogroup uiparp
* @{
*/
/**
* \file
* Macros and definitions for the ARP module.
* \author Adam Dunkels <adam@dunkels.com>
*/
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* 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 uIP TCP/IP stack.
*
* $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $
*
*/
#ifndef __UIP_ARP_H__
#define __UIP_ARP_H__
#include "uip.h"
extern struct uip_eth_addr uip_ethaddr;
/**
* The Ethernet header.
*/
#ifdef __ICCARM__
#pragma pack(1)
#endif
struct uip_eth_hdr {
struct uip_eth_addr dest;
struct uip_eth_addr src;
u16_t type;
}PACK_STRUCT_END;
#ifdef __ICCARM__
#pragma pack()
#endif
#define UIP_ETHTYPE_ARP 0x0806
#define UIP_ETHTYPE_IP 0x0800
#define UIP_ETHTYPE_IP6 0x86dd
/* The uip_arp_init() function must be called before any of the other
ARP functions. */
void uip_arp_init(void);
/* The uip_arp_ipin() function should be called whenever an IP packet
arrives from the Ethernet. This function refreshes the ARP table or
inserts a new mapping if none exists. The function assumes that an
IP packet with an Ethernet header is present in the uip_buf buffer
and that the length of the packet is in the uip_len variable. */
void uip_arp_ipin(void);
//#define uip_arp_ipin()
/* The uip_arp_arpin() should be called when an ARP packet is received
by the Ethernet driver. This function also assumes that the
Ethernet frame is present in the uip_buf buffer. When the
uip_arp_arpin() function returns, the contents of the uip_buf
buffer should be sent out on the Ethernet if the uip_len variable
is > 0. */
void uip_arp_arpin(void);
/* The uip_arp_out() function should be called when an IP packet
should be sent out on the Ethernet. This function creates an
Ethernet header before the IP header in the uip_buf buffer. The
Ethernet header will have the correct Ethernet MAC destination
address filled in if an ARP table entry for the destination IP
address (or the IP address of the default router) is present. If no
such table entry is found, the IP packet is overwritten with an ARP
request and we rely on TCP to retransmit the packet that was
overwritten. In any case, the uip_len variable holds the length of
the Ethernet frame that should be transmitted. */
void uip_arp_out(void);
/* The uip_arp_timer() function should be called every ten seconds. It
is responsible for flushing old entries in the ARP table. */
void uip_arp_timer(void);
/** @} */
/**
* \addtogroup uipconffunc
* @{
*/
/**
* Specifiy the Ethernet MAC address.
*
* The ARP code needs to know the MAC address of the Ethernet card in
* order to be able to respond to ARP queries and to generate working
* Ethernet headers.
*
* \note This macro only specifies the Ethernet MAC address to the ARP
* code. It cannot be used to change the MAC address of the Ethernet
* card.
*
* \param eaddr A pointer to a struct uip_eth_addr containing the
* Ethernet MAC address of the Ethernet card.
*
* \hideinitializer
*/
#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
uip_ethaddr.addr[1] = eaddr.addr[1];\
uip_ethaddr.addr[2] = eaddr.addr[2];\
uip_ethaddr.addr[3] = eaddr.addr[3];\
uip_ethaddr.addr[4] = eaddr.addr[4];\
uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
/** @} */
/** @} */
#endif /* __UIP_ARP_H__ */

View File

@ -0,0 +1,539 @@
/**
* \defgroup uipopt Configuration options for uIP
* @{
*
* uIP is configured using the per-project configuration file
* uipopt.h. This file contains all compile-time options for uIP and
* should be tweaked to match each specific project. The uIP
* distribution contains a documented example "uipopt.h" that can be
* copied and modified for each project.
*
* \note Most of the configuration options in the uipopt.h should not
* be changed, but rather the per-project uip-conf.h file.
*/
/**
* \file
* Configuration options for uIP.
* \author Adam Dunkels <adam@dunkels.com>
*
* This file is used for tweaking various configuration options for
* uIP. You should make a copy of this file into one of your project's
* directories instead of editing this example "uipopt.h" file that
* comes with the uIP distribution.
*/
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* 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 uIP TCP/IP stack.
*
* $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $
*
*/
#ifndef __UIPOPT_H__
#define __UIPOPT_H__
#ifndef UIP_LITTLE_ENDIAN
#define UIP_LITTLE_ENDIAN 3412
#endif /* UIP_LITTLE_ENDIAN */
#ifndef UIP_BIG_ENDIAN
#define UIP_BIG_ENDIAN 1234
#endif /* UIP_BIG_ENDIAN */
#include "uip-conf.h"
/*------------------------------------------------------------------------------*/
/**
* \name Static configuration options
* @{
*
* These configuration options can be used for setting the IP address
* settings statically, but only if UIP_FIXEDADDR is set to 1. The
* configuration options for a specific node includes IP address,
* netmask and default router as well as the Ethernet address. The
* netmask, default router and Ethernet address are appliciable only
* if uIP should be run over Ethernet.
*
* All of these should be changed to suit your project.
*/
/**
* Determines if uIP should use a fixed IP address or not.
*
* If uIP should use a fixed IP address, the settings are set in the
* uipopt.h file. If not, the macros uip_sethostaddr(),
* uip_setdraddr() and uip_setnetmask() should be used instead.
*
* \hideinitializer
*/
#define UIP_FIXEDADDR 0
/**
* Ping IP address asignment.
*
* uIP uses a "ping" packets for setting its own IP address if this
* option is set. If so, uIP will start with an empty IP address and
* the destination IP address of the first incoming "ping" (ICMP echo)
* packet will be used for setting the hosts IP address.
*
* \note This works only if UIP_FIXEDADDR is 0.
*
* \hideinitializer
*/
#ifdef UIP_CONF_PINGADDRCONF
#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF
#else /* UIP_CONF_PINGADDRCONF */
#define UIP_PINGADDRCONF 0
#endif /* UIP_CONF_PINGADDRCONF */
/**
* Specifies if the uIP ARP module should be compiled with a fixed
* Ethernet MAC address or not.
*
* If this configuration option is 0, the macro uip_setethaddr() can
* be used to specify the Ethernet address at run-time.
*
* \hideinitializer
*/
#define UIP_FIXEDETHADDR 0
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name IP configuration options
* @{
*
*/
/**
* The IP TTL (time to live) of IP packets sent by uIP.
*
* This should normally not be changed.
*/
#define UIP_TTL 64
/**
* Turn on support for IP packet reassembly.
*
* uIP supports reassembly of fragmented IP packets. This features
* requires an additonal amount of RAM to hold the reassembly buffer
* and the reassembly code size is approximately 700 bytes. The
* reassembly buffer is of the same size as the uip_buf buffer
* (configured by UIP_BUFSIZE).
*
* \note IP packet reassembly is not heavily tested.
*
* \hideinitializer
*/
#define UIP_REASSEMBLY 0
/**
* The maximum time an IP fragment should wait in the reassembly
* buffer before it is dropped.
*
*/
#define UIP_REASS_MAXAGE 40
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name UDP configuration options
* @{
*/
/**
* Toggles wether UDP support should be compiled in or not.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP
#define UIP_UDP UIP_CONF_UDP
#else /* UIP_CONF_UDP */
#define UIP_UDP 0
#endif /* UIP_CONF_UDP */
/**
* Toggles if UDP checksums should be used or not.
*
* \note Support for UDP checksums is currently not included in uIP,
* so this option has no function.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP_CHECKSUMS
#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS
#else
#define UIP_UDP_CHECKSUMS 0
#endif
/**
* The maximum amount of concurrent UDP connections.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP_CONNS
#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS
#else /* UIP_CONF_UDP_CONNS */
#define UIP_UDP_CONNS 10
#endif /* UIP_CONF_UDP_CONNS */
/**
* The name of the function that should be called when UDP datagrams arrive.
*
* \hideinitializer
*/
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name TCP configuration options
* @{
*/
/**
* Determines if support for opening connections from uIP should be
* compiled in.
*
* If the applications that are running on top of uIP for this project
* do not need to open outgoing TCP connections, this configration
* option can be turned off to reduce the code size of uIP.
*
* \hideinitializer
*/
#define UIP_ACTIVE_OPEN 1
/**
* The maximum number of simultaneously open TCP connections.
*
* Since the TCP connections are statically allocated, turning this
* configuration knob down results in less RAM used. Each TCP
* connection requires approximatly 30 bytes of memory.
*
* \hideinitializer
*/
#ifndef UIP_CONF_MAX_CONNECTIONS
#define UIP_CONNS 10
#else /* UIP_CONF_MAX_CONNECTIONS */
#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS
#endif /* UIP_CONF_MAX_CONNECTIONS */
/**
* The maximum number of simultaneously listening TCP ports.
*
* Each listening TCP port requires 2 bytes of memory.
*
* \hideinitializer
*/
#ifndef UIP_CONF_MAX_LISTENPORTS
#define UIP_LISTENPORTS 20
#else /* UIP_CONF_MAX_LISTENPORTS */
#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS
#endif /* UIP_CONF_MAX_LISTENPORTS */
/**
* Determines if support for TCP urgent data notification should be
* compiled in.
*
* Urgent data (out-of-band data) is a rarely used TCP feature that
* very seldom would be required.
*
* \hideinitializer
*/
#define UIP_URGDATA 0
/**
* The initial retransmission timeout counted in timer pulses.
*
* This should not be changed.
*/
#define UIP_RTO 3
/**
* The maximum number of times a segment should be retransmitted
* before the connection should be aborted.
*
* This should not be changed.
*/
#define UIP_MAXRTX 8
/**
* The maximum number of times a SYN segment should be retransmitted
* before a connection request should be deemed to have been
* unsuccessful.
*
* This should not need to be changed.
*/
#define UIP_MAXSYNRTX 5
/**
* The TCP maximum segment size.
*
* This is should not be to set to more than
* UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
*/
#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
/**
* The size of the advertised receiver's window.
*
* Should be set low (i.e., to the size of the uip_buf buffer) is the
* application is slow to process incoming data, or high (32768 bytes)
* if the application processes data quickly.
*
* \hideinitializer
*/
#ifndef UIP_CONF_RECEIVE_WINDOW
#define UIP_RECEIVE_WINDOW UIP_TCP_MSS
#else
#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW
#endif
/**
* How long a connection should stay in the TIME_WAIT state.
*
* This configiration option has no real implication, and it should be
* left untouched.
*/
#define UIP_TIME_WAIT_TIMEOUT 120
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name ARP configuration options
* @{
*/
/**
* The size of the ARP table.
*
* This option should be set to a larger value if this uIP node will
* have many connections from the local network.
*
* \hideinitializer
*/
#ifdef UIP_CONF_ARPTAB_SIZE
#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE
#else
#define UIP_ARPTAB_SIZE 8
#endif
/**
* The maxium age of ARP table entries measured in 10ths of seconds.
*
* An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
* default).
*/
#define UIP_ARP_MAXAGE 120
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name General configuration options
* @{
*/
/**
* The size of the uIP packet buffer.
*
* The uIP packet buffer should not be smaller than 60 bytes, and does
* not need to be larger than 1500 bytes. Lower size results in lower
* TCP throughput, larger size results in higher TCP throughput.
*
* \hideinitializer
*/
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_BUFSIZE 1500
#else /* UIP_CONF_BUFFER_SIZE */
#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE
#endif /* UIP_CONF_BUFFER_SIZE */
/**
* Determines if statistics support should be compiled in.
*
* The statistics is useful for debugging and to show the user.
*
* \hideinitializer
*/
#ifndef UIP_CONF_STATISTICS
#define UIP_STATISTICS 0
#else /* UIP_CONF_STATISTICS */
#define UIP_STATISTICS UIP_CONF_STATISTICS
#endif /* UIP_CONF_STATISTICS */
/**
* Determines if logging of certain events should be compiled in.
*
* This is useful mostly for debugging. The function uip_log()
* must be implemented to suit the architecture of the project, if
* logging is turned on.
*
* \hideinitializer
*/
#ifndef UIP_CONF_LOGGING
#define UIP_LOGGING 0
#else /* UIP_CONF_LOGGING */
#define UIP_LOGGING UIP_CONF_LOGGING
#endif /* UIP_CONF_LOGGING */
/**
* Broadcast support.
*
* This flag configures IP broadcast support. This is useful only
* together with UDP.
*
* \hideinitializer
*
*/
#ifndef UIP_CONF_BROADCAST
#define UIP_BROADCAST 0
#else /* UIP_CONF_BROADCAST */
#define UIP_BROADCAST UIP_CONF_BROADCAST
#endif /* UIP_CONF_BROADCAST */
/**
* Print out a uIP log message.
*
* This function must be implemented by the module that uses uIP, and
* is called by uIP whenever a log message is generated.
*/
void uip_log(char *msg);
/**
* The link level header length.
*
* This is the offset into the uip_buf where the IP header can be
* found. For Ethernet, this should be set to 14. For SLIP, this
* should be set to 0.
*
* \hideinitializer
*/
#ifdef UIP_CONF_LLH_LEN
#define UIP_LLH_LEN UIP_CONF_LLH_LEN
#else /* UIP_CONF_LLH_LEN */
#define UIP_LLH_LEN 14
#endif /* UIP_CONF_LLH_LEN */
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name CPU architecture configuration
* @{
*
* The CPU architecture configuration is where the endianess of the
* CPU on which uIP is to be run is specified. Most CPUs today are
* little endian, and the most notable exception are the Motorolas
* which are big endian. The BYTE_ORDER macro should be changed to
* reflect the CPU architecture on which uIP is to be run.
*/
/**
* The byte order of the CPU architecture on which uIP is to be run.
*
* This option can be either BIG_ENDIAN (Motorola byte order) or
* LITTLE_ENDIAN (Intel byte order).
*
* \hideinitializer
*/
#ifdef UIP_CONF_BYTE_ORDER
#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER
#else /* UIP_CONF_BYTE_ORDER */
#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN
#endif /* UIP_CONF_BYTE_ORDER */
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \name Appication specific configurations
* @{
*
* An uIP application is implemented using a single application
* function that is called by uIP whenever a TCP/IP event occurs. The
* name of this function must be registered with uIP at compile time
* using the UIP_APPCALL definition.
*
* uIP applications can store the application state within the
* uip_conn structure by specifying the type of the application
* structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.
*
* The file containing the definitions must be included in the
* uipopt.h file.
*
* The following example illustrates how this can look.
\code
void httpd_appcall(void);
#define UIP_APPCALL httpd_appcall
struct httpd_state {
u8_t state;
u16_t count;
char *dataptr;
char *script;
};
typedef struct httpd_state uip_tcp_appstate_t
\endcode
*/
/**
* \var #define UIP_APPCALL
*
* The name of the application function that uIP should call in
* response to TCP/IP events.
*
*/
/**
* \var typedef uip_tcp_appstate_t
*
* The type of the application state that is to be stored in the
* uip_conn structure. This usually is typedef:ed to a struct holding
* application state information.
*/
/**
* \var typedef uip_udp_appstate_t
*
* The type of the application state that is to be stored in the
* uip_conn structure. This usually is typedef:ed to a struct holding
* application state information.
*/
/** @} */
/** @} */
#endif /* __UIPOPT_H__ */

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2002, Adam Dunkels.
* 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 uIP TCP/IP stack
*
* $Id: webserver.h,v 1.2 2006/06/11 21:46:38 adam Exp $
*
*/
#ifndef __WEBSERVER_H__
#define __WEBSERVER_H__
#include "httpd.h"
typedef struct httpd_state uip_tcp_appstate_t;
/* UIP_APPCALL: the name of the application function. This function
must return void and take no arguments (i.e., C type "void
appfunc(void)"). */
#ifndef UIP_APPCALL
#define UIP_APPCALL httpd_appcall
#endif
#endif /* __WEBSERVER_H__ */