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 + -
显示快捷键?