TMS320C642x DSP的Bootloader是固化在ROM中的一段启动代码,它在芯片上电复位(POR)后首先执行。这段代码通过读取BOOTCFG寄存器的值来确定启动模式,BOOTCFG寄存器在POR上升沿时捕获芯片引脚状态。这种硬件级的设计确保了启动配置的可靠性,避免了软件配置可能带来的不确定性。
C642x支持三大类启动模式,通过FASTBOOT引脚状态进行区分:
非快速启动模式(FASTBOOT=0):设备在PLL旁路模式下运行,CPU时钟直接来源于输入时钟(CLKIN)。这种模式时钟频率较低,但稳定性最高,适合对启动速度要求不高的场景。
固定倍频快速启动模式:当FASTBOOT=1且AEM[2:0]=001b时,PLLMS[2:0]引脚被重新定义为AEAW[2:0],用于选择EMIFA地址宽度。此时PLL倍频器采用固定值。
用户可选倍频快速启动模式(FASTBOOT=1):允许用户通过PLLMS[2:0]引脚选择PLL倍频系数。这种模式可以显著提高启动速度,但对时钟设计和PCB布局有更高要求。
关键提示:如果配置了无效的启动模式,Bootloader会将错误代码写入BOOTCMPLT寄存器的ERR字段,并默认使用UART启动模式(对于非主机启动模式如I2C、SPI等)。
启动模式的选择依赖于以下引脚组合:
这些引脚状态在上电复位时被锁存到BOOTCFG寄存器,Bootloader通过读取该寄存器值来决定后续操作。表1展示了非快速启动模式(FASTBOOT=0)下的配置详情。
表1:非快速启动模式配置表(FASTBOOT=0)
| BOOTMODE[3:0] | PCIEN | 模式描述 | PLL模式 | CLKDIV1 | 启动地址 |
|---|---|---|---|---|---|
| 0000 | 0/1 | 仿真启动(默认) | Bypass | /1 | 0x0010 0000 |
| 0001 | 0 | HPI启动 | Bypass | /1 | 0x0010 0000 |
| 0100 | 0/1 | EMIFA ROM直接启动 | Bypass | /1 | 0x4200 0000 |
| 0101 | 0/1 | I2C启动(标准模式) | Bypass | /1 | 0x0010 0000 |
| 0110 | 0/1 | 16位SPI启动(McBSP0) | Bypass | /1 | 0x0010 0000 |
| 0111 | 0/1 | NAND Flash启动 | Bypass | /1 | 0x0010 0000 |
| 1000 | 0/1 | UART启动(无硬件流控) | Bypass | /1 | 0x0010 0000 |
| 1110 | 0/1 | UART启动(有硬件流控) | Bypass | /1 | 0x0010 0000 |
| 1111 | 0/1 | 24位SPI启动(McBSP0+GP97) | Bypass | /1 | 0x0010 0000 |
当FASTBOOT=1时,Bootloader会根据AEM和PLLMS[2:0]引脚状态配置PLL。表2展示了用户可选倍频快速启动模式下的PLL配置选项。
表2:PLL倍频选择(PLLMS[2:0])在用户可选倍频快速启动模式中
| PLLMS[2:0] | PLL模式 | 时钟频率(27MHz输入时) |
|---|---|---|
| 000 | ×20 | CLKIN ×20 / 2 = 270MHz |
| 001 | ×15 | CLKIN ×15 / 2 = 202.5MHz |
| 010 | ×16 | CLKIN ×16 / 2 = 216MHz |
| 011 | ×18 | CLKIN ×18 / 2 = 243MHz |
| 100 | ×22 | CLKIN ×22 / 2 = 297MHz |
| 101 | ×25 | CLKIN ×25 / 2 = 337.5MHz |
| 110 | ×27 | CLKIN ×27 / 2 = 364.5MHz |
| 111 | ×30 | CLKIN ×30 / 2 = 405MHz |
实践建议:在选择PLL倍频系数时,必须确保不超过芯片的额定工作频率。对于C642x-600器件,最大SYSCLK1频率为600MHz;C642x-500为500MHz,依此类推。
EMIFA ROM启动分为两种形式:
直接启动模式(BOOTMODE[3:0]=0100b, FASTBOOT=0):
快速启动AIS模式(BOOTMODE[3:0]=0100b, FASTBOOT=1):
c复制// EMIFA快速启动AIS模式示例流程
void EMIFA_FastBoot_AIS() {
configure_PLL(PLLMS_value); // 配置PLL
set_EMIF_data_width(BOOTCFG.8_16); // 设置数据宽度
while(1) {
ais_cmd = read_EMIFA(); // 读取AIS命令
process_AIS_command(ais_cmd); // 处理命令
if(ais_cmd == JUMP_CLOSE) break;
}
jump_to_app(ais_cmd.addr); // 跳转到应用程序
}
SPI 16x8启动模式(BOOTMODE[3:0]=0110b)使用McBSP0配置为SPI主模式:
表3:SPI主模式时钟频率(27MHz输入,FASTBOOT=1)
| PLLM | PLLOUT | CPU频率 | MCBSP时钟 | SPI主时钟 |
|---|---|---|---|---|
| 19 | 540MHz | 270MHz | 45MHz | 15MHz |
| 24 | 675MHz | 337.5MHz | 56MHz | 18.7MHz |
| 29 | 810MHz | 405MHz | 67.5MHz | 22.5MHz |
SPI接口连接方式:
注意事项:Bootloader仅支持8位数据排列的SPI EEPROM,因为只提供足够的时钟来获取8位数据。
NAND启动(BOOTMODE[3:0]=0111b)在器件版本1.30后完全支持:
表4:支持的NAND器件类型
| 设备ID | 页大小 | 总容量 | 设备ID | 页大小 | 总容量 |
|---|---|---|---|---|---|
| 0xE3 | 512+16 | 4MB | 0x76 | 512+16 | 64MB |
| 0xE5 | 512+16 | 4MB | 0xF1 | 2048+64 | 128MB |
| 0x6B | 512+16 | 8MB | 0xAA | 2048+64 | 256MB |
| 0x73 | 512+16 | 16MB | 0xAC | 2048+64 | 512MB |
版本注意:对于Rev 1.0和1.20,ROM中存在NAND就绪轮询的竞争条件,建议通过I2C或SPI启动二级Bootloader再加载NAND代码。
AIS是TI专有的启动镜像格式,基本结构包括:
图1展示了AIS的基本结构:
code复制+---------------------+
| Magic Number (0x41504954) |
+---------------------+
| Total Sections Count |
+---------------------+
| Total Bytes to Load |
+---------------------+
| Command 1 (Opcode + Data) |
+---------------------+
| Command 2 (Opcode + Data) |
+---------------------+
| ... |
+---------------------+
| JUMP_CLOSE Command |
+---------------------+
表5列出了AIS 2.0支持的操作码:
表5:AIS 2.0操作码列表
| 操作码 | 值 | 描述 |
|---|---|---|
| Section Load | 0x58535901 | 加载段到指定地址 |
| Request CRC | 0x58535902 | 请求CRC校验 |
| Enable CRC | 0x58535903 | 启用CRC检查 |
| Disable CRC | 0x58535904 | 禁用CRC检查 |
| Jump | 0x58535905 | 跳转到指定地址 |
| Jump_Close | 0x58535906 | 跳转并关闭Bootloader |
| Set | 0x58535907 | 设置寄存器值 |
| Start Over | 0x58535908 | 重新开始AIS解析 |
| Section Fill | 0x5853590A | 填充内存区域 |
| Function Execute | 0x5853590D | 执行ROM函数 |
以下是一个典型的EMIFA ROM快速启动AIS镜像示例:
bash复制# EMIFA ROM Fast Boot AIS示例
41 50 49 54 # 魔术数字
00 00 00 01 # 总节数
00 00 10 00 # 总字节数(4KB)
58 53 59 07 # SET命令
00 00 00 00 # 地址
00 00 00 00 # 值
58 53 59 01 # SECTION_LOAD命令
00 00 00 00 # 目标地址
00 00 10 00 # 字节数
[实际代码/数据...]
58 53 59 06 # JUMP_CLOSE命令
00 00 00 00 # 入口地址
硬件连接:
软件准备:
启动验证:
表6:常见启动问题及解决方案
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 卡在Bootloader初始阶段 | BOOTMODE引脚配置错误 | 检查BOOTMODE[3:0]引脚电压 |
| PLL无法锁定 | 输入时钟不稳定或超出范围 | 确保CLKIN在20-30MHz且稳定 |
| SPI启动失败 | 时钟频率超出EEPROM规格 | 降低PLL倍频或选择更低速EEPROM |
| NAND启动找不到魔术数字 | AIS镜像未正确写入 | 检查NAND编程工具和坏块标记 |
| UART启动无响应 | 波特率不匹配 | 确保主机使用115200bps 8N1 |
| I2C启动超时 | 上拉电阻缺失或值不合适 | 添加4.7kΩ上拉电阻到SCL/SDA |
快速启动优化:
可靠性增强:
调试技巧:
对于复杂系统,可以采用多阶段启动架构:
阶段1:ROM Bootloader
阶段2:Flash中的增强Bootloader
阶段3:应用加载
c复制// 多阶段启动示例流程
void multi_stage_boot() {
// 阶段1:ROM Bootloader
load_stage2_from_SPI(); // 从SPI加载阶段2
// 阶段2:Flash中的增强Bootloader
verify_signature(); // 验证签名
init_all_peripherals(); // 初始化所有外设
select_app_image(); // 选择要加载的镜像
// 阶段3:应用加载
load_final_application(); // 加载最终应用
jump_to_app(); // 跳转执行
}
利用C642x的硬件特性实现安全启动:
镜像加密:
完整性验证:
安全存储:
安全注意:实际安全方案设计需考虑具体威胁模型,建议咨询TI安全专家。
通过Bootloader实现现场固件升级:
双Bank设计:
通信接口选择:
升级流程:
c复制void firmware_update() {
receive_new_image(UART0); // 通过UART接收新镜像
if(verify_image_signature()) { // 验证签名
erase_target_bank(SPI_Flash);// 擦除目标Bank
program_new_image(); // 编程新镜像
update_boot_flag(); // 更新启动标志
reboot_system(); // 重启系统
}
}
在实际项目中,我们曾遇到SPI启动时序问题,最终发现是PCB布局导致的时钟信号完整性问题。通过缩短SPI信号走线长度并添加串联终端电阻,成功解决了启动不稳定的问题。这个经验告诉我们,高速启动模式下的信号完整性至关重要,特别是在选择较高PLL倍频时。