之前对编译,链接没有概念,拿到程序,用编译器编译完生成可执行文件就行了。现在发现还是太拉了,得多学习。。。学无止境!~~~~
芯片上电后首先执行的并不是main函数,在main函数之前,还进行了关闭全局中断,系统初始化,初始化ram,之后才会跳到main函数(若是多核,可能还会先跳到_start函数)。
对于TC27x系列,以TC277为例,记录一下启动过程的学习。可能有不对的地方欢迎指正~也可以加我WX/QQ一起交流:953509472~
目录
link中定义:
int_flash0 (rx): org = 0x80000000, len = 1M
SECTIONS
{
.startup_bmhd :
{
/* boot header */
KEEP (*(.bmhd.STARTUP))
. = ALIGN(8);
} > int_flash0 =0x00
...
}
map中表现:
.startup_bmhd memory region -> int_flash0
0x80000000 0x38
*(.bmhd.STARTUP)
.bmhd.STARTUP 0x80000000 0x32 obj/crt0.o
0x80000000 _RESET
0x80000020 _START
0x80000038 . = ALIGN (0x8)
*fill* 0x80000032 0x6 00
启动文件代码
/*
startup code
*/
__asm (".section .bmhd.STARTUP");
__asm (".global _RESET");
__asm (".global _START");
__asm ("_RESET: .word 0x00000000");
__asm (".word 0xb3590070");
__asm (".word 0x00000000");
__asm (".word 0x00000000");
__asm (".word 0x00000000");
__asm (".word 0x00000000");
__asm (".word 0x791eb864");
__asm (".word 0x86e1479b");
/* we must make a jump to cached segment, why trap_tab follow */
__asm ("_START: movh.a %a10,hi:0xD000F000");
__asm (" lea %a10,[%a10]lo:0xD000F000");
__asm (" movh.a %a15,hi:_start");
__asm (" lea %a15,[%a15]lo:_start");
__asm (" ji %a15");
芯片手册中的结构:
四个启动引导头:
启动流程图:
启动步骤:
前面的步骤:检查flash,循环检测启动引导头,检测到正确的即跳转
1.检测BMHDID是否正确 正确应为B359
__asm ("_RESET: .word 0x00000000");//这个存的是用户代码起始地址
__asm (".word 0xb3590070"); 高2个字节表示的就是正确的Boot Mode Header ID
2.计算ABM Header crc校验值
a:与0x18中的比较,通过后到b
__asm ("_RESET: .word 0x00000000");
__asm (".word 0xb3590070");
__asm (".word 0x00000000");
__asm (".word 0x00000000");
__asm (".word 0x00000000");
__asm (".word 0x00000000");
__asm (".word 0x791eb864");
b:crc反校验,通过后到3
3.检查BMI[15:10, 7:0]值是否有效,有效到4
bit BMI[9:8]被排除在这个检查之外,因为它们控制Lockstep Logic,可以有任意值
15-10保留,0-2保留
4-6位HWCFG很重要,用来选择启动模式,TC27x这里选择的是111,即从Flash启动
110:备用启动模式 101:保留 100:通用引导模式 011:ASC引导模式
4.检查BMI[3]=0,即启用HWCFGPIN配置,,HWCFG[3] pin
value=0 (pin-configuration selected) AND (Boot Mode Lock not activated):
a,所有条件为真,则为HW cfg 启动,STSTAT.HWCFG[6]位设置为1,后续忽略
TC27x中配置引脚HWCFG[5:4]的启动方式选择如表4-3所示。这些引脚的值在任何复位(去激活-上升沿)时被硬件锁存到寄存器,该寄存器在启动过程中由SSW读取和评估。
b:若不全为真,则按照Configuration from BMI
接着从a/b加载HWCFG的state a:STSTAT.HWCFG[6]=1 ,b:STSTAT.HWCFG[6:4]=BMI[4:5]
若state!=ABM,从STSTAT.HWCFG执行启动模式,这里即从FLash启动
若为ABM则进行CRC校验,校验正确,则从 Install user code start address from BMI STADD:=BMHD[n].STADABM(也就是最低的四字节)
重要:用户代码的起始地址为:A0000020(也就是80000020)即从第一个启动头之后的字节为起始地址
启动文件后跟的就是启动代码
后面还需要继续学习:汇编语言,_start函数的步骤,还有芯片复位相关的知识
__asm ("_START: movh.a %a10,hi:0xD000F000"); __asm (" lea %a10,[%a10]lo:0xD000F000");这个没太懂是在干啥