嵌入式开发之bootloader

news/2024/11/17 2:34:59/

      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() */

 

 


http://www.ppmy.cn/news/807218.html

相关文章

香港第一金:美债上升美元走强 黄金暴跌下破199

做投资最怕的莫过于心急&#xff0c;最坏的莫过于冲动。当把分析变成一种任务、把投资变成一种负担&#xff0c;就已经偏离了路线。做投资一定要首先树立正确的投资理念&#xff0c;这是一切的根源&#xff0c;其次做好仓位资金管理&#xff0c;重要的保持良好的心态&#xff0…

179. 最大数

给定一组非负整数&#xff0c;重新排列它们的顺序使之组成一个最大的整数。 示例 1: 输入: [10,2] 输出: 210 示例 2: 输入: [3,30,34,5,9] 输出: 9534330 说明: 输出结果可能非常大&#xff0c;所以你需要返回一个字符串而不是整数。

美元和人民币

题目描述 随着国际形势的变化&#xff0c;美元与人民币的兑换率也经常在变化。假设美元与人民币的汇率是1美元兑换6.5573元人民币&#xff0c;编写程序输入美元金额&#xff0c;输出能兑换的人民币金额。 输入要求 输入美元金额&#xff08;浮点类型&#xff09;。输出要求 …

Leetcode179

Leetcode179 题目思路新知识循环方式快排函数字符串操作 不足之处自己的代码官方代码 题目 链接: 179. 题目描述&#xff1a;给定一组非负整数 nums&#xff0c;重新排列每个数的顺序&#xff08;每个数不可拆分&#xff09;使之组成一个最大的整数。 注意&#xff1a;输出结…

这29家谷歌SEO公司超赚钱,涉及800亿美元

随着搜索引擎优化的实践早于谷歌&#xff0c;在线最大的市场之一还有机会吗&#xff1f; 这是我在业内一些最成功的公司的细分中要回答的问题。您可能会认识到以下列表中有一些名称。还有一些值得注意的例外&#xff0c;这不是一个错误。 你可以很好地了解DeepCrawl&#xff…

【LeetCode】179. 最大数

文章目录 题目[179. 最大数](https://leetcode-cn.com/problems/largest-number/)解题思路注意&#xff1a;步骤&#xff1a; 代码 题目179. 最大数 给定一组非负整数 nums&#xff0c;重新排列每个数的顺序&#xff08;每个数不可拆分&#xff09;使之组成一个最大的整数。 …

leetcode 179 最大数

给定一组非负整数&#xff0c;重新排列它们的顺序使之组成一个最大的整数。 示例 1: 输入: [10,2] 输出: 210 示例 2: 输入: [3,30,34,5,9] 输出: 9534330 说明: 输出结果可能非常大&#xff0c;所以你需要返回一个字符串而不是整数。 解题思路&#xff1a; 和普通的排序…

zzulioj1008: 美元和人民币

1008: 美元和人民币 题目描述 美元越来越贬值了&#xff0c;手上留有太多的美元似乎不是件好事。赶紧算算你的那些美元还值多少人民币吧。假设美元与人民币的汇率是1美元兑换6.5573元人民币&#xff0c;编写程序输入美元的金额&#xff0c;输出能兑换的人民币金额。 输入 输入…