C6678 EMIF NOR Flash启动实战:从手册到板级调试
1. C6678 EMIF NOR Flash启动原理详解
第一次接触C6678的EMIF启动时,我也被各种专业术语搞得一头雾水。后来在实际项目中踩过几次坑才明白,其实整个过程就像搬家——把存放在NOR Flash这个"仓库"里的程序代码,搬运到DSP内部RAM这个"工作间"来执行。关键在于理解三个核心环节:BootMODE配置决定搬家的方式,RBL(ROM Bootloader)是负责搬家的工人,而EMIF接口就是连接仓库和工作间的传送带。
具体到硬件层面,C6678上电后会检测BOOTMODE[12:0]引脚状态。当配置为EMIF16 NOR启动模式时,芯片会通过EMIF接口自动读取NOR Flash起始地址0x70000000处的代码。这里有个容易忽略的细节:NOR Flash的访问速度远低于DSP内部RAM(典型值在100ns左右),所以通常第一段被执行的代码必须是精简的搬移程序,它的唯一任务就是把后续主程序快速搬运到L2 RAM。
我曾遇到过因为忽略这个细节导致启动失败的情况——直接把完整程序烧写到NOR Flash,结果芯片跑起来像老牛拉车。后来在启动代码中加入以下关键片段才解决问题:
#pragma CODE_SECTION(BootLoader, ".bootload") void BootLoader(void) { /* 将NOR Flash中的主程序拷贝到L2 RAM */ memcpy((void *)0x00800000, (void *)0x70000000, 0x100000); /* 跳转到L2执行 */ asm(" B 0x00800000"); }2. 硬件设计关键点与避坑指南
设计EMIF接口电路时,最让人头疼的就是时序匹配问题。记得有次调试,板子死活不启动,用示波器抓信号才发现EMIF的读写时序与NOR Flash芯片不匹配。后来总结出几个硬件设计要点:
1. 器件选型黄金法则
- 容量匹配:建议选择16bit总线宽度的NOR Flash,容量至少是程序镜像的2倍(例如4MB容量的S29GL512P)
- 电压兼容:确认Flash工作电压(3.3V或1.8V)与DSP的EMIF接口电平匹配
- 速度考量:选择访问时间<70ns的型号(如MX29LV320CTTI-70G)
2. 电路设计Checklist
- 地址线A1-A20连接(注意:C6678 EMIF16模式下A0不接)
- 数据线D0-D15必须等长布线(建议长度差<50mil)
- 片选信号CE和输出使能OE需加22Ω串联电阻
- 在EMIF_CLK线上预留π型滤波电路(典型值:22Ω+0.1μF+22Ω)
3. 时序参数配置表
| 参数 | 计算公式 | 典型值(ns) |
|---|---|---|
| Setup Time | tsu = Read Cycle - tACC | 15 |
| Strobe Width | tw(WE) = 2*EMIF_CLK周期 | 20 |
| Hold Time | th = tOE - tDF | 10 |
实测中发现,当板级走线较长时(>10cm),需要在CCS中调整EMIF的异步时序寄存器:
/* 配置EMIF异步时序参数 */ CSL_EMIF_ASYNC_CS2_TIMING_REG(0) = 0x00504050;这个值对应的是:7个读建立周期、4个选通周期、5个读保持周期。
3. 启动镜像制作全流程
制作可启动的NOR Flash镜像就像准备搬家行李清单,少了任何关键物品都会导致系统无法正常运行。经过多次实践,我总结出以下标准化流程:
步骤1:生成原始可执行文件
cl6x -mv6600 --abi=eabi -g -o app.out app.c步骤2:转换文件格式
hex6x -image -memwidth 16 -order MS -bootorg 0x70000000 app.cmd这里有个坑要注意:-bootorg参数必须与链接命令文件中的MEMORY定义一致。
步骤3:生成烧录文件
b2i2c -image app.hex -format hex -o app.bin -swap关键参数-swap用于处理大小端转换,我曾经因为漏掉这个参数导致代码执行乱序。
完整链接命令文件示例:
MEMORY { BOOT_RAM (RX) : origin=0x70000000 length=0x100000 L2SRAM (RWX) : origin=0x00800000 length=0x080000 } SECTIONS { .bootload > BOOT_RAM .text > L2SRAM .data > L2SRAM .bss > L2SRAM }4. 板级调试实战技巧
当所有准备工作就绪,真正的挑战才刚刚开始。根据我的调试笔记,80%的启动失败都集中在以下三类问题:
问题1:启动模式配置错误
- 症状:DSP始终停留在复位状态
- 排查步骤:
- 测量BOOTMODE[12:0]引脚电压(应为b0000 0100 0000)
- 检查上拉/下拉电阻(建议10kΩ)
- 确认复位期间配置引脚不被其他电路驱动
问题2:代码搬移异常
- 症状:PC指针跑飞或卡死
- 调试方法:
/* 在搬移代码前后加入校验点 */ uint32_t *src = (uint32_t *)0x70000000; uint32_t *dst = (uint32_t *)0x00800000; for(int i=0; i<1024; i++) { if(src[i] != dst[i]) { while(1); // 触发硬件断点 } }问题3:EMIF接口信号异常推荐使用如下示波器触发设置:
- 通道1:EMIF_CE(下降沿触发)
- 通道2:EMIF_OE(建立时间测量)
- 通道3:EMIF_D[15:0](总线竞争检测)
有个特别实用的调试技巧:在NOR Flash起始地址处写入特殊指令码(如0x00000000),当看到DSP开始执行这条指令时(通过JTAG读取PC值),就能确认EMIF接口基本工作正常。
最后分享一个真实案例:某次调试发现系统随机启动失败,最终定位到是电源时序问题——NOR Flash需要3.3V I/O电源比DSP核电源早上电至少10ms。这个教训让我养成了每次设计都要仔细检查电源时序的好习惯。
