📄 main_.c
字号:
// main.c
// 引导程序的主程序,在硬件初始化、自检完成后调用
// 所做的工作包括:
// 1、发送Boot Error信息
// 2、执行串口命令,若无命令,等待
/*
* 2001/5/14 paladin Xdown():If fail to getPacket,regetPacket.
* Xup():If fail to putPacket,reputPacket.
*/
#include "typedef.h"
#include "urt_extr.h"
#include "flash.h"
#define CTRL_CODE_ADDR1 0x380000 // xmodem load buffer
#define CTRL_CODE_ADDR 0xe0000 // CTRL in Flash (offset)
#define CTRL_CODE_LEN 0x1fff0 // 128K-16
#define DRAM_ADDR 0x0
#define CODEVER_ADDR 0x420
#define BOOTVER_ADDR 0x1000000F
//paladin
#define BLOCK_LEN 0x10000
#define TFSNAMESIZE 23 /* name that can be used in TFS. */
struct exec {
unsigned long a_crc; /* crc32 */
unsigned long a_text; /* text segment(loading address) */
unsigned long a_tsize; /* text size */
unsigned long a_entry; /* Entry point address */
unsigned long a_bss; /* bss segment */
unsigned long a_bsize; /* bss size */
unsigned long a_reserved[2]; /* align 16 */
};
/* struct xinfo:
* Used to contain information pertaining to the current transaction.
* The structure is built by the command Xmodem, then passed to the other
* support functions (Xup, Xdown, etc..) for reference and update.
*/
struct xinfo {
UCHAR sno; /* Sequence number. */
UCHAR pad; /* Unused, padding. */
int xfertot; /* Running total of transfer. */
int pktlen; /* Length of packet (128 or 1024). */
int pktcnt; /* Running tally of number of packets processed. */
int filcnt; /* Number of files transferred by ymodem. */
long size; /* Size of upload. */
ULONG flags; /* Storage for various runtime flags. */
ULONG base; /* Starting address for data transfer. */
ULONG dataddr; /* Running address for data transfer. */
int errcnt; /* Keep track of errors (used in verify mode). */
char *firsterrat; /* Pointer to location of error detected when */
/* transfer is in verify mode. */
char fname[TFSNAMESIZE];
};
/* Runtime flags: */
#define USECRC (1<<0)
#define VERIFY (1<<1)
#define YMODEM (1<<2)
/* Current xmodem operation: */
#define XNULL 0
#define XUP 1
#define XDOWN 2
/* X/Ymodem protocol: */
#define SOH 0x01
#define STX 0x02
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
#define CAN 0x18
#define ESC 0x1b
#define PKTLEN_128 128
#define PKTLEN_1K 1024
extern USHORT xcrc16tab[];
#pragma section CODE ".rtext"
static int Xup(struct xinfo *);
static int Xdown(struct xinfo *);
static int getPacket(UCHAR *,struct xinfo *);
static int putPacket(UCHAR *,struct xinfo *);
void download(void);
void upload(void);
void main( void);
#pragma section CODE
extern ULONG CRC32(UCHAR *buf, INT len);
extern void init_CRC32(void) ;
extern unsigned long crc32_table[];
extern int test_ram(void* addr,int len);
unsigned long comp_ver( char *main_ver, char *boot_ver);
//extern unsigned char INT_Version[];
//int flash_flag;
#pragma section DATA ".rinit"
static unsigned char Welcome_Message[] =
"\n"
"\tSTAR NETWORKS TECHNOLOGY CO.,LTD.\n"
"\tTel:(0591)3703333\n"
"\tFax:(0591)3702178\n"
"\tHttp:www.i-net.com.cn\n"
"\n\n"
"Xmodem file system is available.\n";
static char cmd_Msg[] =
"\n\t--- Boot Loader ---\n"
"\n1.Download Ctrl"
"\n2.Upload Flash"
"\nPlease input your choice[1/2]:";
static char *load_Msg[] = {
"\nSwitch Ctrl File download success.\n",
"\nSwitch Ctrl File length longer than 128K.\n",
"\nThe length in Switch CTRL File header is longer than 128K.",
"\nSwitch Ctrl File crc check error.\n",
//"\nS1924F+ Ctrl Maintenance interim software installed, entry point: 0x360000\nexecuting...\n",
//"\nS1924F+ Ctrl Maintenance software installed,\nexecuting...\n",
"\nExecuting...\n",
"\nFlash Upload OK.\n",
"\nPlease Downlaod again.\n",
"\nFlash write error.\n",
"\nXmodem downloading file...\n",
"\nXmodem uploading file...\n",
"\nCTRL version is old!\n",
(char *)0
};
static char Ctrl_fname[] =
"SWITCHFLASH.bin";
static int LoopsPerSecond = 800000;
struct xinfo xi;
int xmodemstart;
char packetbuf[1024];
#pragma section DATA
void main( void)
{
int i;
unsigned char *ptr;
UART_INIT uart_init;
unsigned char buf[10],ch;
// Init Flash
Init_Flash((unsigned short *)FLASH_BASE_ADDRESS);
//paladin
//erase ctrl flash erea
Flash_Erase((unsigned short *)FLASH_BASE_ADDRESS,CTRL_CODE_ADDR);
Flash_Erase((unsigned short *)FLASH_BASE_ADDRESS,CTRL_CODE_ADDR+BLOCK_LEN);
init_CRC32();
// 初始化uart2
uart_init.com_port = UART2;
uart_init.baud_rate = 57600;
uart_init.data_bits = DATA_BITS_8;
uart_init.stop_bits = STOP_BITS_1;
uart_init.parity = PARITY_NONE;
uart_init.data_mode = MODE_NORMAL;
uart_init.vect = 64;
UART_Init_Port(&uart_init);
// Send Welcome message
//UART_Put_String(Welcome_Message);
while(1)
{
UART_Put_String((UCHAR *)cmd_Msg);
ch = 0;
while(1)
{
if (UART_Data_Ready())
{
ch = UART_Get_Char();
break;
}
}
if (ch == '1' )
{
download();
Wait_10ms();
UART_Put_String((UCHAR *)load_Msg[6]);
}
else if (ch == '2')
{
upload();
Wait_10ms();
UART_Put_String((UCHAR *)load_Msg[5]);
}
while(UART_Data_Ready())
ch = UART_Get_Char();
}
}
void download(VOID)
{
unsigned char *sp,*dp;
int i,tmpsize,(*entry)();
unsigned long sptr,dptr;
struct exec *ehdr;
unsigned long crc;
char *main_ver,*boot_ver;
// clear buf
dp = (unsigned char *) CTRL_CODE_ADDR1; // DRAM ADDR
for (i = 0; i < CTRL_CODE_LEN + 16; i ++)
{
*dp++ = 0xff;
}
UART_Put_String((UCHAR *)load_Msg[8]);
xi.dataddr = xi.base = CTRL_CODE_ADDR1; // ctrl address
xi.fname[0] = 0;
xi.size = 0;
xi.flags = 0;
xi.filcnt = 0;
xi.pktlen = PKTLEN_128;
tmpsize = Xdown(&xi);
//for (i = 0 ; i < 100; i ++ )
// Wait_10ms();
if (tmpsize >= CTRL_CODE_LEN)
{
// size too long
UART_Put_String((UCHAR *)load_Msg[1]);
return ;
}
// Calculate CTRL CRC32
ehdr = (struct exec *) CTRL_CODE_ADDR1;
/* Return error if size = 0 or size not be fitted... */
//if ((!(ehdr->a_tsize))||((ehdr->a_tsize + sizeof(struct exec))!= tmpsize))
if (!(ehdr->a_tsize) )
{
UART_Put_String((UCHAR *)load_Msg[3]);
return ;
}
// Check crc
//tmpsize -= sizeof(long);
//tmpsize = ehdr->a_tsize - sizeof(long);
tmpsize = ehdr->a_tsize + sizeof(struct exec) - sizeof(long);
if( (tmpsize + 4) > CTRL_CODE_LEN )
{
UART_Put_String((UCHAR *)load_Msg[2]);
return;
}
if (crc32((UCHAR*)&ehdr->a_text,tmpsize) != ehdr->a_crc) {
UART_Put_String((UCHAR *)load_Msg[3]);
return ;
}
//Compare Version
main_ver = (char *)(CTRL_CODE_ADDR1 + CODEVER_ADDR);
boot_ver = (char *)BOOTVER_ADDR;
if( comp_ver( main_ver, boot_ver) == 0 )
{
UART_Put_String((UCHAR *)load_Msg[10]);
return;
}
// write data to flash
sptr = CTRL_CODE_ADDR1;
dptr = CTRL_CODE_ADDR;
while(1)
{
for(i = 0; i < FLASH_TIMES; i ++)
{
if(Flash_Erase((unsigned short *)FLASH_BASE_ADDRESS,(dptr & 0xffffff)))
continue; // Erase CTRL
if(Flash_Program((unsigned short *)FLASH_BASE_ADDRESS,
(unsigned short *)(FLASH_BASE_ADDRESS + dptr),
(unsigned short *)sptr, 0x8000) == 0)
break; // OK
}
if ( i == FLASH_TIMES)
{
UART_Put_String((UCHAR *)load_Msg[7]);
return ;
}
sptr += 0x10000;
dptr += 0x10000;
if (dptr >= FLASH_MEMORY_SIZE)
break;
}
UART_Put_String((UCHAR *)load_Msg[0]);
/* Establish locations from which text and data are to be */
/* copied from ... */
sp = (UCHAR *)(ehdr+1);
dp = (UCHAR *)ehdr->a_text;
/* Copy text and data sections to RAM: */
for (i = 0; i < ehdr->a_tsize; i ++)
*dp ++ = *sp ++;
UART_Put_String((UCHAR *)load_Msg[4]);
entry = (int(*)())ehdr->a_entry;
//asm(" MOVE.W #$2700,SR");
entry();
}
// upload the whole flash
void upload(void)
{
int i;
UART_Put_String((UCHAR *)load_Msg[9]);
xi.dataddr = xi.base = FLASH_BASE_ADDRESS;
xi.size = FLASH_MEMORY_SIZE;
xi.fname[0] = 0;
xi.flags = 0;
xi.filcnt = 0;
xi.pktlen = PKTLEN_128;
Xup(&xi);
for ( i = 0; i< 100; i ++)
Wait_10ms();
}
/* sendSohSno():
* Common function used to send the initial startup messages for X/Ymodem
*/
void
sendSohSno(struct xinfo *xip)
{
if ((xip->pktlen == PKTLEN_128) || (xmodemstart && (xip->sno == 0)))
UART_Put_Char(SOH);
else
UART_Put_Char(STX);
UART_Put_Char(xip->sno);
UART_Put_Char((UCHAR)~(xip->sno));
}
/* putPacket():
* Used by Xup to send packets.
*/
int
putPacket(UCHAR *tmppkt, struct xinfo *xip)
{
int i;
UCHAR *cp,c;
USHORT chksm;
cp = (UCHAR *)&chksm;
chksm = 0;
sendSohSno(xip);
if (xip->flags & USECRC) {
for(i=0;i<xip->pktlen;i++) {
UART_Put_Char(*tmppkt);
chksm = (chksm<<8)^xcrc16tab[(chksm>>8)^*tmppkt++];
}
UART_Put_Char(cp[0]);
UART_Put_Char(cp[1]);
}
else {
for(i=0;i<xip->pktlen;i++) {
UART_Put_Char(*tmppkt);
chksm = ((chksm+*tmppkt++)&0xff);
}
UART_Put_Char((UCHAR)(chksm&0x00ff));
}
/* Wait for ack */
if (!UART_Get_Char1(&c))
{
if(!UART_Get_Char1(&c))
return -1;
}
if (xmodemstart) {
if (xip->sno == 0)
if (!UART_Get_Char1(&c))
return -1;
xmodemstart = 0;
}
return(c);
}
/* getPacket():
* Used by Xdown to retrieve packets.
*/
static int
getPacket(UCHAR *tmppkt, struct xinfo *xip)
{
int i;
char *pkt;
UCHAR seq[2];
UART_Get_Bytes(seq,2,1);
#ifdef _XMODEM_DEBUG
Mtrace("*");
#endif
if (xip->flags & VERIFY) {
UART_Get_Bytes(tmppkt,xip->pktlen,1);
for(i=0;i<xip->pktlen;i++) {
if (tmppkt[i] != ((char *)xip->dataddr)[i]) {
if (xip->errcnt++ == 0)
xip->firsterrat = (char *)(xip->dataddr+i);
}
}
pkt = (char *)tmppkt;
}
else {
UART_Get_Bytes((UCHAR *)xip->dataddr,xip->pktlen,1);
pkt = (char *)xip->dataddr;
}
#ifdef _XMODEM_DEBUG
Mtrace("*");
#endif
if (xip->flags & USECRC) {
USHORT crc, xcrc;
UCHAR *cp;
cp = (UCHAR *)&crc;
UART_Get_Char1(cp);
UART_Get_Char1(cp+1);
xcrc = xcrc16((UCHAR *)pkt,(ULONG)(xip->pktlen));
if (crc != xcrc) {
UART_Put_Char(CAN);
#ifdef _XMODEM_DEBUG
Mtrace("1 %04x != %04x",crc,xcrc);
#endif
return(-1);
}
}
else {
UCHAR csum, xcsum;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -