在嵌入式看法过程中,需要经常更新固件,常用的是jtag之类的下载工具,当然你也可以采用一些微型的bootloader通过串口来下载更新固件。其实在线升级也没什么好高深的技术,也就是如何定义一个协议将固件文件传递给板载boot loader,再由bootloader写入到板载的flash中,当然为了安全性和稳定性,你可以加入加解密验证和回滚机制,传输也可以采用网络串口等,实现真正的在线升级功能,一下就是一个简单的pc机的下载工具,从我开始涉足嵌入式开发开始一直陪伴我无数次的在线代码升级。希望也能给入门的朋友提供一些帮助。
// dd.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
//#include <process.h>
//#include <conio.h>
#include <stdlib.h>
#include ".\Serial\Serial.h"
#define IN_KMODE // 每1k等待一个字符'*'
int nBaudRate=115200;
CSerial s;
FILE *stream,*stream2;
void transmit(void);
void receive(void);
void StartSend(void);
unsigned char flename[20];
int comport=1;
unsigned int gmode=0;
unsigned int fmode=0;
unsigned int rmode=0;
unsigned int divider=3;
unsigned int noinit=0;
char *rxbuf;
int timeoutlimit=100000;
unsigned int rxcount,rxbufsize;
unsigned long filestart,fileend,datalength;
#define STARTStr '\>'
#define CMDStr "auto"
int main(int argc, char* argv[])
{
char recStr[2];
int tmp;
// unsigned char temp;
if (argc<3)
{
printf("\nUsage:FlashDownLoader <src_file> /<com#:1,2> [/g] [/f:...] [/d:n] [/n] [/r:buf_size]\n");
printf("\nOptions\n");
printf(" /0,/1,/2: output direction. 0:file,1:COM1,2:COM2\n");
printf(" /g : no 4byte_head and 2byte_checksum is added.\n");
printf(" /f:<xx> : output file name\n");
printf(" /d:n : baud rate. n=12(9600),6(19200),3(38400),2(57600),1(115200)\n");
printf(" /n : No COM port initialization\n");
printf(" /r:n : N/A\n");
printf(" /t:n : N/A(100000)\n");
printf("Uasges:Tx to COM1: dd tttt.bin /1 /d:1\n");
printf(" Tx to file: dd xxxx.bin /0 /n /f:yyyy.bhc\n");
return 0;
}
printf("Selected options:\n");
// select com port
//comport=*(argv[2]+1)-'0'-1;
//comportbase=0x3f8; //COM1
//if (comport>=1){comport=1;comportbase=0x2f8;} //COM2
for(tmp=1;tmp<argc;tmp++)
{
if(*(argv[tmp]+0)!='/')continue;
switch(*(argv[tmp]+1))
{
case '0':
comport=-1;
// comportbase=0; //no COM port
printf("/0: no COM port\n");
break;
case '1':
comport=0;
// comportbase=0x3f8; //COM1
printf("/1: COM1 is selected.\n");
break;
case '2':
comport=1;
// comportbase=0x2f8; //COM2
printf("/2: COM2 is selected.\n");
break;
case 'g':
printf("/g: No head & CheckSum\n");
gmode=1;
break;
case 'f':
printf("/f: dest. is file.\n");
fmode=1;
stream2 = fopen((argv[tmp]+3),"wb");
if(stream2==NULL)
{
printf("\nERROR:file creation error.\n");
return 0;
}
break;
case 'd':
divider=atoi(argv[tmp]+3);
printf("/d: divider=%d\n",divider);
if(divider==1) nBaudRate=115200;
else if(divider==2) nBaudRate=57600;
else if(divider==3) nBaudRate=38400;
else if(divider==6) nBaudRate=19200;
else if(divider==12) nBaudRate=9600;
break;
case 'n':
noinit=1;
printf("/n: no com port init.\n");
break;
case 'r':
rmode=1;
rxbufsize = atoi(argv[tmp]+3);
printf("/r: receive mode buffer=%d\n",rxbufsize);
break;
case 't':
timeoutlimit=atoi(argv[tmp]+3);
printf("/t: timeoutlimit=%d\n",timeoutlimit);
break;
}
}
printf(" +--------------------------------+\n");
printf(" | 固泰嵌入串口下载工具程序 |\n");
printf(" | GT Embeded |\n");
printf(" | FlashDownLoader VER 0.8 |\n");
printf(" +--------------------------------+\n");
printf("8BIT,1 Stop,No Parity,(%d)\n",nBaudRate);
printf("Stream Format:< n + 6 >(4)+data(n byte)+checksum(2)\n\n");
if(rmode==1 && fmode==0)
{
printf("\nERROR:/r option has to be used together /f\n");
return 0;
}
if(rmode)
{
rxbuf=new char(rxbufsize);
if(rxbuf==0x0)
printf("\nERROR:memory allocation error.\n");
}
if(!rmode)
{
stream = fopen(argv[1],"rb");
if(stream==NULL)
{
printf("\nERROR:can't find the file.\n");
delete rxbuf;
return 0;
}
fseek(stream,0L,SEEK_END);
fileend=ftell(stream);
fseek(stream,0L,SEEK_SET);
filestart=ftell(stream);
datalength=fileend-filestart; /*fileend == peof+1 */
/*data transmition need not to use interrupt*/
}
if(comport>=0 && noinit==0)
{
if(!s.Open(comport+1,nBaudRate))
{
printf("串口没打开");
delete rxbuf;
return 0;
}
}
StartSend();
Sleep(1000);
// s.Close();
// s.Open(comport+1,115200);
if(rmode)
receive();
else
transmit();
delete rxbuf;
// recStr[0]=13;
// s.SendData(recStr,1);
// Sleep(100);
// recStr[0]='y';
// s.SendData(recStr,1);
s.Close();
return 0;
}
void receive()
{
}
//****************************************************************************
//
// WaitFor waits until a specific character is read from the serial port.
//
//****************************************************************************
void
WaitFor(char cWaitChar)
{
char cChar[2];
//
// Wait until we read a specific character from the serial port.
//
while(1)
{
//
// Read a character.
//
while(!(s.ReadDataWaiting()>=1));
s.ReadData(cChar,1);
//cChar = ReceiveChar(0);
//
// Stop waiting if we received the character.
//
if(cChar[0] == cWaitChar)
{
break;
}
}
}
void transmit(void)
{
unsigned i;
WORD checksum=0;
unsigned char data[2];
if(!gmode)
{
data[0]=(unsigned int)( (datalength +6L) & 0xffL);
s.SendData((char*)data,1);
/*transfer D0 byte of datalength*/
data[0]=(unsigned int)( ((datalength +6L)>>8) & 0xffL);
s.SendData((char*)data,1);
//s.SendData((unsigned int)( ((datalength +6L)>>8) & 0xffL));
/*transfer D1 byte of datalength*/
data[0]=(unsigned int)( ((datalength +6L)>>16) & 0xffL);
s.SendData((char*)data,1);
//s.SendData((unsigned int)( ((datalength +6L)>>16) & 0xffL));
/*transfer D2 byte of datalength*/
data[0]=(unsigned int)( ((datalength +6L)>>24) & 0xffL);
s.SendData((char*)data,1);
//s.SendData((unsigned int)( ((datalength +6L)>>24) & 0xffL));
/*transfer D3 byte of datalength*/
}
printf("\ndata size:%lu\n",datalength);
data[0] = fgetc(stream);
for(i=1;i<=datalength;i++)
{
s.SendData((char*)data,1);
checksum=checksum+data[0];
data[0] = fgetc(stream);
//if(i%1000==0) printf("\rXfered Size=%ld",i);
if(i%0x1000==0)
{
printf("\rXfered Size=%ld",i);
WaitFor('.');
}
/*#ifdef IN_KMODE
if(i%1024==0)WaitFor('*');
#endif
*/ }
if((i-1)%0x1000!=0) WaitFor('.');
printf("\rtransfered Size=%ld\n",i-1L);
if(!gmode)
{
data[0]= ( ((unsigned int)checksum ) & 0xff);
s.SendData((char*)data,1);
data[0]= (((unsigned int)checksum)>>8) & 0xff ;
s.SendData((char*)data,1);
//data[0]= (((unsigned int)checksum)>>16) & 0xff ;
//s.SendData((char*)data,1);
//data[0]= (((unsigned int)checksum)>>24) & 0xff ;
// s.SendData((char*)data,1);
}
if(fmode)fclose(stream2);
printf("checksum:0x%x\n",checksum & 0xFFFFFFFF);
fclose(stream);
}
void StartSend(void)
{
unsigned char recStr[2];
int count=0;
bool bStart=FALSE;
while(TRUE)
{
if(count>5)
{
printf("\r");
printf(" ");
printf("\r");
count=0;
}
else
printf(".");
if(s.ReadDataWaiting()>0)
{
s.ReadData(recStr,1);
//printf(recStr);
if(!bStart)
{
if(recStr[0]=='>')//收到
{
//printf((char*)recStr);
recStr[0]=13;
s.SendData((char*)recStr,1);
bStart=TRUE;
}
}
else
{
if(recStr[0]=='\\')
{
//printf((char*)recStr);
s.ReadData(recStr,1);
if(recStr[0]=='>')
{
//printf((char*)recStr);
s.SendData(CMDStr,strlen(CMDStr));
recStr[0]=13;
s.SendData((char*)recStr,1);
Sleep(300);
return;
}
}
}
}
else
{
recStr[0]='U';
s.SendData((char*)recStr,1);
Sleep(1);
}
count++;
// Sleep(300);
//printf("\r");
//printf(">");
}
}