8051单片机BOOT设计方案.docx
《8051单片机BOOT设计方案.docx》由会员分享,可在线阅读,更多相关《8051单片机BOOT设计方案.docx(16页珍藏版)》请在冰豆网上搜索。
8051单片机BOOT设计方案
8051单片机BOOT设计方案
CDMA事业部支撑软件部周志雄张彦春
【摘要】本文论述了8051单片机BOOT的功能、设计方法、设计流程,内外接口等。
【关键词】8051单片机,BOOT,Flash
1引言
现在我们公司的单片机系统都要求能够实现远程的软件下载,同时为了生产和调试的方便,要求单片机系统在脱离机框的情况下也能够通过调试口下载。
公司现阶段采用的可下载单片机主要有3款:
SST的89V/E564RD、ATMEL的T89C51RD2、Winbond的W78LE516P,CDMA事业部同时采用了这3款芯片,要求这三款芯片的BOOT对外接口完全一致,以简化硬件设计和接口软件设计。
本设计方案支持多路数据下载,动态检测下载的数据通道,完成消息握手,数据交互,校验,写并校验Flash,BOOT和版本程序互相切换等操作。
本方案仅仅在操作flash的地方根据不同的单片机作了改动即满足了要求,方便向更多的单片机移植。
下面主要以T89C51RD2作为范例描述BOOT的设计方法。
2BOOT_T89C51RD2
2.1设计思想
Atmel公司的T89C51RD2有64K的FLASH,256字节的内部RAM,1K字节的外部RAM,自带BOOT。
缺省情况下,BOOT大小为1K字节,位于FLASH的FC00H-FFFFH空间范围内。
由于这个BOOT中有读写Flash,更改状态字的API函数的入口,而且芯片的状态字也包含在这块Flash区间内,所以我们必须保留这个默认的BOOT程序。
由于这款芯片没有为BOOT提供一个单独的Flash区间,BOOT程序和用户的版本程序在同一块64K的Flash空间内,因此,对FLASH区进行重新规划。
重新规划后的FLASH区分配如下图:
出于安全性的考虑,3G中要求单板启动后首先进入BOOT,在等待一段时间后,如果没有软件下载的握手消息,BOOT自动跳入用户的版本程序执行。
考虑到调试的方便,BOOT必须同时支持调试口软件下载。
为了上电后进入BOOT,T89C51RD2提供了两种方式:
硬件方式和软件方式。
如图中所示,采用硬件方式只能从0xFC00处,即芯片自带的BOOT启动。
所以我们采用软件方式进入BOOT,如图中蓝线所示。
如果在等待一段时间后,没有软件下载的握手消息,BOOT沿红线自动跳入用户的版本程序执行。
整个过程不需要硬件的参与,完全由软件来实现正常状态与BOOT状态的互相转换。
在烧录器上烧录文件时的步骤:
Ø打开烧录器,选择设备为Atmel的T89C51RD2
Ø连续载入厂家自带的BOOT,我们的BOOT,版本程序三个HEX文件,每次载入时选择UnusedBytes都是Don’tCare
Ø在Config设置中将SoftwareBootVector由FC改为F0,将BootLoaderJumpBit打勾选中
Ø用Auto烧录
BOOT的启动流程图:
2.2对外接口
流程说明:
✧单板应用程序收到软件下载进程或调试后台发来的E_O_R_MCUDownloadVerReq下载版本请求消息后,保存参数(若需要),然后复位重启,进入BOOT;
✧BOOT程序启动后,同时向片内串口和ST16C550回E_R_O_MCUDownloadVerAck消息,表示进入下载等待状态。
然后开始计时并同时监听片内串口和ST16C550上来的数据,如果超时,跳入用户版本程序;
✧软件下载进程或调试后台通过E_O_R_MCUVerData消息将版本数据传送至单板BOOT,BOOT一旦从一个通道检测到第一个正确包,则不再监听另一个通道;
✧BOOT在收到正确的版本数据后,回E_R_O_MCUVerDataAck消息给软件下载进程或调试后台,消息体中含需要的下一帧数据的帧号,为上次帧号加1;若BOOT收到错误的版本数据后,回E_R_O_MCUVerDataAck消息给软件下载进程,消息体中含需要的下一帧数据的帧号,帧数与上一次相同;
✧以上两步周而复始,直至下载到最后一帧。
软件下载进程或调试后台在发送最后一帧数据时,将帧号改为0xFFFE,表示这是最后一帧,BOOT接收到后,如果一切成功,回应帧号0xFFFF,然后跳入用户程序,如果接收或写Flash错误,需要重传,向后台回应帧号仍然为上次回应的帧号(不是0xFFFE)。
✧软件下载进程或调试后台在收到帧号0xFFFF的帧后,表示下载完成。
消息结构说明:
E_O_R_MCUDownloadVerReq消息结构
typedefstructtagT_M_MCUDownloadVerReq
{
WORDModuleType;
BYTESlotID;/*0xff表示广播消息,其他为指定下载*/
}T_M_MCUDownloadVerReq;
E_R_O_MCUDownloadVerAck消息结构
typedefstructtagT_M_MCUDownloadVerAck
{
WORDModuleType;
BYTESlotID;
BYTEAckFlag;/*0:
SUCCESS,1:
Failure*/
}T_M_MCUDownloadVerAck;
E_O_R_MCUVerData消息结构
typedefstructtagT_M_MCUVerData
{
WORDSequence;//包序号,0:
第一包;1:
第二包,0xfffe最后一包。
WORDLength;/*本包实际数据长度
MCUData_BufArrayBuf;
BYTEChecksum;/*消息数据校验和:
Buf中所有字节的累加和,只保最后字节,越界进位丢弃*/
}T_M_MCUVerData;
#defineMAXMCUDATA128
typedefBYTEMCUData_BufArray[MAXMCUDATA];
E_R_O_MCUVerDataAck消息
typedefstructtagT_M_MCUVerDataAck
{
WORDNextSequence;/*下一帧序号,E_O_R_MCUVerData消息结构Sequence+1,接受错误则,返回Sequence再次请求上一帧;*/
BYTEAckFlag;/*失败原因:
0:
SUCCESS,1:
接收失败,2:
写FLASH失败/
}T_M_MCUVerDataAck;
2.3软件设计
为了实现预定的功能,我们总结BOOT需要完成的具体软件功能:
Ø读写Flash
Ø同时监听片内串口和外接的ST16C550,申请和释放485总线,完成数据收发
Ø处理485帧格式
Ø能够跳到用户的版本程序
Ø喂狗
ØBOOT版本号的处理
由于整个下载过程中采用发送——接收——处理——回应的方式工作,故整个程序采用一个完全串行化的处理流程。
主程序流程如图所示:
由于BOOT程序的特殊性,考虑到T89C51RD2的芯片特性,我们需要注意以下几个问题:
Ø因为BOOT程序和用户版本在同一块64K的Flash中,所以在BOOT程序中要避免使用中断(中断服务程序的入口地址在用户版本程序的空间中),所有的中断(包括时钟中断、串口中断、外部中断)都使用查询方式进行。
Ø因为BOOT程序的起始地址为0xF000,所以必须更改程序启动的初始位置为0xF000,故STARTUP.A1文件必须重载。
方法为从KeilC的“..\C51\LIB\”目录中得到STARTUP.A1,将第91行的“CSEGAT00000H”改为“CSEGAT0F000H”,并将新文件加入工程。
Ø为了保证BOOT程序的安全性,程序不能使用片外RAM。
由于为了接收长帧,必须开一个比较大的缓冲区,所以必须使用芯片内部的XRAM。
Ø由于BOOT和版本程序在同一块Flash中,所以在BOOT态和正常态转换时只需要将所有的特殊寄存器清零,退出2级中断,然后跳到0x0000执行即可(虽然BOOT中没有使用中断,但是保险起见,需要调用2次RETI退出中断嵌套)。
ØBOOT版本号的处理:
在BOOT程序中将版本号作为一个常量定义,每次BOOT在启动的时候将这个BOOT版本号放在SRAM的最高点,初定为0x7FFD-0x7FFF共3个字节,版本软件启动后从这个内存区间中读出BOOT版本号。
2.3.1系统初始化
系统初始化的主要工作是将需要用到的设备和全局变量进行初始化。
具体的初始化步骤:
Ø串口初始化:
采用定时器1作为波特率发生器,采用外部晶振为11.0592MHz,采用的波特率为19200bps,具体单板根据自身采用的晶振和485总线波特率的不同自行更改。
ØST16C550初始化:
采用外部晶振为11.0592MHz,采用的波特率为19200bps,具体单板根据自身采用的晶振和与后台通讯波特率的不同自行更改。
ST16C550的地址采用杜江编写的3G单板统一编址。
Ø时钟初始化:
定时器0采用模式1的16位定时器。
2.3.2数据收发
为了方便调试,BOOT既支持通过片内串口的485通讯,又支持通过ST16C550的232通讯。
因此数据的收发有2条通道。
在BOOT刚刚启动的时候,并不知道当前是哪个通道需要下载,故向2个通道都打出握手消息,然后用查询方式监听2个通道,同时开始计时。
如果哪个通道有正确的数据上来,关闭计时,关闭另一个通道,开始在这个通道上收发数据。
2个通道的数据收发都采用查询方式。
2条通路都采用同样的数据帧格式,即3G485通讯协议。
2.3.3读写Flash
T89C51RD2的64Kflash的读写采用API函数的方式进行。
Atmel公司提供了flash_api.h、flash_api.c、flash_lib.asm共三个源程序供用户使用。
我们首先将这3个文件加入我们的工程,然后进行定制。
flash_api.h文件:
我们需要使用Flash页写功能,故打开#define__API_WR_CODE_PAGE。
flash_lib.asm文件:
__API_FILL_FF_PAGE函数必须在处在64Kflash的低31k空间中,与我们BOOT程序的区域划分存在矛盾,故注释掉相关代码。
flash_api.c文件:
在我们使用的__api_wr_code_page函数中调用了__API_FILL_FF_PAGE函数,需要注释掉。
3BOOT_SST89V564RD
3.1设计思想
SST89V564RD提供了2块Flash区间用于分别存放用户版本程序和BOOT程序,即64K的Block0和8K的Block1。
它提供了256字节的内部RAM,768字节的外部RAM。
SST公司提供了一个自带的BOOT程序,并提供了相应的汇编源代码。
由于这款芯片的Flash的读写提供了相应的IAP命令时序,不需要依靠芯片自带的BOOT,所以我们去掉这个芯片的自带BOOT,替换为我们的BOOT程序。
3G要求所有芯片的BOOT必须完全兼容。
所以这款芯片也是首先从BOOT启动,在等待一段时间后,如果没有软件下载的握手消息,BOOT自动跳入用户的版本程序执行。
SST89V564RD没有提供硬件拉管脚的方法来从哪个Block启动或从一个Block跳到另一个Block。
芯片提供了一个编程位(Prog-SC0)来标示在单片机上电后是从Block0还是从Block1启动,这个编程位在烧录时给定,我们设定为从Block1的BOOT启动(默认就是,在烧录时不需要更改)。
从Block1的BOOT程序跳转到Block0的用户程序采用更改特殊寄存器SFCF软件复位的方法(如下图中的C方法)。
SST89V564RD的BOOT启动、正常状态与BOOT状态的互相转换完全由软件来实现,整个过程不需要硬件的参与,与T89C51RD2完全兼容。
SST89V564RD提供了对Flash的软锁和硬锁两种写保护,由Prog-SB1、Prog-SB2、Prog-SB3的0/1的六种组合对Flash提供4个不同级别的保护。
我们采用第三个保护级别:
对Block1硬锁,对Block0软锁;安全设置位SFCT[7:
5]=001b或110b;所有的外主模式命令(除Chip-Erase和Prog-SBx)被禁止;只能在Block1中用IAP命令操作Block0;从Block1到Block0的MOVC指令有效,从Block0到Block1的MOVC指令无效。
在烧录器上烧录BOOT文件时的步骤:
Ø打开烧录器,选择设备为SST的SST89V564(PLCC)
Ø载入BOOT的HEX文件,选择UnusedBytes为Don’tCare
Ø打开Auto,将Prog-SB3上的勾去掉,然后点击RUN烧录
就目前得到的资料,包括向供应商咨询的结果,SST89V564RD不支持同时烧录BOOT和版本程序,现在的解决方案是首先用烧录器烧录BOOT文件,然后用支撑包后台将版本软件下进去。
两块Flash切换的示意图:
3.2对外接口
与3.2节相同。
3.3软件设计
软件设计与3.3节基本一致,这里给出不同之处:
Ø对Flash的读、写、擦除采用芯片提供的IAP命令实现,所用寄存器和命令如下表:
特殊寄存器
用途
SFCF
EnableIAPandmake4KFlashmemoryblockvisible
SFDT
Data
SFAH
Highorderaddressbyte
SFAL
Loworderaddressbyte
SFCM
Command#(0x0D:
EraseBlock0;0x0E:
Program_byte;0x0C:
Byte_verify)
SFST
MonitorFlash_busybitforCommandCompletionorwaitforINT1#interrupt
Ø从BOOT向版本程序跳转的方法:
采用软件复位的方法直接从Block1切换到Block0的0x0000执行。
SST89V564RD提供了一种快速方便的切换方式:
只要将特殊寄存器SFCF的Bit1从0变为1,就会自动触发一个软件复位,复位后开始从0x0000执行Block0的代码。
4BOOT_W78LE516P
4.1设计思想
W78LE516P提供64K的可ISP编程的APROM用于存放用户的版本程序,4K的LDROM用于存放BOOT。
提供了256字节的内部RAM,256字节的AUX-RAM。
根据3G的要求,用户的版本程序应该与BOOT程序完全独立,即BOOT程序的执行不能依赖于用户程序。
T89C51RD2和SST89V564RD由于上电后首先进入BOOT程序,再跳入用户程序的方法,所以满足了要求,而W78LE516P没有提供通过烧录编程位让芯片一上电就进入4KLDROM的方法。
W78LE516P提供了一种称作F04KBOOTMODE的硬件方法可以让芯片在上电后进入LDROM,而采用这种方法启动进入BOOT程序后没有办法用软件方法跳到用户区,必须重新在外部采用硬复位(不满足F04KBOOT时序)的方法让单片机从用户版本程序启动,所以用逻辑做出F04KBOOT时序,让单片机每次复位进入BOOT的方法不能适用于这款芯片。
如图:
为了满足3G的要求,同时为了与前面2款芯片兼容,决定采用以下方法:
Ø芯片上电时正常启动,运行用户版本程序。
Ø主控板要求下载时,拉下载使能线。
Ø由于P2.6、P2.7这两个管脚在C51单片机中通常有其他用途;而P4.3这个管脚通常不用,在AtmelT89C51RD2和SST89V564RD中均是空管脚,所以为了保持三款芯片的兼容性,我们将P4.3这个管脚引入EPLD。
单板逻辑平时让单片机P4.3脚保持高电平,在检测到下载使能后,用上图中的时序复位单片机,让单片机进入BOOT态,在复位后将P4.3拉高。
同时要注意P2.6、P2.7这两个管脚,为了安全,在正常启动时最好将这2个管脚也拉高,启动完后进入高阻态。
ØBOOT程序下载完毕后复位看门狗,同时主控板将下载使能线恢复,让芯片从正常状态启动进入用户版本程序。
W78LE516P用一个位于LDROM的0xFFFF处的特殊寄存器来提供对程序的安全性保护,在烧录器的Config中可以对这个寄存器编程。
我们将LockBit和MOVCInhibit这两位设置为0,保护我们的代码不被异常更改。
在烧录器上烧录文件时的步骤:
Ø打开烧录器,选择设备为Winbond的W78LE516
Ø载入用户版本软件的HEX文件,选择UnusedBytes为Don’tCare
Ø载入BOOT的HEX文件,选择UnusedBytes为Don’tCare,BuffStart为0x10000
ØConfig中将SetLockBit设为Active,将SetMOVC设为disable
Ø打开Auto,点击RUN烧录
4.2对外接口
与3.2节相同。
4.3软件设计
软件设计与3.3/4.3节基本一致,这里给出不同之处:
Ø对APROM的擦除、读、写:
首先设置定时器中断,根据不同的ISP命令的执行时间设定定时器初值,然后对几个特殊寄存器附值来设置ISP命令,打开定时器中断,进入IDLE状态。
在定时器中断到时后,芯片被唤醒,ISP命令就执行完毕,程序从刚才停止的地方接下去执行。
这里需要注意的一点是用于唤醒IDLE态的时钟中断需要写一个空的中断服务程序,否则即使打开了中断,IDLE态也不会被唤醒。
Ø为了BOOT程序的安全性,要使用芯片内部的XRAM。
T89C51RD2和SST89V564RD都是通过设置AUXR(0x8E)这个寄存器来实现片内XRAM和片外XRAM的映射转换的,设置的比特位和值都一样。
而W78LE516P这款芯片的设置位为CHPCON(0xBF),必须采用ISP编程的方法才能更改。
Ø从BOOT向版本程序跳转的方法:
如果芯片是通过软件跳转的方法从APROM跳到LDROM的,特殊寄存器CHPCON被附值0x83将导致芯片的软件复位,在复位后芯片将从APROM启动;而采用硬件的方法(F04KBOOT)进入LDROM的话,这种软件复位的方法就没有办法跳到APROM,只在LDROM中重启。
所以我们需要调用MAX706复位,用外部的硬复位进入APROM。
这里需要注意的是在正常情况下的启动必须注意P4.3、P2.6、P2.7这三个管脚,避免误进入F04BOOT模式。
参考文献
1.T89C51RD2.pdf
2.In-SystemProgramming-T89C51RD2BootloaderOperating.pdf
3.SST89V564RD.pdf
4.SST89E/V554RC/SST89E/V564RDSecurityFeatures.pdf
5.SSTFlashFlex51MicrocontrollerIn-ApplicationProgrammingBasics.pdf
6.MemoryBlockSwitchingontheSST89E/V564RDandSST89E/V554RCMicrocontrollers.pdf
7.w78le516.pdf
8.马忠梅等著,“单片机的C语言应用程序设计”,北京:
航空航天大学出版社,1997.3