TMS320C6657挂载SPI Nor Flash自启动

TMS320C6657挂载SPI Nor Flash自启动

首先声明本文仅适用于TMS320C6657芯片,多核单镜像的SPI启动。TI C66X系列的资料比较零散,不系统,这无疑给像我这样的DSP初学者带来了极大的困难。因工作需要,将原有的EMIF启动的一个DSP程序改成SPI启动模式的程序,由于DSP烧写的不可观性,一直没找到问题所在,只能一步一步的摸索修改。在CSDN以及TI的官方论坛上查阅了大量的资料,站在巨人的肩膀上,好歹成功实现了。感慨DSP烧写的困难,特殊此文,希望能帮到跟我一样的DSP初学者。如有不严谨的地方还望大佬指教。
理论上的东西可以参考《TMS320C66x KeyStone架构多核DSP入门与实例精解》P314基于Nor Flash SPI的多核Boot实例这一节。本文主要是根据我调试过程编写的,比较粗显。

一.源程序修改

原有的程序是基于EMIF启动模式设计的,首先需要去掉一段用汇编语言编写的EMIFboot程序,他的功能是将Flash中的代码搬移到core0的L2SRAM中(flash运行速度低)并跳转到起始地址开始执行。但由于板子的设计问题,需要改成 SPI启动模式,所以把这一段汇编去掉了。

二.单核启动

正常生成.out文件后,通过TI公司提供的工具链转成dat(bin):
在这里插入图片描述

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代码能够识别的大端模式

生成的.bin文件通过flash烧写工具,这个是我自己写的,需要参考flash芯片的数据手册,跟型号有关,如果是开发板的话,开发版光盘里有烧写工具的镜像,这个不难。烧进去之后DSP复位,控制bootmode[15:0]=0001 0010 0000 1101,SPI启动模式,参数设置参考《TMS320C6657》BOOTMODE这一节,各个GPIO引脚设置与初设化外设相关。启动后并没有捕捉到DSP工作的信号,但不清楚问题出在哪。然后接了FLASH芯片的输入输出与时钟信号到示波器上,我们用的FLASH芯片地址位宽为24位,数据位宽为16位。通过时钟可以看到,输入信号前8位为指令,后24位为地址,再查看输出。通过比对bin文件发现,前1k的数据正常输出,但读完1k后,输入读取的地址为0x500400,超出了bin文件的长度所以DSP没有正常的工作。猜测这个地址应该是0x000400,刚好是1K与bin文件能对得上,因此我去查了固化在ROM里RBL源代码,验证了我的猜想。

typedef struct boot_params_spi_s
{
    /* common portion of the Boot parameters */
    UINT16 length;
    UINT16 checksum;
    UINT16 boot_mode;
    UINT16 portNum;
    UINT16 swPllCfg_msw;  /* CPU PLL configuration, MSW */
    UINT16 swPllCfg_lsw;  /* CPU PLL configuration, LSW */

    UINT16 options;

     UINT16 addrWidth;          /* 16 or 24 are the only valid values */
     UINT16 nPins;              /* 4 or 5 pins are the only valid values */
     UINT16 csel;               /* only values 0b10 (cs0 low) or 0b01 (cs1 low) are valid */
     UINT16 mode;               /* Clock phase/polarity. These are the standard SPI modes 0-3 */
     UINT16 c2tdelay;           /* Setup time between chip select assert and the transaction */

     UINT16 cpuFreqMhz;         /* Speed the CPU is running after PLL configuration */
     UINT16 busFreqMhz;         /* The speed of the SPI bus, the megahertz portion */
     UINT16 busFreqKhz;         /* The KHz portion of the bus frequency. A frequency of 1.5 MHz would have the value 5 here */

     UINT16 read_addr_msw;      /* The base address to read from the SPI, upper 16 bits */
     UINT16 read_addr_lsw;      /* The base address to read from the SPI, lower 16 bits */

     UINT16 next_csel;          /* The next chip select to use if in boot config mode, when the config is complete */
     UINT16 next_read_addr_msw; /* The next read address to use if in boot config mode */
     UINT16 next_read_addr_lsw; /* The next read address to use if in boot config mode */

} BOOT_PARAMS_SPI_T;  

在这里插入图片描述
比对源代码和参数表以及bin文件发现,bin文件中offset30-32的地址上为0x500400,所以一直在读0x500400。也有看到相关的博客上说需要将50改成00,更加验证了我的这个想法,不知道原工具链的为50的目的,但确实改成00后单核启动成功了。

三.从核启动

我的源程序是双核单镜像的,程序不是特别复杂,但单镜像中通过DNUM寄存器让两个核执行不同的代码。刚开始我认为从核的启动只需要核0启动后,给核1的magicaddr写入_c_int00地址,再给IPC中断即可,尝试了N次之后发现从核一直起不来。分析原因:一是不是核1的代码没有从flash搬到内存里来?但核0的代码通过ROM里面的boot代码自动搬运了,核1和核0共用相同的代码,应该不需要再去搬运核1的代码。二是不是IPC中断没有给到,是不是需要初始化IPC中断,注册中断事件?最后发现都不是。我最后观看了x龙的DSP教学视频关于DSP6678多核架构的共享内存,想到我程序的cmd文件配置的代码和数据都是放在核内的L2SRAM中,ROM里的bootloader搬运也只有0核的,核1的L2SRAM
里并没有程序,所以一直起不来。我参考了x龙C6678光盘提供的MultiCore_SingleIamge源程序中的cmd文件,将.text,.cinit,.const等存入MSMCSRAM共享内存中。注意此时的_c_int00入口地址发生变化,重新赋值给核1 的magicaddr。再重新生成.out文件,再用工具链生成.bin文件烧写进去即可。后续就跟单核的一样了。

虽然现在写出来很轻松,但当时调试的时候是真的掉头发。特意写下来,仅供参考。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值