经过一段时间的研究终于把TMS320C6657单核和双核的SPI Nor Flash的程序烧写调通了。工具都是前辈的工作,有需要的可以留下邮箱,我有空可以发。
原理参考钱丰的《TI c66x 系列DSP 多核BOOT 的研究》论文。
通过Nor flash 烧写加载程序的全部流程:(在no-boot模式下)
一、首先讲讲工具链:
hex6x 配合.rmd文件(有几个.out文件就需要几个.rmd文件,描述输出控制、引导选项、存储器选项等内容)生成片上引导加载器加载程序所需的引导表,输出文件为*.btbl
mergebtbl将*.btbl按照一定的顺序链接起来
b2i2c 将*.btbl转换成i2c/spi格式,把boot表划分成0x80字节块并附加长度(length)和校验码(checksum)
b2ccs将*.btbl.i2c转换成.i2c.ccs,CCSV5 IDE接收的.dat格式,加载到DDR3中去。并手动将i2crom.ccs中的第9行51改为00。
romparse 合并boot表和boot参数表,参数配置表文件*.map作为输入。
byteswapccs将.dat转换成ROM Bootloader代码能够识别的大端模式
二、将工具链写成批处理文件
1.单核.dat文件生成
hex6x simple.rmd
b2i2c simple.btbl simple.btbl.i2c
b2ccs simple.btbl.i2c simple.i2c.ccs
romparse nysh.spi.map
pause //暂停时,将i2crom.ccs中的第9行51改为00
byteswapccs i2crom.ccs spirom_le.dat
2.双核.dat文件生成
hex6x core0.rmd
hex6x core1.rmd
mergebtbl core0.btblcore1.btbl multi_core.btbl
b2i2c multi_core.btbl simple.btbl.i2c
b2ccs simple.btbl.i2c simple.i2c.ccs
romparse nysh.spi.map
pause //暂停时,将i2crom.ccs中的第9行51改为00
byteswapccs i2crom.ccs spirom_le.dat
蓝色与单核.dat文件生成不同,其他相同。
三、*.dat烧写过程
1. 2个led测试工程,成功编译并生成2个.out文件,生成.out 文件必须命名为core0.out 、core1.out
2. 将2个.out文件拷贝到SPI_Bootloader工具链路径下,双击spibootMulticore.bat批处理文件,开始生成文件,得到spirom_le.dat
3. 将evm板调成no-boot 模式,拨码开关对应 SW3~SW5 1000 0000 0000 0000 (0 对应on 1对应off)
4. 打开MCSDK自带的nor-writer工程,将工程bin文件夹下的nor_writer_input.txt 打开,修改输入文件名为spirom_le.dat 并将spirom_le.dat拷贝到mcsdk_xxxx\tools\writer\nor\evmc667xl\bin路径下
5. 链接工程,等PC指针停在main函数入口,打开view--memory browser,输入0x80000000,load memory 选择spirom_le.dat,(自动)勾上Use the header... 再次确认start address 为0x80000000,length为spirom_le.dat的长度(单位是word) 开始往DDR里灌数。
6. 烧写工程run,注意console输出 显示与length长度大小相同的文件烧入flash,则烧写成功,此时单位是字节。
7. 最后拨码开关拨到ROM SPI boot模式下,SW3~SW5 1011 0000 0010 0000,断电重启
四、多核启动过程
C66x DSP 内部有一个固化的ROM,里面存放着boot 代码(ROM bootloader)。每当DSP 启动时,会自动从这里读取代码并执行。这里执行的代码是固化的不可更改的,其作用就是根据DSP的管脚配置方式对核进行初始化(比如PLL 等)和完成不同模式的Boot 处理。所有的core 执行同一份代码。不同的core 在执行的时候通过DNUM(核编号索引)来去做区分。初始化外设的操作由 core0来完成。所以core0初始化其他外设的同时,其他core都会执行相关的代码映射IPC 中断,并配置相应的寄存器,然后进入IDLE 状态,等待core0 的IPC中断发起。简言之,其他核是在core0 的命令下执行第一句代码。
Boot Magic 地址是每个core 各自一块固定的内存。该字存放的是各个core 初始化之后需要跳转到的c程序入口地址 _c_int00()。TMS320C6657/TMS320C6670的Boot Magic地址是0x1x8FFFFC,因为他们L2 RAM大小为1MB。TMS320C6678的Boot Magic地址是0x1x87FFFC,因为L2 RAM只有512KB。
如果多核DSP 是由同一套工程分别编译,那么每个核内存分配完全相同。core0 在读取自己核的Boot Magic 地址(0x108ffffc)后,加上0x0*000000 后就可以得到其他核的Boot Magic 地址(*为核号)。但是如果各核编译各自独立工程,各变量内存映射关系不再相同,那么就无法从core0 的Boot Magic 地址里的值去推算其他核相应地址。这个时候只能事先记录下各核的 Magic地址,然后写死在核 0 的用户初始化代码上。
在完成所有上述操作后,core0 需要对每个核的IPCGRx 寄存器写中断以唤醒其他核的正常运行状态。IPCGRx 寄存器的31-4 比特位是IPC 中断源索引,最多可支持多达28 个中断源,文中例程可以设置为全0;比特3-1 是保留位,可以任意赋值。因此只要对最低比特赋1 就可以完成IPC 中断的触发。