⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ser2enet.c

📁 ARM CORTEX L3M6XXX CPU 以太网 lwip 源码
💻 C
📖 第 1 页 / 共 4 页
字号:
//*****************************************************************************
//
// ser2enet.c - Serial to Ethernet converter.
//
// Copyright (c) 2007 Luminary Micro, Inc.  All rights reserved.
// 
// Software License Agreement
// 
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
// 
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws.  All rights are reserved.  You may not combine
// this software with "viral" open-source software in order to form a larger
// program.  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.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
// 
// This is part of revision 195 of the Serial to Ethernet Converter.
//
//*****************************************************************************

#include "../../hw_ints.h"
#include "../../hw_memmap.h"
#include "../../hw_types.h"
#include "../../src/ethernet.h"
#include "../../src/flash.h"
#include "../../src/gpio.h"
#include "../../src/interrupt.h"
#include "../../src/sysctl.h"
#include "../../src/systick.h"
#include "../../src/uart.h"
#include "lwip/api.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/stats.h"
#include "lwip/sys.h"
#include "lwip/tcpip.h"
#include "netif/etharp.h"
#include "config.h"
#include "luminaryif.h"
#include "telnet.h"

//*****************************************************************************
//
//! \page ser2enet_intro Introduction
//!
//! The Serial to Ethernet Converter provides a means of accessing the UART on
//! a Stellaris device via a network connection.  The UART can be connected to
//! the UART on a non-networked device, providing the ability to access the
//! device via a network.  This can be useful to overcome the cable length
//! limitations of a UART connection (in fact, the cable can become thousands
//! of miles long) and to provide networking capability to existing devices
//! without modifing the device's operation.
//!
//! The telnet protocol (as defined by RFC854) is used to make the connection
//! across the network.  The Serial to Ethernet Converter provides the telnet
//! server, and a connection is made to the converter using a telnet client.
//! In its simplest form, a telnet client is simply a TCP connect to the
//! appropriate port.  Telnet interprets 0xff as a command indicator (known as
//! the Interpret As Command, or IAC, byte).  Consecutive IAC bytes are used to
//! transfer an actual 0xff byte; thus, the only special processing required is
//! to translate 0xff to 0xff 0xff when sending, and to translate 0xff 0xff to
//! 0xff when receiving.
//!
//! The WILL, WONT, DO, DONT option negotiation protocol is also imlpemented.
//! This is a simple means of determining if capabilities are present, and for
//! enabling or disabling features that do not require configuration.  Through
//! the use of this negotiation protocol, telnet clients and servers are able
//! to easily match capabilities and avoid trying to configure features that
//! are not shared by both ends of the connection (which would therefore result
//! in the negotiation sequence being sent as actual data instead of being
//! absorbed by the client or server).
//!
//! In this implementation, only the SUPPRESS_GA option is supported; all other
//! options are negatively responded to in order to prevent the client from
//! trying to use them.
//!
//! The converter can be configured to use a static IP configuration or to use
//! DHCP to obtain its IP configuration.  Since the converter is providing a
//! telnet server, the effective use of DHCP requires a reservation in the DHCP
//! server so that the converter gets the same IP address each time it is
//! connected to the network.
//
//*****************************************************************************

//*****************************************************************************
//
//! \defgroup ser2enet_api Definitions
//! @{
//
//*****************************************************************************

//*****************************************************************************
//
//! The number of times per second that the SysTick timer generates a processor
//! interrupt.
//
//*****************************************************************************
#define SYSTICKHZ               100

//*****************************************************************************
//
//! The number of milliseconds between SysTick generated processor interrupts.
//
//*****************************************************************************
#define SYSTICKMS               (1000 / SYSTICKHZ)

//*****************************************************************************
//
//! The bit in #g_ulFlags that indicates that a SysTick interrupt has occurred.
//
//*****************************************************************************
#define FLAG_SYSTICK            0

//*****************************************************************************
//
//! The bit in #g_ulFlags that indicates that an Ethernet controller interrupt
//! has occurred.
//
//*****************************************************************************
#define FLAG_RXPKT              1

//*****************************************************************************
//
//! The bit in #g_ulFlags that indicates that a UART receive interrupt has
//! occurred.
//
//*****************************************************************************
#define FLAG_RXUART             2

