DSP

基于C语言烧写C6713的二级bootloader

2019-07-13 19:30发布

一 基本原理     TMS320C6713的启动按照如下步骤:系统上电复位时,EDMA控制器便开始将存储在CE1空间ROM中(本文采用的是Flash)起始的1K字节数据,作为一个单帧的数据块传输到片内RAM的0地址处。传输完成后,CPU退出复位状态跳转到片内RAM的0地址处执行这1K字节的程序。     当目标程序小于1K字节时,可直接将程序放在CE1空间起始的1K字节内,从而实现自启动。然而通常情况下用户的目标程序都大于1K字节,所以要在这1K字节的Flash空间中存放一个二级bootloader程序,来将用户存储在Flash其它位置的目标程序拷贝到支持片内执行的存储器(本文采用的是DSP片内RAM),然后运行该目标程序,从而实现自启动。 二 过程实现     根据上述启动原理,需要完成的工作主要有两项:一是在1K字节的程序内实现把存储在Flash中的目标程序拷贝进片内RAM,并且能够顺利运行该目标程序;二是把目标工程烧写进Flash的合适位置,实现DSP的二级bootloader。    (一)实现程序拷贝及正确跳转     为了将储存在Flash中的目标程序拷贝到RAM中并实现运行,所编写的bootloader程序就必须在1K的空间内实现拷贝任务,并且在拷贝结束后自动跳转到目标程序的入口处开始运行。其中,bootloader程序一般采用汇编语言实现,本文尝试采用C语言来实现。虽然此时C环境还尚未建立起来,但是简单的C程序也可以正确运行,这也是本文进行C尝试的出发点。具体的bootloader程序代码如下: #define CODE_ADDR 0x00000400 #define FLASH_CODE_ADDR 0x90000400 #pragma CODE_SECTION(bootloader,".BOOTLOAD") extern far void c_int00(void); void bootloader (void)  { register int code_i ; /***指定要拷贝的字节数,具体根据目标工程的map文件而定***/ register int code_num =0x30000; /***将代码从Flash读到RAM中***/ for(code_i =0;code_i { *(short*)(CODE_ADDR+2*code_i) = *(short *)(FLASH_CODE_ADDR + 2*code_i); } c_int00(); }     在这段代码中,由于C6000系列DSP在CCS3.3的编译环境下,#pragmaCODE_SECTION语句(详见附件Ⅰ)需要满足条件链接伪指令.clink的链接条件(详见附件Ⅱ)才能实现相应的空间分配。也就是说,条件链接伪指令.clink默认为使能状态,指定的代码段只有在被调用的条件下才能实现编译和链接,进行预期的内存分配;若未调用,则不进行编译和链接,不进行内存分配。这里,采取的措施是在目标工程中加入一个汇编文件caller,来实现调用bootloader程序的要求,而在该段汇编代码中不使用条件链接伪指令.clink,使其能够在未调用的情况下完成编译和链接,从而实现对bootloader程序的调用,具体的代码如下: .sect".CALLER" .ref  _bootloader _call_bootloader: mvkl.S2 _bootloader, B0 mvkh .S2 _bootloader, B0     通过这段汇编代码,即可满足条件链接伪指令.clink的要求,实现指定代码的预期分配。然后,将上述bootloader.c和caller.asm文件添加到目标工程中,并修改CMD文件为如下内容, bootloader程序便可被加载到内存空间的BOOT[0x0000-0x0400]区间。 -c -x -stack 0x8000 -heap 0x8000   MEMORY {     BOOT:   o= 0x00000000   l = 0x00000400     IRAM:   o = 0x00000400   l = 0x0002FA00    SDRAM:  o = 0xA0000000   l =0x0002FA00 } SECTIONS {          .BOOTLOAD    >     BOOT         .CALLER      >    SDRAM .text         >     IRAM             .bss          >    IRAM          .cinit        >    IRAM          .switch       >    IRAM          .const        >    IRAM          .far          >    IRAM          .stack        >    IRAM         .cio          >    IRAM          .sysmem       >    IRAM }    (二)烧写目标工程到Flash     烧写过程需要将.out文件转换为Flash可识别的二进制数据,这里采用将.out文件直接加载到片内RAM中(不运行),使其自动转换为二进制格式,然后通过FlashBurn程序直接将RAM中的.out数据烧写到Flash中。具体的Flash烧写流程如下:                                                        
    上述过程中烧写目标程序到Flash的指定地址要与bootloader程序中的拷贝地址一致,bootloader程序和目标程序在RAM中的地址和大小可查找目标工程的map文件获得。 三 方法总结    (一)该方法省却了汇编语言的麻烦,增强了程序的可读性,原则上适用C6000其它系列DSP,常见如C671x和C641x,只需修改CMD文件和相应的烧写地址便可实现启动。    (二)在bootloader程序中,也可以通过修改目的地址将Flash中的目标程序拷贝到SDRAM或其它支持片内执行的存储器中,在拷贝完成后跳转到该位置来运行目标程序,这样做仅需要在拷贝之前完成相应存储器的初始化即可。    (三)在处理条件链接时,也可以通过反汇编屏蔽.clink来禁用该段代码的条件链接,或者直接禁用全局条件链接功能,均可实现指定的内存分配,具体的操作方法见附件Ⅱ。    (四)加载目标工程前,可以通过修改工程中的CMD文件将目标程序和bootloader程序加载到任意可用的内存空间,但是需要保证把bootloader程序和目标程序分别烧写到Flash最初的1K和指定的地址,同时需要注意拷贝和烧写时的数据长度。