DSP在线升级(2)--bootloader的设计框架
DSP在线升级(3)-----一块DSP芯片的片上flash如何烧写2个工程
DSP在线升级(4)-----bootloader实现的功能
对于DSPTMS320F28377D,首先查看芯片手册,了解该芯片的片内存储资源;
包括RAM以及ROM(flash);查找的芯片资源如下(图1):
图1
其中上图红色部分是用户可以擦除和烧写的rom部分(F系列以flash为主);
Secure rom以及boot rom是Ti出厂就已经固化好的代码,用户不需要去操作;
dsp28377片上有256K的flash,flash分为多个扇区,flash内部具体的划分方式如下(如图2):
图2
在线升级的具体思路是,升级程序bootloader和主应用程序分开,分为两个工程;
工程1:bootloader
编写以及调试完成后,bootloader代码固化在FLASH的sector A 和sector B(按需求确定固化的flash地址和范围),之后flash sector A和B的内容保持不变,bootloader不再改变;应用工程代码,可以通过bootloader来进行烧写、在线更新;
需将bootloader的 codestart 地址设置为 0x80000(即芯片上电运行完系统代码后,执行的第一条指令的地址)
工程2:应用工程
应用工程,需要保证CMD文件链接的所有代码段(包括数据段)都限制在 flash sector C及以后;
需将应用工程代码的codestart起始地址设置为 0x84000(或者该地址之后,按需设置)
需要注意 CMD文件中链接代码需要限制64bit对齐 ,须在SECTIONS{ }中添加条件ALIGN(4)
例如: .cinit : > FLASHD, PAGE = 0, ALIGN(4)
.text : > FLASHD, PAGE = 0, ALIGN(4)
bootloader和应用工程在芯片的flash中,正常的启动流程如下:
图3
1、上电不需要升级时(图3):
当正常启动,不需要在线升级时:程序直接由bootloader程序跳转至主应用程序;
不需要在线升级时,系统上电直接先运行bootloader程序,由bootloader程序直接跳转至主应用程序 main application。
图4
2、当需要在线升级时(图4):
系统上电直接先运行bootloader程序,通过上位机串口收发工具向DSP发送升级指令;dsp此时运行着bootloader,并且进入等待升级状态;
再通过上位机的串口收发工具发送main application的可执行文件(通常为bin文件或者hex文件);
bootloader擦除除了flash sector AB 以外的其他sector;
然后将可执行文件烧写至对应的flash sector中即可;
此时我们需要的仅为TI 提供的flash操作函数;
Fapi库;
通常只需要下面的一些函数:
Fapi_initializeAPI(, , , ); Flash初始化
Fapi_setActiveFlashBank(Fapi_FlashBank0); 检测flash的扇区是否为初始化状态
Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, Bzero_SectorC_start);
flash扇区擦除;
Fapi_issueProgrammingCommand((addr),Buffer,4,0,0, Fapi_AutoEccGeneration);
flash烧写(在给定的地址烧写内同);
上诉的库函数需要去看TI的手册,或者看官方的flash操作例程;
由于一个片上FLASH上烧写了两个工程文件;
我们需要对两个工程的cmd文件的配置做简单的说明;
1、bootloader工程;
cmd文件的配置和一般工程相同;
MEMORY
{
PAGE 0 : /* Program Memory */
/* Memory (RAM/FLASH) blocks can be moved to PAGE1 for data allocation */
/* BEGIN is used for the "boot to Flash" bootloader mode */
BEGIN : origin = 0x080000, length = 0x000002
RAMM0 : origin = 0x000122, length = 0x0002DE
RAMD0 : origin = 0x00B000, length = 0x000800
RAMLS03 : origin = 0x008000, length = 0x002000
/* RAMLS1 : origin = 0x008800, length = 0x000800
RAMLS2 : origin = 0x009000, length = 0x000800
RAMLS3 : origin = 0x009800, length = 0x000800 */
RAMLS4 : origin = 0x00A000, length = 0x000800
RAMGS14 : origin = 0x01A000, length = 0x001000 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
RAMGS15 : origin = 0x01B000, length = 0x001000 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
RESET : origin = 0x3FFFC0, length = 0x000002
/* Flash sectors */
PROGRAM_SECTOR : origin = 0x080002, length = 0x003FFE
/*
FLASHA : origin = 0x080002, length = 0x001FFE
FLASHB : origin = 0x082000, length = 0x002000
*/
FLASHC : origin = 0x084000, length = 0x002000 /* on-chip Flash */
FLASHD : origin = 0x086000, length = 0x002000 /* on-chip Flash */
FLASHE : origin = 0x088000, length = 0x008000 /* on-chip Flash */
FLASHF : origin = 0x090000, length = 0x008000 /* on-chip Flash */
FLASHG : origin = 0x098000, length = 0x008000 /* on-chip Flash */
FLASHH : origin = 0x0A0000, length = 0x008000 /* on-chip Flash */
FLASHI : origin = 0x0A8000, length = 0x008000 /* on-chip Flash */
FLASHJ : origin = 0x0B0000, length = 0x008000 /* on-chip Flash */
FLASHK : origin = 0x0B8000, length = 0x002000 /* on-chip Flash */
FLASHL : origin = 0x0BA000, length = 0x002000 /* on-chip Flash */
FLASHM : origin = 0x0BC000, length = 0x002000 /* on-chip Flash */
FLASHN : origin = 0x0BE000, length = 0x002000 /* on-chip Flash */
PAGE 1 : /* Data Memory */
/* Memory (RAM/FLASH) blocks can be moved to PAGE0 for program allocation */
BOOT_RSVD : origin = 0x000002, length = 0x000120 /* Part of M0, BOOT rom will use this for stack */
RAMM1 : origin = 0x000400, length = 0x000400 /* on-chip RAM block M1 */
RAMD1 : origin = 0x00B800, length = 0x000800
RAMLS5 : origin = 0x00A800, length = 0x000800
RAMGS0 : origin = 0x00C000, length = 0x001000
RAMGS1 : origin = 0x00D000, length = 0x001000
RAMGS2 : origin = 0x00E000, length = 0x001000
RAMGS3 : origin = 0x00F000, length = 0x001000
RAMGS4 : origin = 0x010000, length = 0x001000
RAMGS5 : origin = 0x011000, length = 0x001000
RAMGS6 : origin = 0x012000, length = 0x001000
RAMGS7 : origin = 0x013000, length = 0x001000
RAMGS8 : origin = 0x014000, length = 0x001000
RAMGS9 : origin = 0x015000, length = 0x001000
RAMGS10 : origin = 0x016000, length = 0x001000
RAMGS11 : origin = 0x017000, length = 0x001000
RAMGS12 : origin = 0x018000, length = 0x001000 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
RAMGS13 : origin = 0x019000, length = 0x001000 /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
CPU2TOCPU1RAM : origin = 0x03F800, length = 0x000400
CPU1TOCPU2RAM : origin = 0x03FC00, length = 0x000400
}
SECTIONS
{
/* Allocate program areas: */
.cinit : > PROGRAM_SECTOR, PAGE = 0, ALIGN(4)
.pinit : > PROGRAM_SECTOR, PAGE = 0, ALIGN(4)
.text : > PROGRAM_SECTOR, PAGE = 0, ALIGN(4)
codestart : > BEGIN, PAGE = 0, ALIGN(4)
/* Allocate uninitalized data sections: */
.stack : > RAMM1 PAGE = 1
.ebss : >> RAMLS5 | RAMGS0 | RAMGS1 PAGE = 1
.esysmem : > RAMLS5 PAGE = 1
.cio : > RAMLS5 PAGE = 1
/* Initalized sections go in Flash */
.econst : > PROGRAM_SECTOR PAGE = 0, ALIGN(4)
.switch : > PROGRAM_SECTOR PAGE = 0, ALIGN(4)
.reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */
Filter_RegsFile : > RAMGS0, PAGE = 1
/* Flash Programming Buffer */
BufferDataSection : > RAMD1, PAGE = 1, ALIGN(4)
SHARERAMGS0 : > RAMGS0, PAGE = 1
SHARERAMGS1 : > RAMGS1, PAGE = 1
ramgs0 : > RAMGS0, PAGE = 1
ramgs1 : > RAMGS1, PAGE = 1
#ifdef __TI_COMPILER_VERSION__
#if __TI_COMPILER_VERSION__ >= 15009000
GROUP
{
.TI.ramfunc
{ -l F021_API_F2837xD_FPU32.lib}
} LOAD = PROGRAM_SECTOR,
RUN = RAMLS03,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
RUN_SIZE(_RamfuncsRunSize),
RUN_END(_RamfuncsRunEnd),
PAGE = 0, ALIGN(4)
#else
GROUP
{
ramfuncs
{ -l F021_API_F2837xD_FPU32.lib}
} LOAD = PROGRAM_SECTOR,
RUN = RAMLS03,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
RUN_SIZE(_RamfuncsRunSize),
RUN_END(_RamfuncsRunEnd),
PAGE = 0, ALIGN(4)
#endif
#endif
/* The following section definitions are required when using the IPC API Drivers */
GROUP : > CPU1TOCPU2RAM, PAGE = 1
{
PUTBUFFER
PUTWRITEIDX
GETREADIDX
}
GROUP : > CPU2TOCPU1RAM, PAGE = 1
{
GETBUFFER : TYPE = DSECT
GETWRITEIDX : TYPE = DSECT
PUTREADIDX : TYPE = DSECT
}
/* The following section definition are for SDFM examples */
Filter1_RegsFile : > RAMGS1, PAGE = 1, fill=0x1111
Filter2_RegsFile : > RAMGS2, PAGE = 1, fill=0x2222
Filter3_RegsFile : > RAMGS3, PAGE = 1, fill=0x3333
Filter4_RegsFile : > RAMGS4, PAGE = 1, fill=0x4444
Difference_RegsFile : >RAMGS5, PAGE = 1, fill=0x3333
}
需要将bootloader执行的codestart设置在0x80000zhong ;
需要将程序全部限制在flash sectorA以及flash sectorB(0x80000~0x83fff)中;
2、用户应用工程(待升级的工程)
MEMORY
{
PAGE 0 : /* Program Memory */
/* BEGIN is used for the "boot to FLASH" bootloader mode */
D01SARAM : origin = 0x00B000, length = 0x001000
/* Flash boot address */
/*BEGIN : origin = 0x080000, length = 0x000002*/
BEGIN : origin = 0x084000, length = 0x000010
/* Flash sectors */
FLASHA : origin = 0x080000, length = 0x002000 /* on-chip Flash */
FLASHB : origin = 0x082000, length = 0x002000 /* on-chip Flash */
FLASHC : origin = 0x084010, length = 0x001FF0 /* on-chip Flash */
FLASHD : origin = 0x086000, length = 0x002000 /* on-chip Flash */
FLASHE : origin = 0x088000, length = 0x008000 /* on-chip Flash */
FLASHF : origin = 0x090000, length = 0x008000 /* on-chip Flash */
FLASHG : origin = 0x098000, length = 0x008000 /* on-chip Flash */
FLASHH : origin = 0x0A0000, length = 0x008000 /* on-chip Flash */
FLASHI : origin = 0x0A8000, length = 0x008000 /* on-chip Flash */
FLASHJ : origin = 0x0B0000, length = 0x008000 /* on-chip Flash */
FLASHK : origin = 0x0B8000, length = 0x002000 /* on-chip Flash */
FLASHL : origin = 0x0BA000, length = 0x002000 /* on-chip Flash */
FLASHM : origin = 0x0BC000, length = 0x002000 /* on-chip Flash */
FLASHN : origin = 0x0BE000, length = 0x002000 /* on-chip Flash */
RESET : origin = 0x3FFFC0, length = 0x000002
PAGE 1 : /* Data Memory */
BOOT_RSVD : origin = 0x000002, length = 0x000120 /* Part of M0, BOOT rom
will use this for
stack */
M01SARAM : origin = 0x000122, length = 0x0006DE /* on-chip RAM */
LS05SARAM : origin = 0x008000, length = 0x003000 /* on-chip RAM */
/* on-chip Global shared RAMs */
RAMGS0 : origin = 0x00C000, length = 0x001000
RAMGS1 : origin = 0x00D000, length = 0x001000
RAMGS2 : origin = 0x00E000, length = 0x001000
RAMGS3 : origin = 0x00F000, length = 0x001000
RAMGS4 : origin = 0x010000, length = 0x001000
RAMGS5 : origin = 0x011000, length = 0x001000
RAMGS6 : origin = 0x012000, length = 0x001000
RAMGS7 : origin = 0x013000, length = 0x001000
RAMGS8 : origin = 0x014000, length = 0x001000
RAMGS9 : origin = 0x015000, length = 0x001000
RAMGS10 : origin = 0x016000, length = 0x001000
RAMGS11 : origin = 0x017000, length = 0x001000
RAMGS12 : origin = 0x018000, length = 0x001000
RAMGS13 : origin = 0x019000, length = 0x001000
RAMGS14 : origin = 0x01A000, length = 0x001000
RAMGS15 : origin = 0x01B000, length = 0x001000
/* Shared MessageRam */
CPU2TOCPU1RAM : origin = 0x03F800, length = 0x000400
CPU1TOCPU2RAM : origin = 0x03FC00, length = 0x000400
}
SECTIONS
{
/* Allocate program areas: */
.cinit : > FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
.binit : > FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
#ifdef __TI_EABI__
.init_array : > FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
#else
.pinit : > FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
#endif
.text : >> FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
codestart : > BEGIN PAGE = 0 ALIGN(4)
ramfuncs : LOAD = FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
RUN = LS05SARAM PAGE = 1
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
RUN_SIZE(_RamfuncsRunSize),
RUN_END(_RamfuncsRunEnd)
#ifdef __TI_COMPILER_VERSION__
#if __TI_COMPILER_VERSION__ >= 15009000
.TI.ramfunc : {} LOAD = FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
RUN = LS05SARAM PAGE = 1,
table(BINIT)
#endif
#endif
/* Allocate uninitalized data sections: */
.stack : > M01SARAM | LS05SARAM PAGE = 1
#ifdef __TI_EABI__
.bss : > M01SARAM | LS05SARAM PAGE = 1
.sysmem : > LS05SARAM | M01SARAM PAGE = 1
.data : > M01SARAM | LS05SARAM PAGE = 1
#else
.ebss : > M01SARAM | LS05SARAM PAGE = 1
.esysmem : > LS05SARAM | M01SARAM PAGE = 1
#endif
.cio : > LS05SARAM | M01SARAM PAGE = 1
/* Initalized sections go in Flash */
#ifdef __TI_EABI__
.const : > FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
#else
.econst : > FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
#endif
.switch : > FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
.args : > FLASHC | FLASHD | FLASHE |
FLASHF | FLASHG | FLASHH | FLASHI | FLASHJ |
FLASHK | FLASHL | FLASHM | FLASHN PAGE = 0, ALIGN(4)
Filter_RegsFile : > RAMGS0 | RAMGS1 | RAMGS2 | RAMGS3 | RAMGS4 |
RAMGS5 | RAMGS6 | RAMGS7 | RAMGS8 | RAMGS9 |
RAMGS10 | RAMGS11 | RAMGS12 | RAMGS13 | RAMGS14 |
RAMGS15 PAGE = 1
/* The following section definitions are required when using the IPC API Drivers */
GROUP : > CPU1TOCPU2RAM, PAGE = 1
{
PUTBUFFER
PUTWRITEIDX
GETREADIDX
}
GROUP : > CPU2TOCPU1RAM, PAGE = 1
{
GETBUFFER : TYPE = DSECT
GETWRITEIDX : TYPE = DSECT
PUTREADIDX : TYPE = DSECT
}
}
对于应用工程的cmd文件,需要将该工程的codestart 设置在0x84000(用户自行定义)处;
需要将整个工程代码连接在flash的sectorC及之后(用户自行定义);
3、bootloader跳转至主应用程序
bootloader假设不需要升级直接跳转或者升级完成需要跳转时,在需要跳转处添加汇编代码
asm(" LB 0x84000");即可(具体跳转地址,用户自行定义)