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

📄 bl_enet.c

📁 基于周立功公司的EasyARM615开发套件的串口驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
//*****************************************************************************
//
// bl_enet.c - Functions to update via Ethernet.
//
// 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 1928 of the Stellaris Peripheral Driver Library.
//
//*****************************************************************************

#include "../hw_ethernet.h"
#include "../hw_flash.h"
#include "../hw_gpio.h"
#include "../hw_memmap.h"
#include "../hw_nvic.h"
#include "../hw_sysctl.h"
#include "../hw_types.h"
#include "bl_config.h"
#include "bl_decrypt.h"

//*****************************************************************************
//
// If using Ethernet update, make sure that the crystal frequency is defined.
//
//*****************************************************************************
#if defined(ENET_ENABLE_UPDATE) && !defined(CRYSTAL_FREQ)
#error ERROR: CRYSTAL_FREQ must be defined for Ethernet update!
#endif

//*****************************************************************************
//
// If using Ethernet update, issue a warning if boot loader update is enabled
// (it is not supported via BOOTP given that there is no way to distinguish
// between a normal firmware image and a boot loader update image).
//
//*****************************************************************************
#if defined(ENET_ENABLE_UPDATE) && defined(ENABLE_BL_UPDATE)
#error ERROR: Updating the boot loader is not supported over Ethernet!
#endif

//*****************************************************************************
//
// Directly include the uIP code if using Ethernet for the update.  This allows
// non-Ethernet boot loader builds to not have to supply the uip-conf.h file
// that would otherwise be required.
//
//*****************************************************************************
#if defined(ENET_ENABLE_UPDATE)
#include "../third_party/uip-1.0/uip/pt.h"
#include "../third_party/uip-1.0/uip/uip_arp.c"
#undef BUF
#include "../third_party/uip-1.0/uip/uip.c"
#endif

//*****************************************************************************
//
//! \addtogroup boot_loader_api
//! @{
//
//*****************************************************************************
#if defined(ENET_ENABLE_UPDATE) || defined(DOXYGEN)

//*****************************************************************************
//
// A prototype for the function (in the startup code) for a predictable length
// delay.
//
//*****************************************************************************
extern void Delay(unsigned long ulCount);

//*****************************************************************************
//
// Defines for setting up the system clock.
//
//*****************************************************************************
#define SYSTICKHZ               100
#define SYSTICKMS               (1000 / SYSTICKHZ)

//*****************************************************************************
//
// UIP Timers (in ms)
//
//*****************************************************************************
#define UIP_PERIODIC_TIMER_MS   50
#define UIP_ARP_TIMER_MS        10000

//*****************************************************************************
//
// This structure defines the fields in a BOOTP request/reply packet.
//
//*****************************************************************************
typedef struct
{
    //
    // The operation; 1 is a request, 2 is a reply.
    //
    unsigned char ucOp;

    //
    // The hardware type; 1 is Ethernet.
    //
    unsigned char ucHType;

    //
    // The hardware address length; for Ethernet this will be 6, the length of
    // the MAC address.
    //
    unsigned char ucHLen;

    //
    // Hop count, used by gateways for cross-gateway booting.
    //
    unsigned char ucHops;

    //
    // The transaction ID.
    //
    unsigned long ulXID;

    //
    // The number of seconds elapsed since the client started trying to boot.
    //
    unsigned short usSecs;

    //
    // The BOOTP flags.
    //
    unsigned short usFlags;

    //
    // The client's IP address, if it knows it.
    //
    unsigned long ulCIAddr;

    //
    // The client's IP address, as assigned by the BOOTP server.
    //
    unsigned long ulYIAddr;

    //
    // The TFTP server's IP address.
    //
    unsigned long ulSIAddr;

    //
    // The gateway IP address, if booting cross-gateway.
    //
    unsigned long ulGIAddr;

    //
    // The hardware address; for Ethernet this is the MAC address.
    //
    unsigned char pucCHAddr[16];

    //
    // The name, or nickname, of the server that should handle this BOOTP
    // request.
    //
    char pcSName[64];

    //
    // The name of the boot file to be loaded via TFTP.
    //
    char pcFile[128];

    //
    // Optional vendor-specific area; not used for BOOTP.
    //
    unsigned char pucVend[64];
}
tBOOTPPacket;

