download.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 775 行 · 第 1/2 页

C
775
字号
/*****************************************************************************
*
*   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
*   ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
*   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
*   PARTICULAR PURPOSE.
*   Copyright (c) 1998 Hitachi,Ltd.
*
*   @doc EXTERNAL BOOTLOAD
*
*   @module download.c | Boot loader image downloader
*
*   @comm
*          Implements Image transfer using the bi-directional parallel port.
*          Takes care of CR-LF as well as CR-only combinations.
*
*   @topic  Image Down Loader |
*          The image down loader is responsible for downloading an image to the
*          target system.
*
*          On some systems, the ROM code can not be cached. To speedup downloading,
*          the ROM-resident loader (DownloadImage) will copy the section of code
*          handling download to be run out of cached region.
*
*          When the downloading code is to run out of cached RAM, the ROM loader
*          copies everything from pDownload to pDownloadEnd to RAM area and pass
*          control to it.
*
*          To acheive maximum performance, the code should be as self-contained
*          as possible within this section.
*
*          The ROM loader can as well as itself entirely into RAM area and execute
*          from there.  However, this could involve in copying too much code.
*
*          We want to reduce the amout of RAM used by the loader.
*
*          *** Important ***
*
*          The only external reference in the reloacatable download code is
*          ParallelPortRead().  This piece of code is also relocated.
*          In case more external references are added, they need to be relocated
*          too and should be called indirectly.
*
*          Also, since the code has to be relocatable even after the linking,
*          there should not be any near calls in the routine. That is why
*          pDownload() is a big routine.
*
*   @topic  PPFS Message Formats |
*          File server for embedded OS.
*
*          Message format: assume little endian, lower address first
*          -4      0      4     N-1       N        N+4
*          AA5555AA:header:data:checksum:5AA50A1A
*
*          Header Format:
*          0      2        4
*          opcode:length
*          lsb   msb
*
*          Length is 16 bit value. It includes all fields(==N)
*          Opcode is 16 bit value. Current values are:
*          0x0000 - boot (AA5555AA000000500FA5AA50A1A)
*          0x0001 - init
*          0x0002 - open
*          0x0003 - close
*          0x0004 - read
*          0x0005 - write
*          0x0006 - seek
*          0x0007 - delete
*          0x0008 - findfirst
*          0x0009 - findnext
*          0x000A - rRegGet
*          0x000B - rRegOpen
*          0x000C - rRegClose
*          0x000D - rRegEnum
*
*          Reply to a message will have the same opcode. Bit15 is set to
*          indicate transmission failure.
*
*          Data is stream of bytes(currently limited to 128 bytes)
*
*          Checksum is ~(sum of preceding N-1 bytes)
*
*          Length of data is (length) - 5
*/
#include <windows.h>
// #include <stdarg.h>
#include <loader.h>
// #include <oemfw.h>
#include <platform.h>
// #include <project.h>    // LED
#include "standalone.h"

#include "../../kernel/hal/mdppfs.c"

#define BIDI 1

// parallel port defines
#define SPPT_DATARDY    1

//      download return status codes
#define DL_SUCCESS                      0                       // successful download
#define DL_PARALLEL_ERROR       1                       // error on parallel port
#define DL_FLASH_ERROR          2                       // error on flash
#define DL_CHECKSUM_ERROR       3                       // checksum error
#define DL_TIMEOUT                      4                       // inactivity timeout

// flash status codes
#define FL_ADDRESS_ERROR        1

//
// Functional Prototypes
//
VOID OEMParallelPortSendByte(BYTE ch);
unsigned int OEMFlashWriteBegin(unsigned int ulPhysStart, unsigned int ulPhysLen);
unsigned int OEMFlashWriteEnd(void);
unsigned int OEMFlashWrite(unsigned int ulAddress, unsigned int ulValue);
unsigned int OEMFlashWriteStatus(unsigned int ulAddress);

int ParallelPortRead(unsigned char *pByteReceived, unsigned int cb);
unsigned DownloadSreFile(int pport); 

