TMS320F28335串口二阶bootloader详解
[复制链接]
将程序分为两个工程,即BOOT引导程序和用户程序,boot引导程序储存在单独的sector里,用户程序存在另外的sector,引导完成后使用指针进行跳转
生成HEX文件
.out文件不能直接进行BOOT烧写,需要将用户程序的.out文件转换为HEX,BOOT程序先用烧写器烧写进芯片,然后再讲HEX通过串口发送到芯片由BOOT程序完成烧写,这里可以使用HEX2000等工具软件完成,注意HEX文件格式应为 地址-数据 地址-数据 或一个地址(flash sector)后跟一坨数据,在分配BOOT程序地址时应注意不与用户程序地址冲突 否则会出现花里胡哨的BUG
CMD文件修改
因为28335的flash只能按sector擦除,Boot引导程序和用户程序需要储存在不同的Flash sectoer中,故需要在CMD文件中进行修改,先让程序进入Boot引导程序,进行要升级程序的接收,在RAM里运行擦除及烧写flash,然后再跳转到用户程序执行。
以将BOOT程序存在flashA为例 需要修改的地方如下:
FLASHA : origin = 0x338002, length = 0x007F7E /* on-chip FLASH */
BEGIN : origin = 0x338000, length = 0x000002 /* Part of FLASHA. Used for "boot to Flash" bootloader mode. */
Flash28_API:
{
-lFlash28335_API_V210.lib(.econst)
-lFlash28335_API_V210.lib(.text)
} LOAD = FLASHA,
RUN = RAML0,
LOAD_START(_Flash28_API_LoadStart),
LOAD_END(_Flash28_API_LoadEnd),
RUN_START(_Flash28_API_RunStart),
PAGE = 0
/* Allocate program areas: */
//.USER_CODE : > FLASHE PAGE = 0
.cinit : > FLASHA PAGE = 0
.pinit : > FLASHA PAGE = 0
.text : > FLASHA PAGE = 0
codestart : > BEGIN PAGE = 0
// ramfuncs : > FLASHH PAGE = 0
ramfuncs : LOAD = FLASHA,
RUN = RAML0,
LOAD_START(_RamfuncsLoadStart),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
PAGE = 0
升级过程
当不需要升级程序时需要跳过Bootloader进入主程序,这里我的思路为等待超时0.5S未收到上位机指令则认为不需要升级程序,直接跳转到用程序,跳转代码如下:
#define FlashH 0x300000
Uint32 BeginAdress=FlashH; //为了后期可进行由上位机指定的地址烧写,可不用
inline void UserMain()
{
(*(void(*)(void))BeginAdress)();
}
当需要进行烧写时,则用到了TI的flash API,协议可由自己拟定,若文件较小可采用单次接收完再烧写,文件较大则采用上位机分包。这里提供烧写示例和擦除示例:
char Erase_Sec_Once(Uint16 Sector)
{
char outflag = 0xff;
DINT;
if(SysCtrlRegs.PLLSTS.bit.MCLKSTS==0)outflag=Flash_Erase(Sector, &FlashStatus);
EINT;
return outflag;
}
if(Erase_Sec_Once(SECTORH|SECTORG|SECTORF|SECTORE|SECTORD|SECTORC|SECTORB)!= STATUS_SUCCESS) UartXmit("EraseErro\r\n");
else UartXmit("OK\r\n");
if(Flash_Program((Uint16 *)ProgAdress,(Uint16 *)UartBuf,DatNum,&FlashStatus)!=STATUS_SUCCESS) UartXmit("ProgramErro\r\n");
else ProgAdress+=DatNum;
Flash_Erase和Flash_Program均为TI提供的API函数
烧写完成后由指针跳转到用户函数,即烧写的首地址
注意,进行BOOT烧写后不能再使用调试器进行烧写或调试,否则会覆盖掉boot程序,这里建议首先将用户程序调试完成再由BOOT烧写
|