上次在《DDR引发的问题(上)》中说到,想把一段大的初始化数组放到DDR中,结果链接不通过,最后通过修改链接选项解决了问题。但是把程序用仿真器下载进芯片内执行时,却发现DDR中的数据并未初始化成想要的数据。

DDR使用控制器来完成底层时序和刷新操作,需要事先对DDR控制器进行适当的配置。一般都在最开始的初始化代码中配置完PLL和DDR,之后就可以在其地址空间范围内当作普通RAM直接寻址实现读写操作。然而用仿真器调试时,程序先加载后执行,加载时DDR未初始化,当然没有数据。因此需要把DDR初始化过程放到加载过程之前。

可以使用GEL文件来实现这个功能,加载代码前先加载GEL文件,在其中执行PLL和DDR的初始化,然后再加载的代码就不会再有问题了。这时需要注意在代码中不能再进行PLL和DDR的初始化操作,因为初始化过程中时钟不稳定,可能会丢失其中原有的数据。

当不使用仿真器调试时怎么办呢?XX板使用的是HPI启动,由主机DM8168通过HPI接口加载程序。此时同样需要在加载前先对PLL和DDR完成初始化。

详细分析一下启动过程。复位后DSP首先运行的是内置ROM中的Bootloader(起始地址0010 0000h),完成一些基本的初始化,然后通过启动引脚来进入不同的启动模式分支,C6455的启动模式有不启动(仿真器启动)、SRIO启动、HPI启动、EMIF启动、主从I2C启动等。

在I2C启动模式下,可以使用一个启动参数表或启动配置表来预先配置PLL和DDR。在《TMS320C645x Bootloader User’s Guide(SPRUEC6B)》中对启动参数表和启动配置表有描述。

在HPI启动模式下,PLL1会被Bootloader初始化为旁路模式,Cache为32KB。然后作为HPI从机接收主机发送来的数据,最后由主机触发一个中断来退出Bootloader,开始从加载代码的入口地址执行。
加载前初始化有两种途径,一是上电后主机先通过HPI接口写C6455的相关寄存器完成PLL和DDR配置。二是采用两次Boot的方式,即先加载一次启动代码,由该启动代码将PLL和DDR做初始化,再加载正常功能的启动代码。

在这两种情况下,DDR都不能两次初始化,否则刷新时序混乱后DDR内的数据会有丢失的风险。因此在正常代码的初始化过程中都不能再进行PLL和DDR的初始化。