2812从内部flash启动的详细流程说明:
a) 程序硬件复位或者软件复位
b) 判断mp/mc是否为0,为0则从boot rom启动,否则从外部启动(见附录1)
c) 到boot rom的0x3FFFC0处取出复位向量,跳到boot函数
d) 采集IO管脚状态,根据IO状态选择boot方式(见附录2)
e) 如果是flash,程序退出boot函数,跳转到0x3F7FF6
f) 取出跳转指令,跳转到自己的指定地址或者C初始化的入口_C_INT00处
g) 在C初始化的入口_C_INT00对一些变量,堆栈和寄存器进行必要的设置,该函数在c的库函数内
h) 进入main函数
(a)上电复位后,(c)复位向量是指向片内Flash的0x3FFFC0,2812有一块flash地址从0x3FF000-0x3FFFFF在出厂时已经固化好了引导程序。在0x3FFFC0处是一条跳转指令,跳到iniboot(地址0x3F FC00)函数处执行iniboot代码,该iniboot代码就是TI在dsp出厂时固化在flash中的。(d)InitBoot assembly Routine将选择SelectBootMode function启动模式函数。这个函数由GPIO 引脚的状态决定启动类型(见附录2)。一旦启动结束,选择启动模式函数返回一入口地址给InitBoot函数。入口地址是退出bootloader之后代码开始执行的起始点。InitBoot接着将会调用ExitBoot子程序,把CPU寄存器的状态恢复到复位状态。比如flash boot模式,(e)那么initboot执行完后跳转到0x3F7FF6处(codestart处),此位置刚好在128位(CSM)密码位置之前,(f)你要在0x3F7FF6处放置跳转指令(跳转见附录3),以跳转到你要去的地方,比如是boot loader或应用代码,通常的跳转去处是_c_int00。(g)上面代码执行后跳到C初始化的入口_c_int00(0x3F6000) ,在C初始化的入口,_c_int00对一些变量,堆栈和寄存器进行必要的设置(见附录4)。(h)调用main函数开始运行C程序。
附录1:XMP/~MC
当该引脚的为高电平时表示是微处理器模式(microprocessor),为低电平时表示微计算机模式(microcomputer),当为微处理器模式时,2812内部的bootrom被禁止,通过zone7(0x3F C000)从外部调引导程序启动。2812复位以后,其复位向量是固定的0x3FFFC0,如果为微处理器模式,那么复位后的复位向量指向的外部的地址,即0x3FFFC0是zone7处的地址,若为微计算机模式,那么0x3FFFC0指向的是2812的片内FLASH的地址。
附录2:引导模式选择
GPIOF4 |
GPIOF12 |
GPIOF3 |
GPIOF2 |
|
(SCITXDA) |
(MDXA) |
(SPISTEA) |
(SPICLK) |
|
PU |
No PU |
No PU |
No PU |
Mode Selected |
1 |
X |
X |
X |
跳转到地址为0x3F7FF6的Flash,用户必须在这里编写分支语句优先于复位,以按需要重新定位代码的执行. |
0 |
1 |
X |
X |
调用SPI_Boot 以从外部的EEPROM载入 |
0 |
0 |
1 |
1 |
调用SCI_Boot 以从SCI-A载入 |
0 |
0 |
1 |
0 |
J跳转到 H0 SARAM 0x3F 8000 |
0 |
0 |
0 |
1 |
跳转到OTP地址 0x3D 7800 |
0 |
0 |
0 |
0 |
调用Parallel_Boot从GPIO 端口B载入 |
附录3: 在0x3F 7FF6 处放置跳转指令,跳到C初始化的入口_c_int00(0x3F6000)
(DSP281x_CodeStartBranch.asm中):
.sect "codestart"
code_start:
.if WD_DISABLE == 1
LB wd_disable ;Branch to watchdog disable code
.else
LB _c_int00 ;Branch to start of boot.asm in RTS library
.endif
.if WD_DISABLE == 1
.text
wd_disable:
SETC OBJMODE
EALLOW
MOVZ DP, #7029h>>6
MOV @7029h, #0068h
EDIS
LB _c_int00
.endif
.end
CMD文件中对应位置
MEMERY
{
Page 0:
………..
RAML0 : origin = 0x008000, length = 0x001000 /* on-chip RAM block L0 */
OTP : origin = 0x3D7800, length = 0x000400 /* on-chip OTP */
FLASHD : origin = 0x3F0000, length = 0x002000 /* on-chip FLASH */
FLASHC : origin = 0x3F2000, length = 0x002000 /* on-chip FLASH */
FLASHA : origin = 0x3F6000, length = 0x001F80 /* on-chip FLASH */
CSM_RSVD : origin = 0x3F7F80, length = 0x000076
BEGIN : origin = 0x3F7FF6, length = 0x000002
………..
}
SECTIONS
{ ……….
/* Allocate program areas: */
.cinit : > FLASHA PAGE = 0
.pinit : > FLASHA, PAGE = 0
.text : > FLASHC PAGE = 0
codestart : > BEGIN PAGE = 0
ramfuncs : LOAD = FLASHD,
RUN = RAML0,
LOAD_START(_RamfuncsLoadStart),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
PAGE = 0
csmpasswds : > CSM_PWL PAGE = 0
csm_rsvd : > CSM_RSVD PAGE = 0
/* Allocate uninitalized data sections: */
.stack : > RAMM0 PAGE = 1
.ebss : > RAML1 PAGE = 1
.esysmem : > RAML1 PAGE = 1
/* For SDFlash to program these, they must be allocated to page 0 */
.econst : > FLASHA PAGE = 0
.switch : > FLASHA PAGE = 0
……….
}
附录4:_c_int00
这个函数在运行支持库(rts.lib)中,_c_int00函数为建立C运行环境,需完成以下工作:
1.为系统堆栈产生.stack块,并初始化堆栈指针;
2.从.cinit块将初始化数据拷贝到.bss块中相应的变量;
3.对寄存器进行必要的配置,调用main函数开始运行C程序;