一、28335的启动介绍
TI支持很多种方式的boot,内部的ram(saram),flash,sci,但无论哪种启动都遵循下面的流程:
而该流程中的reset,initboot,callselectbootmode, read i/o state, call boot loader这些步骤都是固化在芯片内的程序自己执行的,也就是说这些代码在出厂的时候已经在TI的芯片内。(我们写的程序是从codestart出开始的,其代码在DSP2833x_CodeStartBranch.asm内,其指定位置在CMD文件内定义。下载到flash中时是在0x3f7ff6处,因为复位
的时候指向的0x3fffc0,先执行固化的bootloader再跳转到0x3f7ff6。下载到RAM中时是在0处。因为不需执行bootloader。) 在28335中是一段的8k*16的read-only的memory,地址位于0x3fe000-0x3fffff,见下图:
根据上面的流程图,详细的解释一下流程:
1.在3fffc0到3fffff其实是放了中断向量表的地方:系统一开机当然是处于reset中断,因此直接跳至reset的地方执行(0x3fffc0)。而这个地方的两个字节只是放了一条指令,就是跳至initboot函数,也就是3ff34c的地址执行bootloader。
.reset 与reset是不同的,一个在memory,一个在sections中。 .reset只包含一个32位的中断矢量,指向实时支持库rts2800_ml.lib中的C编译器导引函数,即_c_int00子程序。通常我们不用此块,而是另外创建分支指令指向开始代码。如4中介绍。
2.在3ff34c的bootloader的程序,这里主要有initboot, 和
SelectBootMode, 以及一些外设引导的函数。SeleteBootMode根据芯片的硬件或软件设置来判断芯片该去哪里寻找程序入口,直接目的是如何找到main,然后执行应用程序。bootloader操作中会去检测外部GPIO口的状态,从而判断是哪种方式的启动:
3.然后根据相应的启动方式跳至相应的入口地址:比如FLASH启动就是0x33fff6, 内部SARAM启动就是0x0。
4.而这里的入口地址就是cmd文件中定义的begin段。因此对于flash启动和ram启动,begin的定义是不同的,在flash启动时begin就是0x33fff6,而ram启动begin就是0x0.这个2个字的区间也就是放了我
们程序最初执行的第一条指令(通常是code_start).一条长跳转指令LB刚好占两个字节。
bootloader执行完毕之后会跳到0x3f7ff6处,而codestart被放置到了BEGIN处。故即是执行DSP2833x_CodeStartBranch.asm代码。
codestart包含一条长跳转指令,指向实时支持库rts2800_ml.lib中的C编译器导引函数,即_c_int00子程序。不同的是:如果系统的程序(.text)放在系统内部RAM中仿真运行,则本块应放入片内RAM中,如地址单元0x3F8000;如果是固化程序进FLASH,则.codestart应定位与FLASH中的其实地址为0x3F7FF6中。(一条长跳转指令占2个字)。
ramfuncs作用
是程序的搬移。
load=allocation(强制地址或存储空间名称)同>allocation:定义输出段将会被装载到哪里。
run= allocation(强制地址或存储空间名称)同>allocation:定义输出段将会在哪里运行。
另:CMD文件中只出现一个关键字load或run时,表示两者的地址时表示两者的地址时重合的。
LOAD_START(_RamfuncsLoadStart)令编译器创建了一个变量RamfuncsLoadStart,该变量指向段ramfuncs的装载地址的首地址(LOAD_ START为编译伪指令,请见CCS的帮助文档); LOAD_START(_RamfuncsLoadEnd)令编译器创建了一个变量RamfuncsLoadEnd,该变量指向段ramfuncs的装载地址的末地址(LOAD_ END为编译伪指令,请见CCS的帮助文档); RUN_START(_RamfuncsRunStart)令编译器创建了一个变量RamfuncsRunStart,该变量指向段ramfuncs的运行地址的首地址(LOAD_ START为编译伪指令,请见CCS的帮助文档);
或
通过这个方式可以把一些程序放入指定的位置。(放置的位置与执行时的位置不同时,如下载到flash中,但是运行时要在RAM中运行)