关于Green Hills启动代码该怎么去配置,还有Green Hills启动代码和芯片入口不匹配的情况要怎么办,遇到这个问题的时候,排查的重点不能只放在启动汇编文件上,芯片的复位机制、链接布局、启动头、向量表和调试脚本,这些东西也要同时去核对。启动代码通常会做的事情,是把栈环境给建立起来,对数据段进行初始化,把BSS段给清零,然后再进到main函数里面去,只要入口地址跟芯片实际上会去取指令的位置没有对准,那么工程就算是编译成功了,程序也可能在复位之后一下子就跑进异常的地址里去了。
一、Green Hills启动代码怎么配置
启动代码的配置,最好是先从当前芯片对应的示例工程开始做,不能光因为内核的架构是一样,就把别的型号工程直接复制过来用,不同芯片之间,对复位入口、启动头、存储器分区,还有多个核的释放顺序,这些要求可能是会有差别的。
1、选择匹配的启动文件
芯片型号、内核架构、编译器的版本,还有启动的方式,这些东西要先确认清楚,然后去检查工程里用的是默认的那个crt0文件,还是芯片厂商给提供的startup文件。
有部分Green Hills的工程,会默认把crt0这一类启动文件给加进去。要是项目需要用到自己写的启动代码,那同时也要把工程构建的选项给检查一下,避免默认的启动文件和自定义的文件一块儿被链接到,两个文件都把入口的符号给定义了的话,就有可能出现重复定义的情况,也有可能会让真正的那个入口来源,跟人们设想的不太一样。
2、配置链接布局
链接文件里面,Flash的起始地址、RAM的范围、栈顶、向量表、启动段、数据段,还有BSS段,这些都要被检查到。
启动代码用到的一些地址符号,它必须是由链接文件给正确地提供出来的。要是工程里面带着Bootloader,应用程序一般就不能再继续放在独立工程用的那个默认起始位置上面了,还要把空间给预留出来,分别给Bootloader、启动头,还有应用的镜像来用。地址区域一旦出现了重叠,那么下载这个动作看起来可能是正常结束了,但真正要启动的内容,却早已经被覆盖掉了。
3、确认初始化顺序
芯片被复位之后,应该先把处理器运行需要的一些基本的初始化工作给完成,然后再进到比较复杂的C函数里面去。
常见的流程,就是先设置栈指针,配置好向量表,把已经初始化的数据给复制过来,将BSS段清零,之后才跳到main里面去。时钟、内存控制器,还有看门狗的处理顺序,是要结合芯片本身的要求来定的。如果是多核的芯片,还要把主核的入口、从核的入口,以及从核的释放条件都给明确下来。
二、Green Hills启动代码和芯片入口不匹配怎么办
入口出现不匹配的时候,常常会看到的现象,就是main里面的断点打不中,程序停在了复位的那个地址上,PC跳进一个无效的区域里面,又或者,只有在调试器还连着的状态下,程序才能跑得起来。排查这个事儿,应该从芯片被复位之后的第一条指令开始做,而不是一上来就去改那些业务的代码。
1、核对复位后的PC地址
让处理器在复位以后马上就停下来,把当时的PC给记录下来,然后再拿着这个值去跟芯片手册里规定的启动位置、启动头里面的入口地址,还有Map文件中的启动符号,这些放在一块儿做对照。
要是这三个地址对不上,那就要去检查启动头、复位向量和链接地址。有一部分芯片,上电之后会先去寻找有效的启动头,接着再把那里面记录的入口信息给读出来跳过去。启动头的位置弄错了,或者里面的内容是无效的,那程序就不会自然而然地进到应用的启动代码里面去了。
2、检查入口符号来源
去Map文件里面,搜一下像_start、reset、Startup_Handler这一类的入口符号,把它们找出来,确认这些符号是从人们所预想的那个目标文件里面来的。
假如工程里面还留着旧芯片的启动文件,那么链接器就还是有可能选中那个旧的入口。同时,也要去检查一下入口段是不是被放到了正确的Flash区域里面去,还有,链接优化是不是把那些没有被引用到的启动段,当成无效的内容给移除掉了。
3、排除调试脚本干扰
要去检查一下MULTI的连接脚本,看看它是不是在复位以后,做了改PC、初始化RAM、关看门狗,或者是直接就跳到应用入口这些事情。
调试脚本的存在,是有可能暂时把启动配置上的错误给掩盖起来的,这就会造成程序在被下载下去之后可以运行,但断了电再重新启动,就跑不起来了,遇到了这种不一样的情况,就应该把调试器预先处理的动作给减少一些,再去观察芯片在真实的上电之后,是怎么去执行那条路径的。
三、启动配置完成后怎么验证
启动的问题被处理过以后,不能光靠着一次调试运行就当作结论,还要去验证内存的初始化、向量表,还有不同的复位方式,这么做是为了不让错误被拖到后面,等到业务程序跑起来的时候才暴露出来。
1、检查关键内存状态
进了main以后,要去看一下栈指针、全局变量的初值,还有那些没有被初始化的变量。初值不对,通常就说明数据复制区那边的配置是有问题的,而随机的变量没有被清零,那就要去查一查BSS段的边界了。
2、核对Map文件
要确认好启动段、向量表、代码段、数据段,还有栈空间,这些东西之间没有发生重叠,而且也没有超出芯片实际有的Flash和RAM的范围。如果是Bootloader工程,还要去检查一下应用的镜像,是不是使用了正确的偏移量。
3、测试不同复位方式
调试器复位、软件复位、看门狗复位,还有断电重新启动,这几种方式要分别都去验证一下,只有当这些场景全部都能稳稳当当地进到同一个启动流程里面的时候,才能说明入口和初始化的配置基本上是对齐了的。
总结
对于Green Hills启动代码该怎么去配置,以及Green Hills启动代码和芯片入口不匹配要怎么办,可以按照“选对启动的文件、把链接布局给配置好、核对复位时候的PC、检查入口符号到底是哪里来的、把调试脚本的干扰给排除掉”这样一个顺序去处理。入口不匹配,往往并不是main函数本身的问题,而是芯片的复位机制、启动头、链接地址,还有启动代码这些东西之间没能对应上,把复位以后实际跑到的地址,跟Map文件里面的一项一项去对齐,也就更容易把程序没办法正常启动的那个具体的位置给找出来了。
