bootloader开发在嵌入式开发中是一个不可或缺的存在,就像bios /pc ,uboot/linux ,虽然现在的软件组件都是很成熟发达了。但是要深入嵌入式的本质还是需要从裸机开始,知道cpu是怎么启动,怎么中断跳转,怎么实现内核加载的,bootloader的编写基本上就可以覆盖这些内容。
以下是嵌入式程序在flash中分布的地址分配图,mcu在启动时会从0地址开始(也可能是一个其他什么固定地址,)运行第一行代码,这个代码一般是cpu自带的,她负责设置初始化并跳转指令将控制权交给程序员,程序员通过启动代码(汇编语言),设置堆栈以及中断向量表,然后将控制权跳转到c语言的man函数,在从里面我们就可以编写逻辑实现跟上位机交互获取固件文件并写入flash对应的地址区域,在每次启动时bootlaod先判断固件所在的区域程序是否完整,如果完整就将固件装载到ram中,然后跳转到内存的固件起始地址,并将控制权交由固件,如果没有发现固件就就进入shell等待交互,这一过程适用于所有的操作系统启动,只是复杂程度,外设驱动初始化不一样,其原理都差不多。
//片内flash为512k bytes 4k*128page
//0x9D07FFFF--0x9D000000 Program Flash
//
// PFM KERNEL AND USER MODE MAPPING
// Virtual Address Physical Address
// --------------- ----------------
// 0xBFC0_2FEF or ***************** 0x1FC0_2FEF
// 0X9FC0_2FEF * *
// * *
// * Boot Flash *
// 0xBFC0_0000 or * *
// 0x9FC0_0000 ***************** 0x1FC0_0000// 0xBD07_FFFF or ***************** 0x1D07_FFFF
// 0x9D07_FFFF * * BL_CSUM_ADDR 0x1D07_FFF4
// * * BL_PROGSZ_ADDR 0x1D07_FFF0
// 0xBD07_E000 or ***************** 0x1D07_E000
// 0x9D07_E000 * *
// * User App * 500k User app
// * *
// * Program *
// * Flash *
// * *
// 0x9D00_1000 ***************** 0x1D00_1000//4k bootloader
// * BootLoader *
// 0xBD00_0000 or * *
// 0x9D00_0000 ***************** 0x1D00_0000**********************************************************************/
启动代码是mcu厂家提供的demo,我们可以在这个里面进行按需更改,比如加上一些特殊的处理代码,一般bootloader类的代码直接可以采用原厂的代码,这个汇编语言也跟mcu采用的内核及指令集密切相关,但功能都相差无几,当你想了解一款mcu时从读懂他的启动代码是最快的一种方式,汇编语言难懂,主要是在于你记性好不好,就像想在网络流行的很多简写体,你没有功略可能就是天书,所以不清楚的差芯片指令手则就好了,无他为手熟尔,我相信隔一段时间你又会搞忘的,所以不要纠结这个,也没必要去背他,当然你是学霸除外。
#include <p32xxxx.h>
#ifdef __LIBBUILD__.file 1 "crt0.S".loc 1 0
#endif################################################################### Entry point of the entire application##################################################################.section .reset,"ax",@progbits.set noreorder.ent _reset
_reset:la k0, _startupjr k0 # Jump to startup codenop.end _reset.globl _reset################################################################### Startup code##################################################################.section .startup,"ax",@progbits.set noreorder.ent _startup
_startup:################################################################### If entered because of an NMI, jump to the NMI handler.##################################################################mfc0 k0,_CP0_STATUSext k0,k0,19,1 # Extract NMI bitbeqz k0,_no_nminopla k0,_nmi_handlerjr k0nop
_no_nmi:################################################################### Initialize Stack Pointer# _stack is initialized by the linker script to point to the# starting location of the stack in DRM##################################################################la sp,_stack################################################################### Initialize Global Pointer# _gp is initialized by the linker script to point to "middle"# of the small variables region##################################################################la gp,_gp################################################################### Initialize Global Pointer in Shadow Set# The SRSCtl's PSS field must be set to the shadow set in which# to initialize the global pointer. Since we only have a# single shadow set (besides the normal), we will initialize# SRSCtl<PSS> to SRSCtl<HSS>. We then write the global pointer# to the previous shadow set to ensure that on interrupt, the# global pointer has been initialized.##################################################################mfc0 t1,_CP0_SRSCTL # Read SRSCtl registeradd t3,t1,zero # Save off current SRSCtlext t2,t1,26,4 # to obtain HSS fieldins t1,t2,6,4 # Put HSS fieldmtc0 t1,_CP0_SRSCTL # into SRSCtl<PSS>wrpgpr gp,gp # Set global pointer in PSSmtc0 t3,_CP0_SRSCTL # Restore SRSCtl################################################################### Call the "on reset" procedure##################################################################la t0,_on_resetjalr t0nop################################################################### Clear uninitialized data sections##################################################################la t0,_bss_beginla t1,_bss_endb _bss_checknop_bss_init: sw zero,0x0(t0)sw zero,0x4(t0)sw zero,0x8(t0)sw zero,0xc(t0)addu t0,16
_bss_check:bltu t0,t1,_bss_initnop################################################################### Copy initialized data from program flash to data memory# src=_data_image_begin dst=_data_begin stop=_data_end##################################################################la t0,_data_image_beginla t1,_data_beginla t2,_data_endb _init_checknop_init_data: lw t3,(t0)sw t3,(t1)addu t0,4addu t1,4
_init_check:bltu t1,t2,_init_datanop################################################################### If there are no RAM functions, skip the next two sections --# copying RAM functions from program flash to data memory and# initializing bus matrix registers.##################################################################la t1,_ramfunc_lengthbeqz t1,_ramfunc_donenop################################################################### Copy RAM functions from program flash to data memory# src=_ramfunc_image_begin dst=_ramfunc_begin stop=_ramfunc_end##################################################################la t0,_ramfunc_image_beginla t1,_ramfunc_beginla t2,_ramfunc_end_init_ramfunc: lw t3,(t0)sw t3,(t1)addu t0,4addu t1,4
_ramfunc_check:bltu t1,t2,_init_ramfuncnop################################################################### Initialize bus matrix registers if RAM functions exist in the# application##################################################################la t1,_bmxdkpba_addressla t2,BMXDKPBAsw t1,0(t2)la t1,_bmxdudba_addressla t2,BMXDUDBAsw t1,0(t2)la t1,_bmxdupba_addressla t2,BMXDUPBAsw t1,0(t2)
_ramfunc_done:################################################################### Initialize CP0 registers################################################################### Initialize Count register##################################################################mtc0 zero,_CP0_COUNT################################################################### Initialize Compare register##################################################################li t2,-1mtc0 t2,_CP0_COMPARE################################################################### Initialize EBase register##################################################################la t1,_ebase_addressmtc0 t1,_CP0_EBASE################################################################### Initialize IntCtl register##################################################################la t1,_vector_spacingli t2,0 # Clear t2 andins t2,t1,5,5 # shift value to VS fieldmtc0 t2,_CP0_INTCTL################################################################### Initialize CAUSE registers# - Enable counting of Count register <DC = 0># - Use special exception vector <IV = 1># - Clear pending software interrupts <IP1:IP0 = 0>##################################################################li t1,0x00800000mtc0 t1,_CP0_CAUSE################################################################### Initialize STATUS register# - Access to Coprocessor 0 not allowed in user mode <CU0 = 0># - User mode uses configured endianness <RE = 0># - Preserve Bootstrap Exception vectors <BEV># - Preserve soft reset <SR> and non-maskable interrupt <NMI># - CorExtend enabled based on whether CorExtend User Defined# Instructions have been implemented <CEE = Config<UDI>># - Disable any pending interrups <IM7..IM2 = 0, IM1..IM0 = 0># - Disable hardware interrupts <IPL7:IPL2 = 0># - Base mode is Kernel mode <UM = 0># - Error level is normal <ERL = 0># - Exception level is normal <EXL = 0># - Interrupts are disabled <IE = 0>##################################################################mfc0 t0,_CP0_CONFIGext t1,t0,22,1 # Extract UDI from Config registersll t1,t1,17 # Move UDI to Status.CEE locationmfc0 t0,_CP0_STATUSand t0,t0,0x00580000 # Preserve SR, NMI, and BEVor t0,t1,t0 # Include Status.CEE (from UDI)mtc0 t0,_CP0_STATUS################################################################### Call the "on bootstrap" procedure##################################################################la t0,_on_bootstrapjalr t0nop################################################################### Initialize Status<BEV> for normal exception vectors##################################################################mfc0 t0,_CP0_STATUSand t0,t0,0xffbfffff # Clear BEVmtc0 t0,_CP0_STATUS################################################################### Call main. We do this via a thunk in the text section so that# a normal jump and link can be used, enabling the startup code# to work properly whether main is written in MIPS16 or MIPS32# code. I.e., the linker will correctly adjust the JAL to JALX if# necessary##################################################################and a0,a0,0and a1,a1,0la t0,_main_entryjr t0nop.end _startup################################################################### Boot Exception Vector Handler# Jumps to _bootstrap_exception_handler##################################################################.section .bev_handler,"ax",@progbits.set noreorder.ent _bev_exception
_bev_exception:la k0,_bootstrap_exception_handlerjr k0nop.end _bev_exception################################################################### General Exception Vector Handler# Jumps to _general_exception_handler##################################################################.section .gen_handler,"ax",@progbits.set noreorder.ent _gen_exception
_gen_exception:la k0,_general_exception_contextjr k0nop.end _gen_exception.text.ent _main_entry
_main_entry:################################################################### Call main##################################################################jal mainnop################################################################### Call exit##################################################################jal exitnop################################################################### Just in case, go into infinite loop##################################################################
1:b 1bnop.end _main_entry
下面是bootlaoder的main主场了,这是你可能就顺眼多了,因为c里面你可以自己用拼音表达你的意思,当然你是英语学习委员也可以用英语,但我反对用123来表示,那是霸权行为,只有当时的你可以明白,我一直觉得代码没必要自己从头开始,快速掌握一门语言或者一款mcu从她自带的demo开始,一通ctl c v后你的kpi就完成了,所以人生苦短,不要太在意那么多,知识层出不穷,只有掌握了快速学习的要义你在能在有限的生命里,畅想无限的事情,当然,买块板子自己亲自跑一跑,那跑板子后面吃灰也是很有必要的,最后祝你顺利毕业找到好工作!
/*********************************************************************** PIC32 Boot Loader*********************************************************************** FileName: main.c* Dependencies:* Processor: PIC32** Complier: MPLAB C32* MPLAB IDE* Company: Microchip Technology, Inc.** Software License Agreement** The software supplied herewith by Microchip Technology Incorporated* (the 揅ompany? for its PIC32 Microcontroller is intended* and supplied to you, the Company抯 customer, for use solely and* exclusively on Microchip PIC32 Microcontroller products.* The software is owned by the Company and/or its supplier, and is* protected under applicable copyright laws. All rights are reserved.* 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 IN AN 揂S IS?CONDITION. 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. THE COMPANY SHALL NOT,* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.*** $Id: $* $Name: $*
//片内flash为512k bytes 4k*128page
//0x9D07FFFF--0x9D000000 Program Flash
//
// PFM KERNEL AND USER MODE MAPPING
// Virtual Address Physical Address
// --------------- ----------------
// 0xBFC0_2FEF or ***************** 0x1FC0_2FEF
// 0X9FC0_2FEF * *
// * *
// * Boot Flash *
// 0xBFC0_0000 or * *
// 0x9FC0_0000 ***************** 0x1FC0_0000// 0xBD07_FFFF or ***************** 0x1D07_FFFF
// 0x9D07_FFFF * * BL_CSUM_ADDR 0x1D07_FFF4
// * * BL_PROGSZ_ADDR 0x1D07_FFF0
// 0xBD07_E000 or ***************** 0x1D07_E000
// 0x9D07_E000 * *
// * User App * 500k User app
// * *
// * Program *
// * Flash *
// * *
// 0x9D00_1000 ***************** 0x1D00_1000//4k bootloader
// * BootLoader *
// 0xBD00_0000 or * *
// 0x9D00_0000 ***************** 0x1D00_0000**********************************************************************/
#include <stdlib.h>
#include <plib.h>
#include "GenericTypeDefs.h"
#include "msg_cmd.h"
//#include "utils.h"
#include <stdarg.h>
// 80Mhz Core/Periph, Pri Osc w/PLL, Write protect Boot Flash
//#pragma config FPLLODIV = DIV_1, FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FWDTEN = OFF, FPBDIV = DIV_1, POSCMOD = XT, FNOSC = PRIPLL, CP = OFF
//#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
//#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
//#pragma config ICESEL = ICS_PGx2, BWP = ON
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = XT, FNOSC = PRIPLL, FPBDIV = DIV_1
#pragma config ICESEL = ICS_PGx2, BWP = ON,CP = OFF#define SHELL_CMD 0#define BL_CSUM_ADDR 0x9D07FFF4
#define BL_PROGSZ_ADDR 0x9D07FFF0
#define FLASH_PROG_BASE 0x9D000000
#define USER_APP_ADDR 0x9D001000
#define FLASH_PAGE_SIZE 4096
#define __ROM_SIZE BL_PROGSZ_ADDR-FLASH_PROG_BASE
#define BIOS_LOAD USER_APP_ADDR
#define BL_MINOR_VERSION 1
#define BL_MAJOR_VERSION 0#define MAX_CMD_LEN 30
#define MAX_ARGS MAX_CMD_LEN/4#define UART1_RXREG_IS_NOTNULL (U1ASTAbits.URXDA==1)#define ENTER_KEY 0x0d
#define BACK_KEY 0x08
#define ESC_KEY 0x1b#define dog()
#define SYS_FREQ (80000000L)#define mLED_1 LATBbits.LATB0
#define mLED_2 LATBbits.LATB1
#define mLED_3 LATBbits.LATB2#define SECONDS (SYS_FREQ/2)
#define MILLI_SECONDS (SECONDS/1000)#define MAX_DATA_BFR 4096unsigned char gBuffer[MAX_DATA_BFR];
//unsigned int pagebuff[1024];#define DFT_DOWNLOAD_ADDR ((int)&gBuffer[0])
void PutChar(BYTE txChar);
void HandleCommand();
BYTE gRxData;
void PutResponse(WORD responseLen);
void VerifyFlashOK(int filesize,WORD csum);
int SectorProg(unsigned int begin, unsigned short *data, unsigned int size);
unsigned char read_byte(unsigned char *recchar);
void Puts(char *s);
void Printf(char *fmt, ...);
#define next_line() Puts("\r\n")
#define prompt() Puts("\\>")
//#define DFT_DOWNLOAD_ADDR
#if SHELL_CMD==1
int LoadFromUart(int argc, char *argv[])
#else
int LoadFromUart()
#endif
{unsigned int start, fileSize;unsigned int write_addr,writedsize=0;unsigned int load_addr =(int) DFT_DOWNLOAD_ADDR; WORD checksum=0,mychecksum=0;int bValue=0;#if SHELL_CMD==1if(argc>1){start = strtoul(argv[1],0,10);if(load_addr>0)load_addr = start; }
#endifstart = load_addr;while(!kbhit());*((unsigned char *)load_addr++) = getkey();while(!kbhit());*((unsigned char *)load_addr++) = getkey();while(!kbhit());*((unsigned char *)load_addr++) = getkey();while(!kbhit());*((unsigned char *)load_addr++) = getkey();fileSize= (*((unsigned char *)DFT_DOWNLOAD_ADDR+0)<<0)+(*((unsigned char *)DFT_DOWNLOAD_ADDR+1)<<8)+(*((unsigned char *)DFT_DOWNLOAD_ADDR+2)<<16)+(*((unsigned char *)DFT_DOWNLOAD_ADDR+3)<<24);fileSize=fileSize-6;if(fileSize>=__ROM_SIZE) {//Puts("Flash size overflow!!!\r\n");return -1;}load_addr = (int)DFT_DOWNLOAD_ADDR; write_addr = (int)FLASH_PROG_BASE;writedsize=0;while(writedsize <fileSize){if(kbhit()){bValue=1-bValue;mLED_1=bValue; mychecksum+=*((unsigned char *)load_addr++) = getkey();writedsize++;dog();if( writedsize%0x1000==0 ){SectorProg(write_addr,(unsigned short*)DFT_DOWNLOAD_ADDR,0x1000);write_addr=write_addr+0x1000;load_addr = (int)DFT_DOWNLOAD_ADDR; PutChar('.');dog();}}}if(load_addr%0x1000!=0){SectorProg(write_addr,(unsigned short*)DFT_DOWNLOAD_ADDR,fileSize - (write_addr-BIOS_LOAD));PutChar('.');dog();}load_addr = (int)DFT_DOWNLOAD_ADDR;//check sumwhile(!kbhit());*((unsigned char *)load_addr++) = getkey();while(!kbhit());*((unsigned char *)load_addr++) = getkey();//while(!kbhit());*((unsigned char *)load_addr++) = getkey();//while(!kbhit());*((unsigned char *)load_addr++) = getkey();checksum=(*((unsigned char *)DFT_DOWNLOAD_ADDR+0)<<0)+(*((unsigned char *)DFT_DOWNLOAD_ADDR+1)<<8);//(*((unsigned char *)DFT_DOWNLOAD_ADDR+1)<<16)+//(*((unsigned char *)DFT_DOWNLOAD_ADDR+1)<<24);if(checksum==mychecksum)VerifyFlashOK(fileSize,checksum);//FILESIZE1 = fileSize;return 0;}void VerifyFlashOK(int filesize,WORD csum)
{//gBuffer[1] contains the prog size in bytes. must be on DWORD boundryint temp;//DWORD* fptr;NVMErasePage( (void*)(BL_CSUM_ADDR&0xFFFFF000));if( !((*(DWORD*)BL_CSUM_ADDR) == 0xFFFFFFFF && (*(DWORD*)BL_PROGSZ_ADDR) == 0xFFFFFFFF) ){//send the error responsePuts("Flash not Erase\r\n");return;} //fptr = (DWORD*)FLASH_PROG_BASE;NVMWriteWord((DWORD*)(BL_PROGSZ_ADDR), filesize); //write flash prog size in bytesNVMWriteWord((WORD*)(BL_CSUM_ADDR), csum); //write checksumif( !((*(WORD*)BL_CSUM_ADDR) == csum && (*(DWORD*)BL_PROGSZ_ADDR) ==filesize ) ){Puts("Flash Check sum Erro\r\n");}
}int SectorProg(unsigned int begin, unsigned short *data, unsigned int size)
{
/*unsigned int tmp = 0x200;//0x1000-(begin&0xfff);//if(tmp>size)// tmp = size;//SectorErase(begin&0xfffff000);for(; size;){ mLED_3=0;if((begin&0xFFF)==0)NVMErasePage((void*)(begin&0xfffff000));//FlashProg(begin, data, tmp/2);// Write the pagebuff data to NVM_PROGRAM_PAGE + NVM_PAGE_SIZE//NVMProgram((void *)begin, (const void *)data, size, (void*) pagebuff);NVMWriteRow((DWORD*)begin, (DWORD*)data);//Puts("Program ok\r\n");size -= tmp;begin += tmp;data += tmp/2;tmp = (size>0x1000)?0x1000:size; }
*/int RowCount, nRow;unsigned char* ptr=(unsigned char*)data;RowCount = size / 512;if( size % 512 )RowCount++;nRow = 0;while(nRow < RowCount){int RowAddr;RowAddr = nRow*512;if( ((begin+RowAddr) & 0xFFF) == 0 )NVMErasePage( (void*)(begin+RowAddr) );// Write 128 words NVMWriteRow((void*)(begin+RowAddr), (void*)&ptr[RowAddr]);nRow++;} return 0;
}void JumpToApp()
{ void (*fptr)(void);fptr = (void (*)(void))USER_APP_ADDR;fptr();
} BOOL VerifyFlash()
{DWORD temp, ProgSz;DWORD* fptr;BYTE* fbptr;WORD csum = 0,mycsum=0;fptr = (DWORD*)BL_PROGSZ_ADDR;ProgSz = *fptr;mycsum = *(WORD*)BL_CSUM_ADDR; if( ProgSz > BMXPFMSZ )return FALSE;fbptr = (BYTE*)FLASH_PROG_BASE;for( temp = 0; temp < ProgSz; temp++ )csum += fbptr[temp];//csum = ~csum + 1;return (csum == mycsum);
}/*********************************************************/#if SHELL_CMD==1int Help(int argc, char *argv[]);
int Auto(int argc, char *argv[]);typedef int (*cmdproc)(int argc, char *argv[]);
typedef struct {char *cmd;char *hlp;cmdproc proc;
}CMD_STRUC;CMD_STRUC CMD_INNER[] ={ {"?", "help", Help},{"load", "load bin file from console", LoadFromUart},// {"prog", "program from sdram to flash", ProgFlash},// {"boot", "boot from flash", BootLoader},// {"copy", "copy from flash to flash", CopyFlash},// {"run", "run from sdram", RunProgram},{"auto", "auto download and program",Auto},{NULL, NULL, NULL}};
/*
int Help(int argc, char *argv[])
{int i; for(i=0; CMD_INNER[i].cmd!=NULL; i++){if(CMD_INNER[i].hlp!=NULL){Puts(CMD_INNER[i].cmd);Puts(" -----> ");Puts(CMD_INNER[i].hlp);Puts("\r\n");}}return 0;
}
*/
//int Auto(void);
int Auto(int argc, char *argv[])
{//1.download to sdram
char *para_ptr[4];
//char temp[10];
argc=argc;LoadFromUart(0, para_ptr);//2.program to flash
/*
para_ptr[1]="8000";
para_ptr[2]="44000000";
para_ptr[3]=temp;
ultostr(temp,FILESIZE1);ProgFlash1(4, para_ptr);
*/
//3.bootJumpToApp();return 0;}
/*********************************************************/static void ParseArgs(char *cmdline, int *argc, char **argv)
{
#define STATE_WHITESPACE 0
#define STATE_WORD 1char *c;int state = STATE_WHITESPACE;int i;*argc = 0;if(strlen(cmdline) == 0)return;// convert all tabs into single spaces c = cmdline;while(*c != '\0'){if(*c == '\t')*c = ' ';c++;}c = cmdline;i = 0;// now find all words on the command line while(*c != '\0'){if(state == STATE_WHITESPACE){if(*c != ' '){argv[i] = c; //将argv[i]指向ci++;state = STATE_WORD;}}else{ // state == STATE_WORD if(*c == ' '){*c = '\0';state = STATE_WHITESPACE;}}c++;}*argc = i;
#undef STATE_WHITESPACE
#undef STATE_WORD
}static int GetCmdMatche(char *cmdline)
{int i; for(i=0; CMD_INNER[i].cmd!=NULL; i++){if(strncmp(CMD_INNER[i].cmd, cmdline, strlen(CMD_INNER[i].cmd))==0)return i;}return -1;
}static int ParseCmd(char *cmdline, int cmd_len)
{int argc, num_commands;char *argv[MAX_ARGS];ParseArgs(cmdline, &argc, argv);// only whitespace if(argc == 0) return -1;num_commands = GetCmdMatche(argv[0]);if(num_commands<0)return -1;if(CMD_INNER[num_commands].proc!=NULL) {CMD_INNER[num_commands].proc(argc, argv);} return 0;
}
#endif
/*********************************************************/#define BlinkLED() {mLED_1 = ((ReadCoreTimer() & 0x0200000) != 0);}
#define BlinkLED2() {mLED_2 = ((ReadCoreTimer() & 0x0200000) != 0);}
#define BlinkLED3() {mLED_1 = ((ReadCoreTimer() & 0x2000000) != 0);}BOOL PutMyDLChar()
{if(ReadCoreTimer()>=SECONDS ){ PutChar('>');WriteCoreTimer(0); return TRUE;}else return FALSE;
}/*********************************************************/int main (void)
{//int s = DFT_DOWNLOAD_ADDR;int i, key;int time_out0;char command[MAX_CMD_LEN]; unsigned int pb_clock;SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);mCTClearIntFlag();OpenCoreTimer(SECONDS);//setup LED portsTRISBbits.TRISB0 = 0;TRISBbits.TRISB1 = 0;TRISBbits.TRISB2 = 0;BOOL FlashGood = FALSE;// SETUP UART COMMS: No parity, one stop bit, autobaud, polled
// OpenUART1(UART_EN|UART_EN_ABAUD|UART_BRGH_FOUR, UART_RX_ENABLE | UART_TX_ENABLE, 0 ); //OpenUART1(UART_EN|UART_EN_ABAUD|UART_BRGH_FOUR, UART_RX_ENABLE | UART_TX_ENABLE, 0 );
// OpenUART1(UART_EN | UART_BRGH_FOUR, UART_RX_ENABLE | UART_TX_ENABLE, mUARTBRG(80000000, 115200)); UARTConfigure(UART1, UART_ENABLE_PINS_TX_RX_ONLY);UARTSetFifoMode(UART1, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);UARTSetLineControl(UART1,UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);UARTSetDataRate(UART1, 80000000, 115200);//UART1_BAUDRATE);UARTEnable(UART1, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));//U1MODEbits.ABAUD = 1; //set autobaud modemLED_3=0;mLED_2=0;
/* while(U1MODEbits.ABAUD ) //wait for sync character U {if( FlashGood && mCTGetIntFlag() ){//timeout while waiting for sync from pc - jump to user appJumpToApp();}BlinkLED(); }
*//*************************************/
/*PutChar(0x0c);PutChar(0x0c); next_line();Puts("********************************************\r\n");Puts("* VDC300 BIOS BOOT *\r\n");Puts("* GT-BIOS GT-SS1-V1.0 *\r\n");Puts("*VDC300 Design By XXD(xiang_xudong@163.com)*\r\n");Puts("********************************************\r\n");Puts("Build Date:");Puts(__DATE__);Puts(" Time:");Puts(__TIME__);next_line();
*///check flash contentsFlashGood = VerifyFlash();if(FlashGood)Puts("Program OK\r\n");elsePuts("Program Not Complete\r\n");// while(U1MODEbits.ABAUD ) //wait for sync character U //#define WAIT_TIME0 0x20000 time_out0 = 10;//WAIT_TIME0; do{dog();if(kbhit()){key = getkey();if (key == ENTER_KEY) break;//else if(key == '<') mLED_3=1;}BlinkLED2();// PutMyDLChar();if(PutMyDLChar()){if((--time_out0==0)&&FlashGood)//timeout while waiting for sync from pc - jump to user appJumpToApp();}}while(1);#if SHELL_CMD==1next_line();prompt(); i = 0;time_out0=0;for(;;){dog();if(kbhit()){key = getkey();if(key == BACK_KEY){ i -= i?1:0;PutChar(key);}elseif(key == ENTER_KEY){int tmp;command[i] = 0;next_line();tmp = ParseCmd(command, i);if(tmp<0){Puts("Bad command\r\n");//Boot();}elsetime_out0=0; prompt();i = 0;}else{if(i<MAX_CMD_LEN-1){command[i++] = key;PutChar(key);}} }else{BlinkLED3();//if(time_out0++>=0x20000) Boot();}}
#elsenext_line();prompt(); i = 0;time_out0=0;for(;;){dog();if(kbhit()){key = getkey();if(key == BACK_KEY){ i -= i?1:0;PutChar(key);}elseif(key == ENTER_KEY){int tmp;command[i] = 0;next_line();//tmp = ParseCmd(command, i);if(strstr(command,"auto")!=NULL){LoadFromUart();JumpToApp();}
/*if(tmp<0){Puts("Bad command\r\n");//Boot();}elsetime_out0=0; prompt();
*/ i = 0;}else{if(i<MAX_CMD_LEN-1){command[i++] = key;PutChar(key);}} }else{BlinkLED3();//if(time_out0++>=0x20000) Boot();}}
#endif
}/********************************************************************
* Function: void PutChar(BYTE Char)
*
* Precondition: UART Setup
*
* Input: Char - Character to transmit
*
* Output: None
*
* Side Effects: Puts character into destination pointed to by ptrChar.
*
* Overview: Transmits a character on UART2.
* Waits for an empty spot in TXREG FIFO.
*
* Note: None
********************************************************************/
void PutChar(BYTE txChar)
{while( BusyUART1() );putcUART1(txChar);
}void Puts(char *s)
{while ( *s ){PutChar(*s++);}return;}
/*
int vsprintf(char * , const char * , __va_list );
void Printf(char *fmt, ...)
{va_list ap;char string[256]; va_start(ap, fmt);vsprintf(string, fmt, ap);Puts(string); //UartSendString(CONSOLE_UART, string);va_end(ap);
}
*/
int kbhit()
{ if(UART1_RXREG_IS_NOTNULL) return 1;else return 0;
}int getkey()
{unsigned char recchar;if(read_byte(&recchar)) //UartReceive(CONSOLE_UART);return recchar;elsereturn 0;
}
unsigned char read_byte(unsigned char *recchar)
{BYTE dummy;/*//check for receive errorsif((U1STA & 0x000E) != 0x0000){dummy = U1RXREG; //dummy read to clear FERR/PERRU1STAbits.OERR = 0; //clear OERR to keep receiving}*///get the dataif(UART1_RXREG_IS_NOTNULL){*recchar= U1RXREG; //get data from UART RX FIFOreturn TRUE;}elsereturn FALSE;} /* end read_serial_byte() */