CPU启动流程
根据启动时是否连接了仿真器,分为两种情况:
- Standalone Boot
- Emulation Boot
独立运行时的流程Standalone Boot
先看整体流程图:
BOOT管脚配置BOOTPINCONFIG
BOOT开始时,首先读取管脚配置PINCONFIG。
管脚配置有2组:Z1和Z2.
Z2的优先级比Z1的高。当Z2有效时,会忽略Z1的配置 。
由于这个配置是一次性写入的,写入之后不能更改。因此,通常情况下,先全能Z1配置,保留Z2.当发现Z1配置有误或者不能满足实际使用需求时,再配置Z2.
Z1或者Z2配置是否有效,首先取决于配置的KEY字节。为0x5A,则认为配置有效;其他值认为是无效配置。
BOOT模式选择
Z1或者Z2的配置方式是相同的。都是1个KEY字节,再加上3个PIN字节。
每个PIN字节可以指定具体的哪个管脚用于BOOT选择。3个PIN字节,最多可以组合出8个模式。也可以不需要那么种模式,只需要将BMSPx保持为0xFF即可。
CPU根据配置的GPIO管脚,去读取GPIO的状态(高电平或者低电平),然后决定使用哪种具体的模式。BOOT模式定义如下。
BOOT模式定义
每一种模式可以定义BOOT分支。总共可以定义8种模式。是一个64位的寄存器。
BOOT选项定义(BOOTDEF)
每一种模式定义的值与对应的含义如下:
BOOTDEF的值 | BOOT类型 | 说明 |
---|---|---|
0x00 | Parallel Boot | 并口boot |
0x01 | SCI Boot | 串口boot |
0x02 | CAN Boot | CAN口boot |
0x03 | Flash Boot | 跳转到FLASH执行 |
0x04 | Wait Boot | 在Boot中等待 |
0x05 | RAM Boot | 跳转到RAM中执行 |
0x06 | SPI Boot | SPI boot |
0x07 | I2C Boot | I2C boot |
其他选项
上面定义的Boot选项只是默认情况。比如SCI Boot,虽然都是选择SCIA这个外设作为BOOT入口,但是,SCIA的RX和TX也是有很多种配置的,到底是使用哪个管脚来通信呢?这个也是可以配置的。
当BOOTDEF配置值为0x01时,使用GPIO28和GPIO29作为SCIA的TX和RX。
当配置值为0x21时,使用GPIO16和GPIO17。。。
CAN口和I2C口、SPI口的情况是类似的。
FLASH BOOT也可以灵活配置,可以选择跳转到不同的扇区:
Wait Boot也可以选择开启或者关闭看门狗:
BOOTDEF解码失败,则会跳转到Flash Boot.
实例
配置
比如Z2不配置。Z1配置为:
- KEY=0x5A,
- BOOTPIN_CONFIG中BMSP0 = 0x01,表示使用GPIO1作为BOOT选择管脚。
- BMSP1和BMSP2都为0xFF。代表不使能。
将只使用mode0和mode1这两种模式。
BOOTDEF配置为:
- BOOTDEF.BOOTDEF0 = 0x02 ,代表CAN Boot
- BOOTDEF.BOOTDEF1 = 0x03,代表FLASH Boot
结果
上电时,当GPIO1为低电平时,会进入到CAN Boot;当GPIO1为高电平时,会跳转到FLASH运行。
出厂默认配置
当Z1和Z2都无效时,将使用出厂默认配置:
BOOT选择管脚
默认使用GPIO24和GPIO32作为BOOT选择的管脚。共有4种可能的boot模式。
SCI 模式可以用作wait boot模式,只要在 SCI 自动波特率锁定过程中继续等待“A”或“a”。
BOOT ROM的内容
BOOT ROM存储空间映射表如下。这一部分内容是芯片出厂时固化的。
其中,BOOT代码占用的空间为0x003F 4082 ~ 0x003F 8051。这部分代码中,有一些“死循环”,可以参照下面的地址空间来判断到底发生了什么。
Wait Points
InitBoot
BootROM中包含的一个重要内容就是InitBoot()函数。
InitBoot()函数的首地址,会存储在0x3F FFC0的位置。
CPU复位后,执行RESET中断向量,即跳转到0x003F FFC0位置所存储的值的地址去执行。
不同的CPU型号,里面BootROM的地址分配不一样。
比如:下图中是28377D的CPU1的情况,表示InitBoot()函数在0x003F F16A的位置。
查看手册,可以看到0x003F F16A是在Boot区间。
Reset Code Flow
下图是2812的复位后的流程,供参考。
仿真器模式BOOT
上述的standalone模式是CPU独自运行时的流程,也可以使用仿真器来调试和验证。
方法是:连接了仿真器,并且设置EMU_BOOTPIN_CONFIG寄存器。
上图中有2个重要的分支。当KEY为0xA5时,将在仿真器模式下,运行模拟的Standalone Boot,使用的仍然是OTP中配置的参数;当KEY配置为0x5A时,将使用EMU系列寄存器中配置的参数,来执行BOOT逻辑。这样的好处是,可以多次修改寄存器的值来反复验证BOOT流程,而不是像OTP那样只能烧写一次。
BOOT ROM配置寄存器
分3个部分:
- 仿真器模拟配置
- Z1区配置
- Z2区配置
配置内容:
- BOOTPIN-CONFIG:32位,分为4个字节:KEY(0x5A)、3个BMSP(BOOT模式选择管脚)
- BOOT-GPREG2:32位,用于MPOST等。参考:4.7.1.1 GPREG2 Usage and MPOST Configuration
- BOOTDEF-LOW和BOOTDEF-HIGH:共64位,分为8个字节,用于配置每种模式下的BOOT选项(是SCI boot、FLASH Boot还是RAM Boot等)。
EMU地址冲突
那么,问题来了,既然EMU-BOOTPIN-CONFIG的地址是0x0000 0D00。
可以,中断向量表的首地址也是0x0000 0D00啊。
这两个家伙的地址怎么重叠了?
从仿真器中也可以看到,这两个寄存器的地址确实是重叠的:
这样的话,那么,写到0x0D00地址的内容,到底是用作EMU-BOOTPIN-CONFIG,还是当成第一个中断向量呢?
实际上,中断向量表的前面12个已经不用了。这个位置被EMU-BOOTPIN配置“鸠占鹊巢”了。
BOOT对RAM的使用
BOOT运行时也需要使用RAM。应用程序不要使用这块区间。
地址从0x0002开始,长度为0x0126。
看看默认的cmd文件,已经留下来了,不会分配给用户的APP程序了。
BOOT RAM起始地址
为什么是双0x0000 0002开始呢?
因为前面2个字节要留给RAM BOOT使用。当配置为RAM BOOT时,CPU复位后会跳转到RAM的起始地址(即0x0000 0000)处开始执行。这个地方要存储一条跳转指令,正好占用2个字节。这条跳转指令会跳到RAM中的main函数(或者说是c_int00函数)。
参见RAM链接文件:
BOOT RAM保存的内容
BOOT RAM保存的内容,对用户程序是可见的,有些内容对应用层是有用的。
BOOT Status
比如0x0002 ~ 0x0003处的32位内容是BOOT Status,
具体内容如下:
比如,当进入到SCI BOOt时,bit4的值就是1.
Boot Mode and MPOST (Memory Power On Self-Test) Status
BOOT Mode也可以看得到。
参考文档
TMS320F28002x Microcontrollers Technical Reference Manual (Rev. A) (英文內容)
Chapter 4
ROM Code and Peripheral Booting