//*****************************************************************************
//
//! A set of flags that indicate the occurrence of interrupts.  The bits in
//! this word are defined by #FLAG_SYSTICK, #FLAG_RXPKT, and #FLAG_RXUART.
//
//*****************************************************************************
static volatile unsigned long g_ulFlags;

//*****************************************************************************
//
//! The possible states of the telnet option parser.
//
//*****************************************************************************
typedef enum
{
    //
    //! The telnet option parser is in its normal mode.  Characters are passed
    //! as is until an IAC byte is received.
    //
    STATE_NORMAL,

    //
    //! The previous character received by the telnet option parser was an IAC
    //! byte.
    //
    STATE_IAC,

    //
    //! The previous character sequence received by the telnet option parser
    //! was IAC WILL.
    //
    STATE_WILL,

    //
    //! The previous character sequence received by the telnet option parser
    //! was IAC WONT.
    //
    STATE_WONT,

    //
    //! The previous character sequence received by the telnet option parser
    //! was IAC DO.
    //
    STATE_DO,

    //
    //! The previous character sequence received by the telnet option parser
    //! was IAC DONT.
    //
    STATE_DONT
}
tTelnetState;

//*****************************************************************************
//
//! The current state of the telnet option parser.
//
//*****************************************************************************
static tTelnetState g_eState;

//*****************************************************************************
//
//! A structure that contains the state of the options supported by the telnet
//! server, along with the possible flags.
//
//*****************************************************************************
typedef struct
{
    //
    //! The option byte.
    //
    unsigned char ucOption;

    //
    //! The flags for this option.  The bits in this byte are defined by
    //! OPT_FLAG_WILL and OPT_FLAG_DO.
    //
    unsigned char ucFlags;
}
tTelnetOpts;

//*****************************************************************************
//
//! The bit in the ucFlags member of #tTelnetOpts that is set when the remote
//! client has sent a WILL request and the server has accepted it.
//
//*****************************************************************************
#define OPT_FLAG_WILL           1

//*****************************************************************************
//
//! The bit in the ucFlags member of #tTelnetOpts that is set when the remote
//! client has sent a DO request and the server has accepted it.
//
//*****************************************************************************
#define OPT_FLAG_DO             2

//*****************************************************************************
//
//! The telnet options supported by this server.
//
//*****************************************************************************
static tTelnetOpts g_psOptions[] =
{
    //
    // This telnet server will always suppress go ahead generation, regardless
    // of this setting.
    //
    { TELNET_OPT_SUPPRESS_GA, (1 << OPT_FLAG_WILL) },
};

//*****************************************************************************
//
//! The initialization sequence sent to a remote telnet client when it first
//! connects to the telnet server.
//
//*****************************************************************************
static const unsigned char g_pucTelnetInit[] =
{
    TELNET_IAC, TELNET_DO, TELNET_OPT_SUPPRESS_GA
};

//*****************************************************************************
//
//! The lwIP network interface structure for the Stellaris Ethernet controller.
//
//*****************************************************************************
static struct netif g_sEMAC_if;

//*****************************************************************************
//
//! The lwIP TCP fast timer, used to determine the rate at which to call
//! tcp_fasttmr().
//
//*****************************************************************************
static unsigned long g_ulTCPFastTimer = 0;

//*****************************************************************************
//
//! The lwIP TCP slow timer, used to determine the rate at which to call
//! tcp_slowtimer().
//
//*****************************************************************************
static unsigned long g_ulTCPSlowTimer = 0;

//*****************************************************************************
//
//! The lwIP ARP timer, used to determine the rate at which to call
//! etharp_tmr().
//
//*****************************************************************************
static unsigned long g_ulARPTimer = 0;

//*****************************************************************************
//
//! The lwIP DHCP coarse timer, used to determine the rate at which to call
//! dhcp_coarse_tmr().
//
//*****************************************************************************
#if defined(USE_DHCP) || defined(DOXYGEN)
static unsigned long g_ulDHCPCoarseTimer = 0;
#endif

//*****************************************************************************
//
//! The lwIP DHCP fine timer, used to determine the rate at which to call
//! dhcp_fine_tmr().
//
//*****************************************************************************
#if defined(USE_DHCP) || defined(DOXYGEN)
static unsigned long g_ulDHCPFineTimer = 0;
#endif