//*****************************************************************************
//
// The BOOTP commands.
//
//*****************************************************************************
#define BOOTP_REQUEST           1
#define BOOTP_REPLY             2

//*****************************************************************************
//
// The TFTP commands.
//
//*****************************************************************************
#define TFTP_RRQ                1
#define TFTP_WRQ                2
#define TFTP_DATA               3
#define TFTP_ACK                4
#define TFTP_ERROR              5

//*****************************************************************************
//
// The UDP ports used by the BOOTP protocol.
//
//*****************************************************************************
#define BOOTP_SERVER_PORT       67
#define BOOTP_CLIENT_PORT       68

//*****************************************************************************
//
// The UDP port for the TFTP server.
//
//*****************************************************************************
#define TFTP_PORT               69

//*****************************************************************************
//
// The MAC address of the Ethernet interface.
//
//*****************************************************************************
#ifdef ENET_MAC_ADDR0
static struct uip_eth_addr g_sMACAddr =
{
    {
        ENET_MAC_ADDR0,
        ENET_MAC_ADDR1,
        ENET_MAC_ADDR2,
        ENET_MAC_ADDR3,
        ENET_MAC_ADDR4,
        ENET_MAC_ADDR5
    }
};
#else
static struct uip_eth_addr g_sMACAddr;
#endif

//*****************************************************************************
//
// The number of SysTick interrupts since the start of the boot loader.
//
//*****************************************************************************
static unsigned long g_ulTicks;

//*****************************************************************************
//
// The seed for the random number generator.
//
//*****************************************************************************
static unsigned long g_ulRandomSeed;

//*****************************************************************************
//
// The number of milliseconds since the last call to uip_udp_periodic().
//
//*****************************************************************************
static volatile unsigned long g_ulPeriodicTimer;

//*****************************************************************************
//
// The number of milliseconds since the last call to uip_arp_timer().
//
//*****************************************************************************
static volatile unsigned long g_ulARPTimer;

//*****************************************************************************
//
// The transaction ID of the most recently sent out BOOTP request.
//
//*****************************************************************************
static unsigned long g_ulXID;

//*****************************************************************************
//
// The state for the proto-thread that handles the BOOTP process.
//
//*****************************************************************************
static struct pt g_sThread;

//*****************************************************************************
//
// The amount of time to wait for a BOOTP reply before sending out a new BOOTP
// request.
//
//*****************************************************************************
static unsigned long g_ulDelay;

//*****************************************************************************
//
// The target time (relative to g_ulTicks) when the next timeout occurs.
//
//*****************************************************************************
static unsigned long g_ulTarget;

//*****************************************************************************
//
// The IP address of the TFTP server.
//
//*****************************************************************************
static uip_ipaddr_t g_sServerAddr;

//*****************************************************************************
//
// The name of the file to be read from the TFTP server.
//
//*****************************************************************************
static char g_pcFilename[128];

//*****************************************************************************
//
// The end of flash.  If there is not a reserved block at the end of flash,
// this is the real end of flash.  If there is a reserved block, this is the
// start of the reserved block (i.e. the virtual end of flash).
//
//*****************************************************************************
static unsigned long g_ulFlashEnd;

//*****************************************************************************
//
// The current block being read from the TFTP server.
//
//*****************************************************************************
static unsigned long g_ulTFTPBlock;

//*****************************************************************************
//
// The UDP socket used to communicate with the BOOTP and TFTP servers (in
// sequence).
//
//*****************************************************************************
struct uip_udp_conn *g_pConn;

