汽车电子expert成长之路

本博客发布的个人原创精品----嵌入式系统技术文章,欢迎大家参考学习,并转发分享!

S32DS使用Tips之应用工程升级重新编译运行程序跑飞问题解决

0
阅读(314) 评论(0)

S32DS使用Tips之S32DS for Power v1.1应用工程升级到v1.2重新编译运行程序跑飞问题解决

内容提要

引言

1. 问题解决方案(issue solutions)

Step1、将S32DS for Power v1.1的应用工程导入S32DS for Power v1.2的工作空间(Workspace)

Step 2、Quick Fix快速修复S32DS for Power v1.1应用工程链接文件中缺失的v1.2 GNU工具链默认段(sections)

Step 3、替换section.ld文件中的.text 段放置内容

Step 4、清除编译结果,重新编译工程

2. 问题分析(the root cause analyze)

2.1 使能汇编指令单步调试模式,跟踪汇编指令执行情况

2.2  修复链接文件前的异常的系统库函数_init和程序跑飞原因

2.3  修复链接文件后的正常的系统库函数_init及其调用运行情况

总结


引言


很多读者跟我反馈说遇到了老的S32DS使用Tips之S32DS for Power v1.1应用工程升级到S32DS for Power v1.2之后,重新编译下载运行,程序跑飞的问题,具体如下,在应用程序的main()函数最开始会调用系统库函数_eabi,无法单步运行跳过该函数调用正常运行应用程序的其他代码,它会直接跑飞到地址0x10:

2-1.jpg


经过一晚上的研究,终于找到了这个问题的解决方案。


本文将详细介绍这个问题的解决方法和步骤,并给出问题的根本原因分析,希望能够对大家有所启发和帮助。


1. 问题解决方案(issue solutions)


Step1、将S32DS for Power v1.1的应用工程导入S32DS for Power v1.2的工作空间(Workspace)


在S32DS for Power v1.2中选择菜单File-->Import..:

3.jpg

选择General-->Existing Projects inti Workspace-->Next:

4.jpg

选择要导入的S32DS for Power v1.1应用工程-->Finish,完成导入:

5.jpg


此时选中导入的应用工程,在Problem窗口中将自动显示其连接文件中缺少一些缺省段(sections)定义:

6.jpg


Tips:如果一个工作空间(Workspace)下存在多个应用工程,且有打开的话,在Problems窗口中可能会同时显示其他应用工程的error和warnings,为了排除其影响,精确定位当前工程的问题,可以选中要处理的工程,然后右键-->Close Unrelated Projects,将其他不相关应用工程关闭:

7.jpg


Step 2、Quick Fix快速修复S32DS for Power v1.1应用工程链接文件中缺失的v1.2 GNU工具链默认段(sections)


选中其中任意一个warning,然后右键,选择Quick Fix:

8.jpg

在弹出的Quick Fix窗口中,选择Add missed section in linker script-->Select All-->Finish完成修复:

9.jpg


Tips:关于S32DS for Power IDE的应用工程链接文件相关知识,请参考本公众号之前的文章《S32DS使用Tips--S32DS for Power V1.2 链接文件和启动过程详解》直接单击跳转即可阅读;


Step 3、替换section.ld文件中的.text 段放置内容


此时,还会剩下一个叫“linker script has deprecated section by position 896”的链接脚本文件中存在不宜用(deprecated)段的warning提示,双击它,将打开应用工程的section.ld文件,并跳转到.text段的放置区域:

10.jpg


将整个.text段的放置内容替换为以下内容(S32DS for Power v1.2新建应用工程默认的.text段定义),通过链接文件关键词KEEP(),增加*(.fini)段,并让编译器强制保留*(.init)和*(.fini)段:


  .text :

   {

     *(.text.startup)

     *(.text)      

     *(.text.*)

    KEEP (*(.init))

     KEEP (*(.fini))            

     . = ALIGN(16);

   } > m_text

11.jpg


Step 4、清除编译结果,重新编译工程


