ATmega128具备引导加载支持的用户程序自编程功能(In-System Programming by On-chipBoot Program),它提供了一个真正的由MCU本身自动下载和更新(采用读/写同时"Read-While-Write"进行的方式)程序代码的系统程序自编程更新的机制。利用AVR的这个功能,可以实现在应用编程(IAP)以及实现系统程序的远程自动更新的应用。 近场通信门户网)vA)e.nI-m!N(_iQ%l
IAP的本质就是,MCU可以灵活地运行一个常驻Flash的引导加载程序(Boot Loader Program),实现对用户应用程序的在线自编程更新。引导加载程序的设计可以使用任何的可用的数据接口和相关的协议读取代码,或者从程序存储器中读取代码,然后将代码写入(编程)到Flash存储器中。 近场通信门户网M#m(\Z?f5] z:B:L
引导加载程序有能力读写整个Flash存储器,包括引导加载程序所在的引导加载区本身。引导加载程序还可以对自身进行更新修改,甚至可以将自身删除,使系统的自编程能力消失。引导加载程序区的大小可以由芯片的熔丝位设置,该段程序区还提供两组锁定位,以便用户选择对该段程序区的不同级别的保护。 近场通信门户网9zR l$R sO,rt i:^R
本节将给出一个实际的的Boot Loader程序,它可以配合Windows中的超级终端程序,采用Xmodem传输协议,通过RS232接口下载更新用户的应用程序。 近场通信门户网/DzAlvXv GZ
<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />5.2.1基本设计思想
_qWC%WS|9V\A01. Boot Loader程序的设计要点 近场通信门户网GI_*}5P t
Boot Loader程序的设计是实现IAP的关键,它必须能过通过一个通信接口,采用某种协议正确的接收数据,再将完整的数据写入到用户程序区中。本例Boot Loader程序的设计要点有:
t"a6E4jJ.c0(1)采用ATmega128的USART口实现与PC之间的简易RS232三线通信; 近场通信门户网^V'@S+b3Gd
(2) 采用Xmodem通信协议完成与PC机之间的数据交换;
YX i @eM0(3)用户程序更新完成后自动转入用户程序执行; 近场通信门户网8MU_&a*P{H
(4) Boot Loader程序采用C语言内嵌AVR汇编方式编写,阅读理解方便,可移植性强,代码小于1K字。 近场通信门户网6@{+K.e&\] RgU R9I
2. Xmodem通信协议
.FeM[4rkZ'ko0Xmodem协议是一种使用拨号调制解调器的个人计算机通信中广泛使用的异步文件运输协议。这种协议以128字节块的形式传输数据,并且每个块都使用一个校验和过程来进行错误检测。如果接收方关于一个块的校验和与它在发送方的校验和相同时,接收方就向发送方发送一个认可字节。为了便于读者阅读程序,下面简要说明该协议的主要特点,有关Xmoden的完整的协议请参考其它相关的资料。
:@,r\$} [;o@ ^;}!c"S0(1) Xmodem的控制字符:<soh> 01H、<eot> 04H、<ack> 06H、<nak> 15H、<can> 18H、<eof> 1AH。 近场通信门户网T4?@Y^ CgUp d&L
(2) Xmodem传输数据块格式:"<soh> <packNO> <255-packNO> <...128个字节的数据块...> <cksum>"。其中<soh>为起始字节;<packNO>为数据块编号字节,每次加一;<255-packNO>是前一字节的反码;接下来是长度为128字节的数据块;最后的<cksum>是128字节数据的CRC校验码,长度为2个字节。
!M E0^6h Y0|0(3)接收端收到一个数据块并校验正确时,回送<ack>;接收错误回送<nak>;而回送<can>表示要发送端停止发送。 近场通信门户网#M B^)Fvs%w
(4) 发送端收到<ack>后,可继续发送下一个数据块(packNO+1);而收到<nak>则可再次重发上一个数据块。 近场通信门户网rG)@;BSV;^)g
(5)发送端发送<eot>表示全部数据发送完成。如果最后需要发送的数据不足128个字节,用<eof>填满一个数据块。
;TA%}*_y6?T0(6) 控制字符"C"有特殊的作用,当发送端收到"C"控制字符时,它回重新开始以CRC校验方式发送数据块(packNO = 1)。
eM{x}wyRi7Q f0(7) 每发送一个新的数据块<packNO>加1,加到OxFF后下一个数据块的<packNO>为零。 近场通信门户网pH)iF*` z:Jw3O
(8) 校验方式采用16位CRC校验(X^16 + X^12 + X^5 + 1)。 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
5.2.2 源程序代码
@{1bx i |z0下面给出的源程序是在ICCAVR中实现的。
G-n+Gw0@ Wx&lc0/*****************************************************
/M5J2^:M [ v eS W0采用串行接口实现Boot_load应用的实例
^#T\OG)v0华东师大电子系 马 潮 2004.07
X J(g/]Aw0Compiler: ICC-AVR 6.31 近场通信门户网*X$B"fo7qH/m&C
Target: Mega128
Zo&lp:r ?8m0Crystal: 16Mhz 近场通信门户网/|[/N F$w,u1JQ/Hl
Used: T/C0,USART0
.v2q_k+~0*****************************************************/ 近场通信门户网[)x3]*W_V(e s
#include <iom128v.h>
2]'^Y J3cc+fF0#define SPM_PAGESIZE 256 //M128的一个Flash页为256字节(128字) 近场通信门户网*m`.D{$I&lp
#define BAUD 38400 //波特率采用38400bps 近场通信门户网h(B5P Bnh
#define CRYSTAL 16000000 //系统时钟16MHz 近场通信门户网3v xTp\w%j
//计算和定义M128的波特率设置参数 近场通信门户网$}Q*tU0s.oLh:U
#define BAUD_SETTING (unsigned char)((unsigned long)CRYSTAL/(16*(unsigned long)BAUD)-1) 近场通信门户网&Z?t{7Y
#define BAUD_H (unsigned char)(BAUD_SETTING>>8) 近场通信门户网8b$|3R0g6?,p5X6sDDYL
#define BAUD_L (unsigned char)BAUD_SETTING
#define DATA_BUFFER_SIZE SPM_PAGESIZE //定义接收缓冲区长度 近场通信门户网 r ui@] f
//定义Xmoden控制字符 近场通信门户网P!U _'f&X|"\c| ox
#define XMODEM_NUL 0x00 近场通信门户网{r hA+Kk?Xs/w
#define XMODEM_SOH 0x01
+g5l^ E rz0#define XMODEM_STX 0x02
i9YB)_%ON l)Z8E?0#define XMODEM_EOT 0x04 近场通信门户网6qu~y]#t\"iR4D
#define XMODEM_ACK 0x06
.cn&`dMsf zx3\|0#define XMODEM_NAK 0x15
y0si.DuoVQ\6k0#define XMODEM_CAN 0x18 近场通信门户网5^ N^d'Fg
#define XMODEM_EOF 0x1A
0I5npG }I0#define XMODEM_RECIEVING_WAIT_CHAR 'C' 近场通信门户网q-bI h F+n
//定义全局变量 近场通信门户网9B/o#J^;mS0p
const char startupString[]="Type 'd' download, Others run app.\n\r\0"; 近场通信门户网r"v\o&k:n$k0U;c"s3eE
char data[DATA_BUFFER_SIZE]; 近场通信门户网t4KN%m`gfK,Yb
long address = 0;
{ }6^JN)C4f1r0//擦除(code=0x03)和写入(code=0x05)一个Flash页 近场通信门户网3_&[od5~K-E
void boot_page_ew(long p_address,char code) 近场通信门户网TSWYOmC
{ 近场通信门户网+fOL A!CVWK
asm("mov r30,r16\n"
v\Op$jN2z!F-We o0 "mov r31,r17\n" 近场通信门户网3H(e0?S#U!Et,|
"out 0x3b,r18\n"); //将页地址放入Z寄存器和RAMPZ的Bit0中
(H'yUz2R)I-pv ?]0 SPMCSR = code; //寄存器SPMCSR中为操作码 近场通信门户网 k!^&DR-]l&Y
asm("spm\n"); //对指定Flash页进行操作
O#Xig:V&x_$A,{p0}
tM&g7['^P0//填充Flash缓冲页中的一个字
8Ox,a-j|0void boot_page_fill(unsigned int address,int data) 近场通信门户网;u']$Mo2d ?0K kA
{
kDh-V6f0 asm("mov r30,r16\n"
-cq Wr0JHG@0 "mov r31,r17\n" //Z寄存器中为填冲页内地址 近场通信门户网#]i9pD1g1hP#h
"mov r0,r18\n" 近场通信门户网X}g&V |
"mov r1,r19\n"); //R0R1中为一个指令字
`z1D~&B0 SPMCSR = 0x01;
4Ml$})uq#Di9NR0 asm("spm\n");
-Rk0Mh'~*_i&r1N0}
CuVmgKF"{%p0//等待一个Flash页的写完成
&[*X F8f%})x3i/TX,sI0void wait_page_rw_ok(void) 近场通信门户网 V,LIez"gn6mc
{
T8X7j_,f1^/c gCc0 while(SPMCSR & 0x40)
4q8C-l3A/oZ9n0 {
*l-Z j$x+P*n0 while(SPMCSR & 0x01);
1UyB'f;v%L7WI0 SPMCSR = 0x11; 近场通信门户网 ?Q9I,LJ:y
asm("spm\n");
(B-Kk$^R3bX,@8f*j0 } 近场通信门户网GYO]0HVF
}
]!q~#fR1c0//更新一个Flash页的完整处理
3i8Eyn4\;n0void write_one_page(void) 近场通信门户网uL K IaGA
{ 近场通信门户网l~\U"`KA^
int i; 近场通信门户网;Pq9Q-p7h z1ig:WHg
boot_page_ew(address,0x03); //擦除一个Flash页
w*W%OnH)NDx B9aG0 wait_page_rw_ok(); //等待擦除完成
)S6rX'F*[^:r2S2_0 for(i=0;i<SPM_PAGESIZE;i+=2) //将数据填入Flash缓冲页中 近场通信门户网],O@uZ)`O,v7S5ij
{ 近场通信门户网U$Hj M}$tD'n9uw
boot_page_fill(i, data+(data[i+1]<<8));
6\ EJ;M Tg({+ny0 } 近场通信门户网I|4_&kXEZ
boot_page_ew(address,0x05); //将缓冲页数据写入一个Flash页
Bn7PdNlt ?0 wait_page_rw_ok(); //等待写入完成
,UVMz9N{0}
LZ Iho`N0//从RS232发送一个字节 近场通信门户网 W IBw@ T
void uart_putchar(char c) 近场通信门户网 w _#q ^%VDJ
{ 近场通信门户网[pUaU]0|
while(!(UCSR0A & 0x20));
.gc+l ^r0 UDR0 = c;
9nc!U;bG;qD0} 近场通信门户网m!]s)?)g&b%u
//从RS232接收一个字节
]G:F`2s+W2s"`Re0int uart_getchar(void) 近场通信门户网+ZK*Y-q&^0|
{ 近场通信门户网vn2Z!b*}3I[v:`4F'M
unsigned char status,res;
O3r(@nu c0 if(!(UCSR0A & 0x80)) return -1; //no data to be received 近场通信门户网Abjz2{u |g*F
status = UCSR0A;
W|(h/Z s C6P0 res = UDR0; 近场通信门户网0\4I(Uc'x AyC y%R8E
if (status & 0x1c) return -1; // If error, return -1
M5e,y'z V0 return res; 近场通信门户网Vt eG6y-P&Z3B
} 近场通信门户网X8^snV']4Y2u)q
//等待从RS232接收一个有效的字节
&JWQU#? ]E0N0char uart_waitchar(void)
.zvg0XU(Tu0{
%S GB$j:p*i0 int c;
(Kq3G+e.{5nV8j(p S r0 while((c=uart_getchar())==-1);
"zJ1P Us)?2iI?0 return (char)c; 近场通信门户网 M!W c6Io*H4N`
} 近场通信门户网,a PU+]F8D D$w
//计算CRC 近场通信门户网p G/b*Fe
int calcrc(char *ptr, int count)
JHVG:_ |9z0{
Ol#W5J AW K0 int crc = 0;
!| N$m0}%O.O(iw0 char i;
x1i,w f6F4PD}0
.i[x+H"?G1R0 while (--count >= 0) 近场通信门户网)YM7PdP'Jf
{
iifrU,L0 crc = crc ^ (int) *ptr++ << 8;
^g&c3~FEul0 i = 8; 近场通信门户网 k!@v7BgQ!^u$T j
do 近场通信门户网/r qKG,fc
{
z:J*u6` c0p p e0 if (crc & 0x8000) 近场通信门户网B*kYUS(VV)~
crc = crc << 1 ^ 0x1021;
y F N @ p(o3Y5`G0 else
md})bMh0 crc = crc << 1;
j4c7UR'V s0 } while(--i); 近场通信门户网L Vlz] J
} 近场通信门户网{1A|1d Qxb8N
return (crc); 近场通信门户网I v!qt6K%c?&Sr
}
@NUU+GsF H)YzEu0//退出Bootloader程序,从0x0000处执行应用程序
k\g)d*oUc&j)p&t\0void quit(void) 近场通信门户网:i%H(fo"E8@
{
)bA:E[2d4oJp!^0 uart_putchar('O');uart_putchar('K'); 近场通信门户网 }*`&pl`:Bs \*\
uart_putchar(0x0d);uart_putchar(0x0a); 近场通信门户网?D o\v*`WW)GW
while(!(UCSR0A & 0x20)); //等待结束提示信息回送完成 近场通信门户网8kW\w.RjSd
MCUCR = 0x01; 近场通信门户网2Ny:GK ~W2K YsO
MCUCR = 0x00; //将中断向量表迁移到应用程序区头部
%\c~ DX2`0z0 RAMPZ = 0x00; //RAMPZ清零初始化
vL^9G\G+P0 asm("jmp 0x0000\n"); //跳转到Flash的0x0000处,执行用户的应用程序
&DCa'S-j l\^t*M"R0}
RlzcCt?/K;K6YzE0//主程序 近场通信门户网!Na-t6^.E$fP
void main(void)
G!JF[|R9sBrW0{ 近场通信门户网I*f.m_ W(~
int i = 0;
W w^,T+} J,V#UFw0 unsigned char timercount = 0; 近场通信门户网2D3`f'G#O0]
unsigned char packNO = 1;
-XO$t${x y%[7l0 int bufferPoint = 0;
`FMLgy)K3E}0 unsigned int crc;
2xYn+t!ls4\0//初始化M128的USART0
IN!I eSw{0 UBRR0H = BAUD_H; 近场通信门户网w4H|G9r-p
UBRR0L = BAUD_L; //Set baud rate 近场通信门户网} dY!urXj4o
UCSR0B = 0x18; //Enable Receiver and Transmitter
8i7kk7W6OB8B;x8Ml0 UCSR0C = 0x0E; //Set frame. format: 8data, 2stop bit
f3j{-O \8J0//初始化M128的T/C0,15ms自动重载
+Y;f!V2o_c0 OCR0 = 0xEA; 近场通信门户网#v gB.qr/_O0`
TCCR0 = 0x0F; 近场通信门户网V#J4@n2J#t ^
//向PC机发送开始提示信息 近场通信门户网!q#J9Z_k-u
while(startupString!='\0')
\8Y/n$i5A0 {
9y[Cgcg#M"r?0 uart_putchar(startupString); 近场通信门户网Zj*L8]@V8A
i++;
o.]S;[w p RHct0 }
//3秒种等待PC下发"d",否则退出Bootloader程序,从0x0000处执行应用程序 近场通信门户网:^0S@*Q(M'Q
while(1) 近场通信门户网Y xb/L8DAI``
{ 近场通信门户网/r&OS1p6r+|%|+g
if(uart_getchar()== 'd') break; 近场通信门户网1J[:L[~9d*{+QG&B(I
if (TIFR & 0x02) //timer0 over flow
/Z&E+\,@,WI0 { 近场通信门户网!t9z1r$c8mh
if (++timercount > 200) quit(); //200*15ms = 3s 近场通信门户网g6U*nbs5m n4s%I
TIFR = TIFR|0x02;
4h;^"s{(o!b/c;@0 } 近场通信门户网[FRL$Pu9S!D})p$k
} 近场通信门户网E:M _a-HOS
//每秒向PC机发送一个控制字符"C",等待控制字〈soh〉 近场通信门户网z7b COiZpg6iP3?
while(uart_getchar()!=XMODEM_SOH) //receive the start of Xmodem 近场通信门户网A%vhAA1ht,p
{
okA&L4yB"`0 if(TIFR & 0x02) //timer0 over flow 近场通信门户网 ?+rb"T ]5K4B`
{
-L7p3d]:M\ d(I0 if(++timercount > 67) //wait about 1 second 近场通信门户网MA8b'pT2f%Ka
{ 近场通信门户网2y"M}-i)@F-c"z4B@'v]
uart_putchar(XMODEM_RECIEVING_WAIT_CHAR); //send a "C" 近场通信门户网 X$v D`)P/^3l
timercount="0";
0?\tA[sWB0 } 近场通信门户网/G]y3F8Q
TIFR="TIFR" | 0x02;
-D A(R:L*~ Vz)?7X0 } 近场通信门户网3y5gwlQ(cR#vg
} 近场通信门户网3l%Y3Qf.\3ts/k
//开始接收数据块 近场通信门户网!PlA$q]5Jf.y7Ib.T
do 近场通信门户网M4C"[y2uE-?/lvg1r
{
O[['Dl@2X+F f }0 if ((packNO == uart_waitchar()) && (packNO ==(~uart_waitchar()))) 近场通信门户网H?-Va~jH7P
{ //核对数据块编号正确
)H%?g3Q;F s5V0 for(i=0;i<128;i++) //接收128个字节数据
*p-r1mT;e+qF6P}s0G0 {
NFvSmGOk0 data[bufferPoint]= uart_waitchar();
p'C1Z.n(k^m+q0 bufferPoint++;
6Hv.av7@M0 } 近场通信门户网 A"Irq4E~?u*ZF:Gp
crc = (uart_waitchar()<<8); 近场通信门户网!m[#Cb,EXq
crc += uart_waitchar(); //接收2个字节的CRC效验字
)U/FKF G9{1m J0 if(calcrc(&data[bufferPoint-128],128)==crc) //CRC校验验证 近场通信门户网U%Q6_8?[U
{ //正确接收128个字节数据
:?T|A%\-nf0 while(bufferPoint >= SPM_PAGESIZE) 近场通信门户网'dG;xBC#} HK x
{ //正确接受256个字节的数据 近场通信门户网#Wu5R/k rA.~&e
write_one_page(); //收到256字节写入一页Flash中
kF2N'e5^/XO0 address += SPM_PAGESIZE; //Flash页加1
F,q;uR3t0QJV [ e0 bufferPoint = 0; 近场通信门户网tu!wvTp
} 近场通信门户网+? qVU6{)Z _ wq
uart_putchar(XMODEM_ACK); //正确收到一个数据块
nd1~mXk0 packNO++; //数据块编号加1 近场通信门户网 ze0~Q r Y
} 近场通信门户网1|A_,f,A'G$Gsg!v
else 近场通信门户网"`Q3n3_:i
{ 近场通信门户网f(Z!iS g/H6Xy [,Q
uart_putchar(XMODEM_NAK); //要求重发数据块
ur ^"k|gp:_.M7O0 }
S0f`Z%] t0 } 近场通信门户网'S+ihfR{~ `
else
r ^0x2U.uAe0 {
P]CBo,u%q1Z0 uart_putchar(XMODEM_NAK); //要求重发数据块 近场通信门户网+tuJuf k z3T
} 近场通信门户网&~bR6qc'L-{F$c'}8C3R
}while(uart_waitchar()!=XMODEM_EOT); //循环接收,直到全部发完 近场通信门户网5N W `!`.rs:h
uart_putchar(XMODEM_ACK); //通知PC机全部收到
l&X`l7X&u0 近场通信门户网-y/W_0Z5x1Y5cY0N
if(bufferPoint) write_one_page(); //把剩余的数据写入Flash中
.G/u9|:\t0B*l#x0 quit(); //退出Bootloader程序,从0x0000处执行应用程序 近场通信门户网.|T z8]-?
}
程序的主体部分采用C高级编写,结构性好,程序的相应部分都给出了比较详细的注释说明,读者非常容易读懂和理解。下面再对程序做进一步的说明。
:|%Dbg&C{0(1) 函数"void write_one_page(void)" 实现了对ATmega128一个Flash页的完整编程处理。当程序从串口正确接收到256个字节后,(ATmega128一个Flash页为128个字),便调用该函数将其写入ATmega128一个Flash页中。函数先将一个指定的Flash页进行擦除;然后将数据填入Flash的缓冲页中,最后将Flash 缓冲页的数据写入到该指定的Flash页中(详细技术细节见第二章相关内容的介绍)。 近场通信门户网1b5z;WT%U^
(2) 一个Flash页的擦除、写入,以及填充Flash缓冲页的函数采用内嵌AVR汇编完成,在ICCAVR中,寄存器R16、R17、R18、R19用于传递一个C函数的第1、2个参数(int类型)或第1个乘数(long类型),具体参考ICCAVR应用说明。
Lpj-r.Kdm0(3) 函数"void quit(void)"的用途是退出Bootloader程序,从Flash的0x0000处执行用户的应用程序。在执行强行跳转指令"jmp 0x0000"前,对寄存器MCUCR的操作是将中断向量地址迁移回应用程序区的头部,因为在ICCAVR环境中编译Bootloader程序时,其自动把中断向量地址迁移到了Bootloader区的头部。为了保证能正确执行用户的程序,在跳转前需要把中断向量地址迁再移回应用程序区的头部。
ExVc0B(d0(4)在这段Bootloader程序中使用的硬件资源为T/C0和USART0,用户在编写其应用程序时,应首先对这两个硬件资源相关的寄存器重新做初始化。
O:?afrb4p*mAt1P8U8x0(5) Bootloader程序占具并住留在Flash的最高1K字空间内,因此实际的应用程序空间为63K字(126K字节),所以用户编写的应用程序不得超出126K字节。同时应将ATmega128的熔丝位BLB12、BLB11的状态设置为"00",禁止SPM和LPM指令对Bootloader区的读写操作,已确保Bootloader程序不被改写和擦除。 近场通信门户网.jbv? p!uvd_:M
5.2.3 IAP的实现与应用
(V/f&kBC$R)V\JE01. Bootloader程序的编译与下载
,[%vt D5ZM*Gs0首先在ICCAVR中新建一个工程项目,并按照生成Bootloader程序代码的要求进行正确的设置。打开Project -> Options的Compiler Options设置选项窗口,见图5.1: 近场通信门户网*R)Je)K5g
(1) 在Device Configration栏中选定器件ATMega128; 近场通信门户网%N jAvlJi$T"r
(2) 选定Use RAMPZ/ELPM项(ATMega128的Flash > 64K字节);
FeI"X WS9I0(3) Program Type选定为Boot Loader; 近场通信门户网o1{;_mI-}M)Tg/cE
(4)Boot Size选择1K Words。
正确设置好编译选项后输入C的源代码,然后编译生成.HEX的下载代码程序。 近场通信门户网:^E W Z-jf}0u
在下载HEX文件前还要对ATmega128芯片的熔丝位进行正确的配置: 近场通信门户网h]8PlCR"x
(1) 配置M103C熔丝位,使芯片工作于ATmega128方式; 近场通信门户网8| R!mX8K(L;W2d_
(2) 配置BOOTSZ1和BOOTSZ0熔丝位,设定BOOTLOADER区的大小为1024个字,起始首地址为0xFC00; 近场通信门户网.y q_z%zN
(3)配置BOOTRST熔丝位,设定芯片上电起动从BOOTLOADER区的起始地址处开始,即每次RESET复位后从0xFC00处执行Bootloader程序;
5uO kz:DfZ {0(4)下载Bootloader程序的HEX文件; 近场通信门户网n;j$GlrK-`
(5) 配置LB2和LB1熔丝位,加密程序; 近场通信门户网|0Ho9[.e/A7iKu-v"M
(6)配置BLB12和BLB11熔丝位,对BOOTLOADER区进行安全锁定。 近场通信门户网} `CEzqN
特别注意的是,以上对芯片熔丝位的配置以及Bootloader程序的下载,需要由ISP、或JTAG、或并行方式实现,既要实现IAP,首先还需要使用一次非IAP的编程方式来建立IAP的应用环境。
2. IAP应用
gOw^1@ z I;f]cr/c-@0当你按照上面的方法将Bootloader程序下载完成后,就可以使用它来下载你的应用程序了。具体操作如下。
3{"V*s*} ^0(1) 编写你的应用程序,编译生成HEX文件; 近场通信门户网/a!p~~ON"B3W
(2)使用HEX2BIN.EXE转换程序,将HEX文件转换成BIN文件;
RB*Tc+KY Xa7Fu0(3)使用普通的RS232电缆将PC机的串口与ATmega128的串口连接; 近场通信门户网T'g.YU}G5y Z1@
(4)打开WINDOWS中的超级终端软件,正确设置COM口的参数:38400,1,8,无,2,无(使用2位停止位提高通信可靠性);
cSmn&\2c z'P0(5)ATmega128上电,在PC超级终端收到"Type 'd' download, Others run app."的Bootloader程序启动的提示详细;
Z/Y+O:y[X(L8Z0(6)3秒钟内在PC上按下"d"键,通知Bootloader程序转入接收数据并更新应用程序的处理。3秒钟内没有按"d"键,PC超级终端收到"OK"提示,Bootloader程序退出,自动转入执行芯片内原有的用户应用程序(如果有的话,否则再次启动Bootloader程序); 近场通信门户网'ixL%L3C4Pzv
(7)当PC超级终端收到"C"(一秒钟一个),说明Bootloader程序转入接收数据和更新应用程序的处理流程,正在等待PC下发数据; 近场通信门户网,sCkl@8w1Z X+s
(8)在PC超级终端上的工具栏中选择"传送->发送文件",在发送文件窗口选择协议"Xmodem",文件栏中选定要下载应用程序的BIN文件,单击发送按钮;
p)l&lJ5gc0(9) 此时出现文件发送窗口,显示文件发送的过程和进度,以及是否出错; 近场通信门户网y/V-`X_%i
(10)当文件全部正确发送完成后,PC超级终端收到"OK"提示,Bootloader程序退出,自动转入执行刚更新的用户应用程序。 近场通信门户网 DS2y2S7P1M$z
在ATmega128中烧入这样一个Bootloader程序,建立了IAP后,最基本的开发AVR的环境就简化成"PC+RS232电缆+目标板"。读者在掌握了Bootloader程序编写的原理后,可以编写自己的Bootloader程序,实现系统程序的自动远程网络更新等应用。
R8@sMz:^e0AVR的BOOTLOADER功能同其它一些芯片不同,它的BOOTLOADER程序没有固化(固定)在芯片内部(出厂为空),而是需要由用户设计实现(实际上,你第一次下载BOOTLOADER程序还必须使用其它的方式编程,如ISP、JTAG等),因此对一般的用户掌握起来有一定的困难,不如一些其它芯片的固化IAP使用方便。但对高手来讲,可以根据实际需要编写高级、高效、专用的BOOTLOADER程序,如从一个U盘读取数据,更新用户的应用程序;编写一个时间炸弹,或对用户的密码进行验证,10次不对则将系统程序销毁等等。简单意味着使用方便,但灵活和适应性差,而灵活性需要你具备更高的能力去驾驭它。可能会有一天,在单片机的系统上也出现了"病毒"程序,其原因就是使用了固化的BOOTLOADER程序。由于固化(固定)的程序采用规定公开(开放)的接口,那么用一个带"病毒"的应用程序更新原来的应用程序也就轻而易举了。
文章评论(0条评论)
登录后参与讨论