//*****************************************************************************
//
//! The size of the buffers used for transmitting to and receiving from the
//! UART.
//
//*****************************************************************************
#define UART_BUF_SIZE           256

//*****************************************************************************
//
//! The buffer used to hold characters received from the UART.
//
//*****************************************************************************
static unsigned char g_pucRXBuffer[UART_BUF_SIZE];

//*****************************************************************************
//
//! The buffer used to hold characters to be sent to the UART.
//
//*****************************************************************************
static unsigned char g_pucTXBuffer[UART_BUF_SIZE];

//*****************************************************************************
//
//! The offset into the UART receive buffer (#g_pucRXBuffer) where the next
//! character is to be read.  The buffer is empty when this is equal to the
//! write offset (#g_ulRXWrite), and is full when the write offset is one
//! character behind the read offset (modulo the buffer size).
//
//*****************************************************************************
static unsigned long g_ulRXRead;

//*****************************************************************************
//
//! The offset into the UART receive buffer (#g_pucRXBuffer) where the next
//! character is to be written.  The buffer is empty when this is equal to the
//! read offset (#g_ulRXRead), and is full when the write offset is one
//! character behind the read offset (modulo the buffer size).
//
//*****************************************************************************
static unsigned long g_ulRXWrite;

//*****************************************************************************
//
//! The offset into the UART transmit buffer (#g_pucTXBuffer) where the next
//! character is to be read.  The buffer is empty when this is equal to the
//! write offset (#g_ulTXWrite), and is full when the write offset is one
//! character behind the read offset (modulo the buffer size).
//
//*****************************************************************************
static unsigned long g_ulTXRead;

//*****************************************************************************
//
//! The offset into the UART transmit buffer (#g_pucTXBuffer) where the next
//! character is to be written.  The buffer is empty when this is equal to the
//! read offset (#g_ulTXRead), and is full when the write offset is one
//! character behind the read offset (modulo the buffer size).
//
//*****************************************************************************
static unsigned long g_ulTXWrite;

//*****************************************************************************
//
//! A buffer used to construct a packet of data to be transmitted to the telnet
//! client.
//
//*****************************************************************************
static unsigned char g_pucTelnetBuffer[512];

//*****************************************************************************
//
//! The number of bytes of valid data in the telnet packet buffer
//! (#g_pucTelnetBuffer).
//
//*****************************************************************************
static unsigned long g_ulTelnetLength;

//*****************************************************************************
//
//! A pointer to the telnet session PCB data structure.
//
//*****************************************************************************
static struct tcp_pcb *g_psTelnetPCB = NULL;

//*****************************************************************************
//
//! A counter for the TCP connection timeout.
//
//*****************************************************************************
#if TELNET_TIMEOUT || defined(DOXYGEN)
static unsigned long g_ulConnectionTimeout;
#endif

//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif

//*****************************************************************************
//
//! Handles the SysTick interrupt.
//!
//! This function is called when the SysTick timer expires.  It increments the
//! lwIP timers and sets a flag indicating that the timeout functions need to
//! be called if necessary.
//!
//! \return None.
//
//*****************************************************************************
void
SysTickIntHandler(void)
{
    //
    // Increment the assorted timers.
    //
    g_ulTCPFastTimer += SYSTICKMS;
    g_ulTCPSlowTimer += SYSTICKMS;
    g_ulARPTimer += SYSTICKMS;
#ifdef USE_DHCP
    g_ulDHCPCoarseTimer += SYSTICKMS;
    g_ulDHCPFineTimer += SYSTICKMS;
#endif

    //
    // Indicate that a SysTick has occurred.
    //
    HWREGBITW(&g_ulFlags, FLAG_SYSTICK) = 1;
}

//*****************************************************************************
//
//! Handles the Ethernet interrupt.
//!
//! This function is called when the Ethernet controller generates an interrupt
//! as a result of the reception of a packet.  It sets a flag indicating that
//! lwIP should read the packet when possible.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetIntHandler(void)
{
    unsigned long ulTemp;

    //
    // Read and clear the interrupt(s).
    //
    ulTemp = EthernetIntStatus(ETH_BASE, false);
    EthernetIntClear(ETH_BASE, ulTemp);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -