DM642启动过程分析供所有C6000系列DSP开发者参考。【TI关于C6000bootloader文档】DM642复位后,芯片先从CE1空间读取1K字节的数据到内部SRAM,然后从地址0开始运行。因为一般的程序都远远大于1K字节,所以一般都是有一个二级bootloader,用它来加载主程序。Bootloader运行完后调用c_int00()来进行C运行时刻初始化,如堆栈,静态变量等,之后会调用BIOS_init,最后开始运行main函数,main函数结束后DSP/BIOS的任务管理器开始运行。具体实现起来时要稍复杂一些,因为有一些实际问题需要考虑。1.外部存储器一般是NORFlash,容量较大时,因为DM642的CE1只有1MB空间,需要使用GPIO配合的分页模式。因为GPIO的缺省值是输入,内有上拉电阻,所以bootloader需要写在最高页。DM642复位后采用最慢的读写时序。2.Bootloader需要在有限的1K字节内完成SDRAM初始化,并将主程序搬运到内存中然后开始运行。TI的例子是用汇编写的,因为此时c的运行环境还没有初始化。其中最关键的是栈指针没有初始化,我们给它赋值后其他部分就可以用c来写,但要注意仍不能使用c库函数。汇编部分进行栈指针初始化:_boot_sp:mvk.S20x0600,B15mvkl.S2_boot_loader,B0mvkh.S2_boot_loader,B0b.S2B0nop5boot.c进行EMIF初始化,并分段将主程序从Flash读入SDRAM#pragmaCODE_SECTION(boot_loader,.boot_load);voidboot_loader(){Uint32program_addr,size;Uint8*src,*dest;program_addr=0x90000404;//FirstEntry//InittheEMIFinterfaceEMIFA_GCTL=0x00052060;EMIFA_CE0=0x00000040;EMIFA_CE1=0x21E28E01;//0x11518a01EMIFA_CE2=0xffffffd3;EMIFA_CE3=0xffffffd3;EMIFA_SDRAMCTL=0x6b228000;EMIFA_SDRAMTIM=0x000003A9;EMIFA_SDRAMEXT=0x000505cd;EMIFA_CE0SECCTL=0x00000071;EMIFA_CE1SECCTL=0x00000002;EMIFA_CE2SECCTL=0x00000002;EMIFA_CE3SECCTL=0x00000002;//LoadSecondBootloadertoSDRAMsize=*(Uint32*)program_addr;while(size){program_addr+=4;dest=(Uint8*)(*(Uint32*)program_addr);program_addr+=4;src=(Uint8*)program_addr;program_addr+=size;if(size%4)program_addr+=4-(size%4);while(size--){*dest++=*src++;}size=*(Uint32*)program_addr;}c_int00();//RuntheSecondBootloader3.经常遇到的问题是bootloader调试时运行正常,写到flash就启动不了。这里的区别在于调试时CCS负责将程序装载到内存中,然后程序直接从c_int00()开始运行,而烧到flash就得一切靠自己了。调试这个问题的办法是CCS加载程序后,先查看内存0地址处,是否是bootloader的代码,如果不对就是linker的cmd文件或DSP/BIOS内存设置有问题,需要将bootloader放在片内SRAM中。然后让程序从0地址开始运行,看主程序是否正确地加载到内存中。.boot_load{boot_sp.objboot.obj}BOOT_RAMBOOT_RAM是起始地址为0,长度1K的内部SRAM空间。4.bootloader调试完毕后就是烧写到flash。先用TI的Hex6x将输出转换成hex文件,然后用flashburn或自己的代码烧写。Flash的头1K字节是bootloader,然后是主程序的代码段。代码的格式可以参见boot.cDSPBootLoader初学DSP时最头疼的事就是DSP的bootload问题,以前学51时只要把程序写好编译通过后就可以用烧写器直接将*.hex文件烧进单片机运行。但DSP内部不带FLASHRAM,它必须在复位期间将外部的程序加载到内部RAM之后才能运行。这有点像PC的体系结构,PC机中的引导加载程序由BIOS(其本质就是一段固件程序)和位于硬盘MBR中的OSBootLoader(比如,LILO和GRUB等)一起组成。BIOS在完成硬件检测和资源分配后,将硬盘MBR中的BootLoader读到系统的RAM中,然后将控制权交给OSBootLoader。BootLoader的主要运行任务就是将内核映象从硬盘上读到RAM中,然后跳转到内核的入口点去运行,也即开始启动操作系统。我刚开始时就被这bootload搞的心焦如焚,仿真好的程序却不能脱机运行,最好还是老老实实看TI的DSPdatasheet,经过一番周折总算搞定!为此我想把我的调试心得写出来与大家共享,一方面是避免初学者走弯路,另一方面是借此抛砖引玉望方家多斧正^_^。简单地说,bootloader就是在用户程序运行之前的一段小程序,通过这段小程序初始化硬件设备、建立内存空间的映射图,最终调用用户程序。这段小程序其实已固化在DSP芯片TMS320VC33内部ROM中,在TMS320C3Xdatasheet中有源码及功能流程图,我们只需知道它的功能流程即可。从流程图我们可以知道在DSP上电复位时只要DSP芯片引脚'MCBL/MP'为高电平,TMS320VC33就开始自动执行固化在内部ROM中的bootloader程序,然后根据外部中断引脚'INT3~INT0'判断用户程序的加载起始地址。管脚电平存储空间INT000x001000INT100x400000INT200xfff000INT30串口在我的系统应用中,我将程序存储在外部FLASH芯片39VF040中,它在系统中的起始地址为:0X400000,所以只要DSP复位时外部中断引脚'INT1'为低电平,bootloader程序就开始读取外部FLASH芯片39VF040中的用户程序并加载到DSP内部RAM中,加载完毕后就自动跳到用户程序的入口地址开始运行用户程序。从bootloader的流程图还可以知道,bootloadr加载用户程序时是有一定格式要求的,即存储在用户外部FLASH程序空间的数据结构的格式要求如下:WORD0:用户外部FLASH芯片数据宽度,如8,16,32位等WORD1:控制字,用来写入TMS320VC33的总线控制寄存器WORD2:数据块大小WORD3:当前上载数据块将要装载到DSP内部RAM中的目标地址WORD4~N:用户程序内容用户的程序分为多个数据块(因为DSP开发软件生成的目标文件是COFF格式),每块数据块起始都包含一个程序头,每个又包含两个内容:1、当前数据块大小,即32位格式的数据量。2、当前数据块在DSP内部RAM存储的起始地址。程序头之后就是用户的程序内容。讲到这里问题的关键就出来了:怎样产生这样的程序块呢?程序内容应该为哪种格式*.hex、*.bin、*.out?这也是我当初最头疼的问题。用TI公司的DSP开发软件CodeComposer建立一个项目文件后,要做的第一件事就是编写*.cmd命令文件,命令文件有两个:一个是链接命令文件,另一个是boot引导表格式生成命令文件。链接命令文件作用是分配各个程序段在DSP内部RAM中的存储位置,链接命令文件必须和项目文件名相同。例如项目online.mak的链接命令文件online.cmd如下所示:-c//ROM初始化-oonline.out//产生online.out可执行文件-monline.map//产生online.map映象文件online.obj//链接的目标文件-lrts30.lib//链入TMS320C3X运行支持库MEMORY{VECS:org=0x809fc1len=0x3f//定义矢量的起始地址及空间的长度RAM0:org=0x809800len=0x7c1//定义堆栈起始地址及空间的长度RAM2:org=0x800000len=0x8000//定义用户程序数据空间}SECTIONS{vectors:load=VECS//将中断向量块安排在VECS空间.text:load=RAM2//将程序代码、常量、变量等数据块安排在RAM2空间.cinit:load=RAM2.const:load=RAM2.bss:load=RAM2.stack:load=RAM0//将堆栈块安排在RAM0空间}建立链接命令文件后,开发软件在对用户程序汇编链接生成目标文件的过程中,就会按照链接命令文件对输出的COFF格式的数据块自动选择存储器地址。boot引导表格式生成命令文件,这个文件名可以随意取,例如可取名为hex.cmd。先头讲到TMS320VC33的bootloader程序加载用户程序是有一定格式,boot引导表格式生成命令文件就是将用户的目标文件转换成符合要求的格式,举例如下:hex.cmdonline.out//要进行转换的目标文件-maphex.map//生成映象文件-boot//产生装载程序-image//输出文件去掉地址映象-i//建立INTEL十六进制文件的输出-memwidth8//用户程序存储器的数据宽度-cg10e8h//总线控制字-e00803f86h//程序装载完成后的执行地址即为_c_int00的地址,可查看online.map文件*/ROMS//ROM的映射范围,及用户程序在外部FLASH中的地址空间{FLASH1:org=0,len=10000h,romwidth=8,files={online1.hex}FLASH2:org=10000h,len=10000h,romwidth=8,files={online2.hex}}写好格式转换命令文件后,在WINDOWS的命令提示符工具下用'cd'命令进入用户程序目标文件所在目录,然后运行hex30hex.cmd即可根据格式命令文件hex.cmd的要求产生两个hex格式的文件online1.hex和online2.hex。其中hex30是DSP开发软件自带的程序。因为Intel格式中除了数据之外还有起始符、字节个数、起始地址、类型以及校验位等各种信息,并非纯粹数据的HEX格式表示。所以还不能直接烧进FLASH芯片,同样在命令提示符下运行hexbin程序,将online1.hex和online2.hex分别转换成online1.bin和online2.bin,就可得到纯粹数据格式的烧写文件,好了,只要把刚才两个文件烧进FLASH芯片,重启系统,OK!终于可以脱机运行程序了!(可参阅TMS320C6000系列二次Bootloader的设计与实现)