最后,保存section.ld,选中该应用工程右键-->Clean Project,将工程之前的编译结果清除并重新编译。


这个时候,在重新下载调试该应用工程就可以正常工作了:

12.jpg


2. 问题分析(the root cause analyze)


2.1 使能汇编指令单步调试模式,跟踪汇编指令执行情况


通过使能汇编指令单步调试模式(单击选择图标i->)可以跟踪汇编指令,在main函数最开始其调用了EABI库中的系统函数_eabi:

13.jpg


汇编单步运行跳转至函数_eabi,可以发现在其最后有调用了库函数_init:

14.jpg


2.2  修复链接文件前的异常的系统库函数_init和程序跑飞原因


汇编单步运行跳转至库函数_init,可以发现在修复链接文件之前,其函数内容如下,只有三行汇编代码,而且没有返回指令(blr),所以其会顺序执行放在其后面的其他程序代码。

 


而在本例中为uSDHC模块的软件复位函数Soft_Reset(),其中会读写uSDHC模块的控制寄存器,但是请注意此时还未使能外设模块的系统时钟(通过模式入口--Mode Entry模块),所以此时对时钟受Mode Entry模块控制的任一外设寄存器进行操作都将错误总线错误(bus error),从而触发关Machine Check--机器检查的CPU内核系统异常IVOR1(相关知识请参考本公众号之前的文章《S32DS 使用Tips之S32DS for Power不同版本之间的GNU工具链差异与外设寄存器位域访问问题总结》直接单击跳转即可阅读),其偏移地址为0x10,而此时我们并未初始化IVPR寄存器(相关知识请参考本公众号之前的文章《外设使用Tips之Qorivva MPC56xx_57xx系列MCU内核异常(IVORx)与IRQ中断处理详解》直接单击跳转即可阅读),故程序会跳转到0x10的未定义地址(即文章一开始引言说描述的异常地址跳转情况):

15.jpg


Tips:Qorivva MPC56xx/57xx系列MCU的外设时钟控制由MC_ME_PCTLxx寄存器控制(相关知识请参考本公众号之前的文章《外设使用Tips之Qorivva MPC56xx/57xx系列MCU的模式控制与切换(片上外设资源使能与功耗控制)》直接单击跳转即可阅读),具体请参考芯片参考手册(如下为本例中介绍的MPC5748G的SDHC模块,其时钟由MC_ME_PCTL7寄存器控制):

16.jpg


2.3  修复链接文件后的正常的系统库函数_init及其调用运行情况


而修复链接文件并修改其中.text段放置内容补全并强制保留*(.fini)段之后的库函数_init,则如下图所示,增加了对库函数frame_dummy和__do_global_ctors_aux,最后通过返回指令se_blr返回带main()函数,从而不会继续往下执行其他程序代码,因此可以正常工作,且在库函数_init,之后还多了_fini:

17.jpg


在库函数frame_dummy中又调用了库函数register_tm_clones:

18.jpg


库函数register_tm_clones如下:

19.jpg


库函数_init中调用的另外一个库函数__do_global_ctors_aux如下:

20.jpg


总结


通过这个问题的解决和分析可知,S32DS for Power IDE不同版本所使用的免费GNU工具链存在一定的差异,其中有很多gcc编译器和ld链接器的系统默认保留段,它们是应用程序编译结果能够正常运行和工作的基础,必须保证其完整性。


因此,建议大家有时间可以仔细研究和学习一下GNU工具链,我也会在后期的公众号文章中根据需要进行介绍,敬请关注。


Tips:根据本公众号之前的文章《S32DS 使用Tips之S32DS for Power不同版本之间的GNU工具链差异与外设寄存器位域访问问题总结》(直接单击跳转即可阅读)的介绍,S32DS for Power v1.2与 S32 DS for Power v2017.R1所使用的GNU工具链相同,所以它们之间的应用工程迁移/升级时不存在本文所讲的问题,而从S32DS for Power v1.1到 S32 DS for Power v2017.R1的应用工程迁移/升级,同样可以使用本文介绍的方法进行解决。