您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > dsp28335-的bootloder过程
一、28335的启动介绍TI支持很多种方式的boot,内部的ram(saram),flash,sci,但无论哪种启动都遵循下面的流程:而该流程中的reset,initboot,callselectbootmode,readi/ostate,callbootloader这些步骤都是固化在芯片内的程序自己执行的,也就是说这些代码在出厂的时候已经在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中运行)学习一款处理器芯片,搞明白芯片的运行过程,特别是程序的启动阶段,对于更好的应用芯片很有帮助。对F28335来讲,它提供的方式很多。首先F28335中有片内flash,可以将程序存储在这里;其次,F28335也提供了bootloader功能;最后,F28335还具有片上OTP,用户可以在这里设定自己的启动方式。在28335的TI提供的例程中,程序的起始位置是code_start,在这里先禁止看门狗,然后再跳转到c_int00处运行;而在一般的C工程中,这个起始位置一般是c_int00;这个起始位置在编译选项(buildoptions)中设定,在C环境建立之前将看门狗禁止,使得程序更可靠。查阅到“DSP2833x_CodeStartBranch.asm”中的说明,如下:Fortheseexamples,code_startisthefirstcodethatisexecutedafterexitingthebootROMcode.Thecodestartsectioninthelinkercmdfileisusedtophysicallyplacethiscodeatthecorrectmemorylocation.ThissectionshouldbeplacedatthelocationtheBOOTROMwillre-directthecodeto.Forexample,forboottoFLASHthiscodewillbelocatedat0x3f7ff6.Inaddition,theexampleDSP2833xprojectsaresetupsuchthatthecodegenentrypointisalsosettothecode_startlabel.Thisisdonebylinkeroption-eintheprojectbuildoptions.Whenthedebuggerloadsthecode,itwillautomaticallysetthePCtotheentrypointaddressindicatedbythe-elinkeroption.InthiscasethedebuggerissimplyassigningthePC,itisnotthesameasafullresetofthedevice.从上面的说明,可以看到,在仿真模式下忽略了启动模式的选择,而是让仿真器直接将程序的起始地址赋给PC的。特别对这个程序来讲,由于在C环境之前,还禁止了看门狗,程序的起始地址是code_start。但是这里有一点还应注意,在仿真模式下,模拟的是将程序引导到M0SARAM中,所以在CMD文件中,将code_start硬件定位到了M0SARAM的起始位置处,如果固化程序的话,需要更改code_start的位置,将其放在对应方式的位置处。二、我们最常用到的主要有两种引导模式:一种是boottoRAM,即跳到0x000000的RAM中,去开始执行指令,主要针对程序加载在RAM的仿真模式;另外一种是boottoFlash,则跳到0x3F7FF6中去开始执行代码。相应的,程序会在这两个入口地址0x000000,0x3F7FF6放一条跳转指令,在codestart.asm源文件中,原因是在Flash的入口地址处只有两个单元的空间,后面是CSM模块,所以需要跳转;而在RAM中之所以也需要跳转,主要是因为在跳转到main之前,需要执行一小段代码_c_int00,该代码会使用0x000003之后的一段RAM,如果代码放在那里,在执行_c_int00之后会损坏代码。下载到RAM中的时候CMD文件有上面的两句,codestart是在文件“DSP2833x_CodeStartBranch.asm”中有定义,实际上codestart段只是包含了一个跳转指令,是程序跳转到_c_int00处,_c_int00在boot.asminRTSlibrary中有定义,_c_int00的代码最终会调用c的main函数,之后就是main函数的执行。下载到flash中的时候CMD文件有上面的两句。(而复位的时候指向的是0x3fffc0)另外就是一些外设引导模式,如SCI引导以及SPI引导等,像我们常使用的C2PROG软件就支持SCI引导,然后通过串口下载程序。三、c_int00介绍_c_int00isbranchtostartofboot.asminRTSlibray//翻译为中文就是:_c_int00是rts2800_ml.lib的入口地址;·_c_int00是C初始化代码的入口地址·在你用C编程的时候,DSP需要执行一段C运行支持库代码以完成C运行环境的初始化,_c_int00就是这段初始化代码的入口地址,·_c_int00函数在运行支持库(rts,runtime-supportlibrary)中。连接器会将这个函数的入口地址放置在复位中断向量处,使其可以在初始化时被调用。c_int0函数进行以下工作以建立C运行环境:为系统堆栈产生.stack块,并初始化堆栈指针。从.cinit块将初始化数据拷贝到.bss块中相应的变量。·执行完初始化代码后,就跳转到main函数,开始运行C程序;·rts2800.lib:C/C++运行支持库;·rts2800_ml.libC/C++大内存模式运行支持库.·rts2800_ml.lib中有大量浮点运算处理的函数而rts2800.lib没有·在指针的访问空间上有区别,rts2800.lib中库函数的指针为near,故不能访问3Fxxxx,rts2800_ml.lib可以访问(大小内存模式故名思议就是可以访问的内存的大小有区别,小内存模式只能访问低64k地址,也就是16位地址线)四、2812的启动步骤(可参照理解28335)下面是2812的flash启动流程,可参照学习28335的启动2812从内部flash启动的详细流程说明:(a)上电复位(b)判断是否从flash启动(c)复位向量是指向片内Flash的0x3FFFC0,2812有一块flash地址从0x3FF000-0x3FFFFF在出厂时已经固化好了引导程序。在0x3FFFC0处是一条跳转指令,跳到iniboot(地址0x3FFC00)函数处执行iniboot代码,该iniboot代码就是TI在dsp出厂时固化在flash中的(d)InitBootassemblyRoutine将选择SelectBootModefunction启动模式函数。这个函数由GPIO引脚的状态决定启动类型。一旦启动结束,选择启动模式函数返回一入口地址给InitBoot函数。入口地址是退出bootloader之后代码开始执行的起始点。InitBoot接着将会调用ExitBoot子程序,把CPU寄存器的状态恢复到复位状态。比如flashboot模式。(e)那么initboot执行完后跳转到0x3F7FF6处(codestart处),此位置刚好在128位(CSM)密码位置之前。(f)你要在0x3F7FF6处放置跳转指令,以跳转到你要去的地方,比如是bootloader或应用代码,通常的跳转去处是_c_int00。(g)上面代码执行后跳到C初始化的入口_c_int00(0x3F6000),在C初始化的入口,_c_int00对一些变量,堆栈和寄存器进行必要的设置。(h)调用main函数
本文标题:dsp28335-的bootloder过程
链接地址:https://www.777doc.com/doc-1863076 .html