//*****************************************************************************
//
// uIP uses memset, so a simple one is provided here.  This is not as efficient
// as the one in the C library (from an execution time perspective), but it is
// much smaller.
//
//*****************************************************************************
void *
memset(void *pvDest, int iChar, size_t lLength)
{
    char *pcBuf = (char *)pvDest;

    //
    // Fill the buffer with the given character.
    //
    while(lLength--)
    {
        *pcBuf++ = iChar;
    }

    //
    // Return a pointer to the beginning of the buffer.
    //
    return(pvDest);
}

//*****************************************************************************
//
// uIP uses memcpy, so a simple one is provided here.  This is not as efficient
// as the one in the C library (from an execution time perspective), but it is
// much smaller.
//
//*****************************************************************************
void *
memcpy(void *pvDest, const void *pvSrc, size_t lLength)
{
    const char *pcSrc = (const char *)pvSrc;
    char *pcDest = (char *)pvDest;

    //
    // Copy bytes from the source buffer to the destination buffer.
    //
    while(lLength--)
    {
        *pcDest++ = *pcSrc++;
    }

    //
    // Return a pointer to the beginning of the destination buffer.
    //
    return(pvDest);
}

//*****************************************************************************
//
//! Handles the SysTick interrupt.
//!
//! This function is called when the SysTick interrupt occurs.  It simply
//! keeps a running count of interrupts, used as a time basis for the BOOTP and
//! TFTP protocols.
//!
//! This function is contained in <tt>bl_enet.c</tt>.
//!
//! \return None.
//
//*****************************************************************************
void
SysTickIntHandler(void)
{
    //
    // Increment the tick count.
    //
    g_ulTicks++;
    g_ulPeriodicTimer += SYSTICKMS;
    g_ulARPTimer += SYSTICKMS;
}

//*****************************************************************************
//
//! Computes a new random number.
//!
//! This function computes a new pseudo-random number, using a linear
//! congruence random number generator.  Note that if the entire 32-bits of the
//! produced random number are not being used, the upper N bits should be used
//! instead of the lower N bits as they are much more random (for example, use
//! ``RandomNumber() >> 28'' instead of ``RandomNumber() & 15'').
//!
//! This function is contained in <tt>bl_enet.c</tt>.
//!
//! \return Returns a 32-bit pseudo-random number.
//
//*****************************************************************************
static unsigned long
RandomNumber(void)
{
    //
    // Generate a new pseudo-random number with a linear congruence random
    // number generator.  This new random number becomes the seed for the next
    // random number.
    //
    g_ulRandomSeed = (g_ulRandomSeed * 1664525) + 1013904223;

    //
    // Return the new random number.
    //
    return(g_ulRandomSeed);
}

//*****************************************************************************
//
//! Reads a packet from the Ethernet controller.
//!
//! This function reads a packet from the Ethernet controller into the uIP
//! packet buffer.  It assumes that a packet is available to be read.
//!
//! This function is contained in <tt>bl_enet.c</tt>.
//!
//! \return None.
//
//*****************************************************************************
static void
EnetReadPacket(void)
{
    unsigned long ulTemp;
    long lIdx, lCount;

    //
    // Read the first word from the FIFO.
    //
    ulTemp = HWREG(ETH_BASE + MAC_O_DATA);

    //
    // Extract the size of the remainder of the packet.
    //
    lCount = (ulTemp & 0xffff) - 4;

    //
    // See if the packet will fit into the data buffer.
    //
    if(lCount > (sizeof(uip_buf) + 2))
    {
        //
        // The packet will not fit into the data buffer, so read the rest of
        // the data and throw it away.
        //
        while(lCount > 0)
        {
            HWREG(ETH_BASE + MAC_O_DATA);
            lCount -= 4;
        }

        //
        // There is no packet for uIP to process.
        //
        uip_len = 0;

        //
        // Return without any further processing.
        //
        return;
    }

    //
    // Copy the first two bytes into the packet buffer.
    //
    *(unsigned short *)uip_buf = ulTemp >> 16;

    //
    // Save the packet length for uIP's use.
    //
    uip_len = lCount - 2;

    //
    // Read the remainder of the packet data into uIP's buffer.
    //

⌨️ 快捷键说明

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