//
// Global defines and declarations
//
const unsigned char   BootHeader[] = {
        0xAA,                                                           // header = 4 bytes
        0x55,
        0x55,
        0xAA,
        0x00,                                                           // opcode = 2 bytes (0 = BOOT)
        0x00,
        };
#define BOOT_HEADER_SIZE (sizeof(BootHeader) / sizeof(BootHeader[0]))

const unsigned char   BootTail[] = {
        0x5A,                                                           // trail = 4 bytes
        0xA5,
        0x0A,
        0x1A
        };
#define BOOT_TAIL_SIZE (sizeof(BootTail) / sizeof(BootTail[0]))

const unsigned char   BootPacket[] = {
        0xAA,                                                           // header = 4 bytes
        0x55,
        0x55,
        0xAA,
        0x00,                                                           // opcode = 2 bytes (0 = BOOT)
        0x00,
        0x05,                                                           // length = 2 bytes
        0x00,
        0xFA,                                                           // checksum = 1 byte
        0x5A,                                                           // trail = 4 bytes
        0xA5,
        0x0A,
        0x1A
        };

#define BOOT_PACKET_SIZE (sizeof(BootPacket) / sizeof(BootPacket[0]))

const unsigned char   SyncBytes[] = {
        '0',
        '0',
        '0',
        'F',
        'F'
        };

#define SIZE_OF_SYNC_BYTES  7

unsigned int    ulPhysStart;                    // image physical starting address
unsigned int    ulPhysLen;                      // image physical length
unsigned char   *pFlashBuffer=NULL;             // flash input buffer address
unsigned char   *pFlashNext=NULL;               // flash input buffer next available
unsigned int    *pFlashOff;                     // start of next record
unsigned int    FlashBase;                      // flash base address
unsigned int blockAddress;                      // current block address
unsigned int bStalled;
unsigned int ulLaunch=0;                        // launch address

extern unsigned int ulRamBufStart;              // starting address of available RAM
extern unsigned int ulRamBufEnd;                // ending address of available RAM
extern BOOL NoPPFS;

//
// Routine starts
//
//  The ring buffer
static unsigned char * RingBuffer;

//  A pointer to the last byte in the ring buffer
static unsigned char * LastByte;

//  The current byte available in the ring buffer
static unsigned char * CurrByte;

//  The last available byte in the ring buffer
static unsigned char * LastAvailByte;

//  InitRingBuffer
//  Set the ring buffer to be empty
static void InitRingBuffer()
{
    ulRamBufStart&=0xdfffffff;
    ulRamBufEnd&=0xdfffffff;
    RingBuffer= (unsigned char *)ulRamBufStart;
    LastByte= (unsigned char *)ulRamBufEnd;
    CurrByte = LastAvailByte = RingBuffer;
    OutputFormatString("RingBuffer=%Xh LastByte=%Xh Currbyte=%Xh LastAvailByte=%Xh\r\n"
                                          ,RingBuffer,LastByte,CurrByte,LastAvailByte);
}

//  RingBufferFull
//  Predicate which determines if the ring buffer is full
static int RingBufferFull()
{
    return ((LastAvailByte + 1) == CurrByte) ||
            ((CurrByte == RingBuffer) &&
             (LastAvailByte == LastByte));
}

//  RingBufferHasData
//  Predicate to determine if the ring buffer has available data in it
static int RingBufferHasData()
{
    return (LastAvailByte != CurrByte);
}

//  InsertRingBuffer
//  Insert a character into the ring buffer.
//  N.B.  It is assumed that the ring buffer is not currently full
static void InsertRingBuffer(unsigned char ch)
{
    *LastAvailByte = ch;
    if (LastAvailByte == LastByte) {
        LastAvailByte = RingBuffer;
        OutputString("+");
    } else {
        ++LastAvailByte;
    }
}

//  RemoveRingBuffer
//  Remove and return a character from the ring buffer
//  N.B.  It is assumed that the ring buffer is not currently empty
static unsigned char RemoveRingBuffer()
{
    unsigned char ch = *CurrByte;

    if (CurrByte == LastByte) {
        OutputString("-");
        CurrByte = RingBuffer;
    } else {
        ++CurrByte;
    }
    return ch;
}


//***************************************************************************
//      ParallelPortRead - read bytes from parallel port
//
//      Syntax:
//
//    int
//    ParallelPortRead(
//        unsigned char * pByteReceived,
//        unsigned int    cb
//        );
//
//      Arguments:
//
//    pByteReceived (a0)  : points to the buffer to receive data
//    cb            (a1)  : number of bytes to read
//
//Return Value:
//
//    returns the number of bytes left to read (in our case, always 0)
//***************************************************************************
int ParallelPortRead(unsigned char *pByteReceived, unsigned int cb)
{
    int result;

// OutputFormatString("ParallelPortRead(pBR=%X, cb=%d)\r\n", pByteReceived, cb);
    while (cb && (result=OEMParallelPortGetByte()) != -1) {
        *pByteReceived++= (unsigned char)result;
		// OutputFormatString("[%x]",result); 
        cb--;
    }
//      if (result == -1)
//              return -1;
    return cb;
}

//////////////////////////////
int ParallelPortRead_debug(volatile unsigned char *pByteReceived, unsigned int cb)
{
    int result;

    while (cb && (result=OEMParallelPortGetByte()) != -1) {
        *pByteReceived++= (unsigned char)result;
		// OutputFormatString("[%x]",result); 
        cb--;
    }
//      if (result == -1)
//              return -1;
    return cb;
}


/*++

ParallelPortWrite:

    This routine has been optimized for parallel port output.

Syntax:

    int
    ParallelPortWrite(
        unsigned char * pByteReceived,
        unsigned int    cb
        );

Arguments:

    pByteReceived (a0)  : points to the buffer to send
    cb            (a1)  : number of bytes to send

Return Value:

    in v0, the number bytes left to write

--*/
//***************************************************************************
//      ParallelPortWrite
//***************************************************************************
int ParallelPortWrite(const unsigned char *pByteSend, unsigned int cb)
{
    while (cb--) {
        OEMParallelPortSendByte(*pByteSend++);
//        if (NoPPFS)
//            return -1;
    }
    return cb;
}


#if ((SH_PLATFORM == PLATFORM_ASPEN) || (SH_PLATFORM == PLATFORM_S1)||(SH_PLATFORM==PLATFORM_BIGSUR))

/* Need a buffer to store temporary flash data. */
#define FREE_RAM			0xade00000	// RAM Buffer for FLASH data. Starts at 14 Mb.

unsigned int Download2Flash(void)
{
	unsigned int	Vaddr;				// record starting address
	unsigned int	cbRecord;			// record length
	unsigned int	checksum;			// record checksu,
	unsigned int	ulCheckSum;			// computed checksum
	unsigned int	ulCheckOff;			// checksum index
	unsigned char	*pCheckSum;			// checksum pointer
	unsigned int	result, i;
										// record header buffer
	unsigned int	ParallelRecvBuffer[3];
	unsigned char *temp_buffer = (unsigned char *) FREE_RAM;

	while (1) {
										// Read in the starting address and length in bytes
		ParallelPortRead((unsigned char *)ParallelRecvBuffer, 3 * sizeof(unsigned int ));
		Vaddr = ParallelRecvBuffer[0];
		cbRecord = ParallelRecvBuffer[1];
		checksum = ParallelRecvBuffer[2];

// OutputFormatString("Vaddr=0x%x, cbRecord=0x%x, checksum=0x%x\r\n",Vaddr, cbRecord, checksum);

		if (Vaddr == 0L) {				// if this is the last record, launch it
			OutputFormatString("\r\nDownload to Flash successful...\r\n");
			OutputFormatString("Please switch off the platform, and flip the switch S1-1 for Flash boot\r\n  to run this image...\r\n");
			return 0;
		}
		// otherwise copy first to RAM buffer.
		if (cbRecord) {					// otherwise copy directly to RAM
			result= ParallelPortRead((unsigned char *)temp_buffer, cbRecord);

			// Now write it to FLASH.
			for(i = 0; i < cbRecord; i+=4) {
#if ((SH_PLATFORM == PLATFORM_ASPEN)||(SH_PLATFORM==PLATFORM_BIGSUR))

⌨️ 快捷键说明

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