IAR下直接下载调试报错怎么解决

描述

分散链接与加载一直是嵌入式领域比较劝退新手的难题,在恩智浦i.MX RT系列为代表的多存储器架构的MCU上,分散链接问题体现得尤为明显,毕竟你在链接应用程序各种段(section)时可能会面对包括内部ITCM/DTCM/OCRAM和外部 Flash/SDRAM/PSRAM/HyperRAM等多种存储器空间选择。

虽然存储器空间选择很多,但是一个最终可离线启动的i.MX RT程序(即能被下载进外部非易失存储器,且能被BootROM加载启动)其readonly段应该是一段连续的数据(SREC/HEX格式镜像文件里仅能包含一段空间地址),即要链接在一个主存储器空间里,这也意味着其它链接在非主存储器空间的 .text 段应该使用重定向方法来实现,不可直接原地链接,参考文章 《IAR下将源文件代码重定向到任意RAM中的方法》最近有一个i.MX RT1060客户,他们就遇到了分散链接工程调试问题,工程readonly段被直接分散链接到了两个不同的外部存储器空间,没有用重定向方法,这虽然不符合离线启动要求,但是在IAR下直接下载调试也会报错,这是怎么回事?  1. 客户的问题

我们再进一步描述客户工程分散链接问题,下图包含了i.MX RT架构下程序段的全部链接选择,根据这些选择组合,我们能产生多种不同的工程链接文件。

下载调试

先来看不涉及分散链接的简单情况,即readonly段全在Flash里,readwrite段在一个或多个RAM空间里,这种情况下IAR下载调试没有什么特殊注意事项,flashloader会负责外部Flash初始化,并将readonly段数据下载进Flash,然后宏文件负责外部RAM初始化,在线调试一切正常。

Case1:APP readonly text/data1 + APP readwrite data2/3/4

再来看第二种情况,这里开始涉及分散链接,readonly段分散在多个RAM空间,readwrite段在一个或多个RAM空间里。这种情况下因为没有链接在Flash空间,因此无需flashloader,完全由宏文件将相关外部RAM初始化好,多个readonly段都能正常下载,在线调试一切正常。

Case2:APP readonly text/data2/3/4 + APP readonly text/data2/3/4 + APP readwritedata2/3/4

第三种情况再复杂一点,readonly段除了在Flash空间外,还有一部分放在了内部RAM里,然后readwrite段依然在一个或多个RAM空间里。这种情况下IAR下载调试感觉上应该没问题,因为内部RAM无需初始化可直接访问,两个不连续readonly段原则上可以下载,但是很遗憾,IAR会报错,其flashloader无法处理放在内部RAM的readonly段,调试无法进行。

Case3:APP readonly text/data1 + APP readonly text/data2 + APP readwrite data2/3/4

最后一种分散链接的情况最复杂,也是客户的问题所在,readonly段除了在Flash空间外,还有一部分放在了外部RAM,然后readwrite段在一个或多个RAM空间里。这种情况下IAR下载调试一定会出问题,默认flashloader只做了Flash初始化,并不负责初始化外部RAM,因此部分readonly段往外部RAM下载时会报错,工程宏文件虽然负责初始化外部RAM,但其执行阶段在flashloader作用之后,鞭长莫及。

Case4:APP readonly text/data1 + APP readonly text/data3/4 + APP readwrite data2/3/4

 

2. 复现客户问题

我们在恩智浦官方MIMXRT1060-EVK板上复现一下客户问题,使用SDK_2.11.0_EVK-MIMXRT1060oardsevkmimxrt1060demo_appshello_worldiar工程,原工程有很多Build,我们就选用flexspi_nor_sdram build,它用到了两块外部存储器,符合客户场景。

在这个build里readonly段都链在外部Flash里,readwrite段都链接在外部SDRAM里,显然这个情况属于第一节介绍的case1:

  1. Flash初始化工作:IARSystemsEmbedded Workbench9.10.2armconfigflashloaderNXPFlashIMXRT1060_FlexSPI.out

  2. SDRAM初始化工作:SDK_2.11.0_EVK-MIMXRT1060oardsevkmimxrt1060demo_appshello_worldiarevkmimxrt1060_sdram_init.mac

下载调试

我们现在要将工程稍微改动一下,在工程源文件里定义一个sw_delay()函数(记得要在main函数里调用一下),并且将其指定在自定义.sdramCodeSection段里:

#pragma default_function_attributes = @ ".sdramCodeSection"
void sw_delay(void)
{
     __NOP();
}
#pragma default_function_attributes =

然后在工程链接文件里将这个自定义.sdramCodeSection段放到SDRAM空间里,这样我们在外部Flash和SDRAM空间里就都有readonly段了,跟客户情况一致了。

place in DATA3_region { section .sdramCodeSection };

板卡上电,直接用板载DAP-Link调试器在线下载工程(为了减少对板子设置的依赖,我们将调试器复位类型改为Core),下载过程中IAR果然一直在报错,如果你忽略错误继续调试,虽然断点会停在main函数,但是只要单步进放到SDRAM空间的函数里时,程序就会跑飞进hardfault,因为SDRAM中根本就没有正确的.sdramCodeSection段数据。

下载调试

 

3. 仅借助宏文件(.mac)解决问题

分析到这里,其实你应该知道问题出在哪里了,工程配套宏文件evkmimxrt1060_sdram_init.mac本应负责SDRAM初始化,但是其执行顺序在 FlashIMXRT1060_FlexSPI.out作用之后,所以没有产生其该有的效果,这个具体可见旧文 《IAR内部C-SPY调试组件配套宏文件(.mac)用法介绍》 3.1 小节,有非常详细的解释。

现在的解决思路就是,如何让evkmimxrt1060_sdram_init.mac里的SDRAM初始化语句在flashloader作用之前生效,所以我们很自然地想在flashloader配套的宏文件FlashIMXRT1060_FlexSPI.mac里的execUserFlashInit()接口里将SDRAM初始化语句都加上,但是很遗憾,这招不奏效,其实在第一节介绍的case3里就应该认清现实了,内部RAM无需初始化IAR也无法正常下载。

下载调试

 

4. 借助双Flashloader解决问题

其实IAR软件设计里,对于两个readonly段,只要其中有一个段被放入了Flash里(即需要flashloader),那么另外一个段不管是不是放在Flash里也需要有相应flashloader,这里痞子衡要吐槽下IAR的设计,有点呆板了。

所以本文案例里解决问题的关键就是为SDRAM也设计一个flashloader,具体制作方法可以参考旧文《串行NOR Flash下载算法(IAR EWARM篇)》。因为SDRAM擦写其实也不需要什么特殊命令时序,就是单纯AHB方式地写就行了,所以这个SDRAM版本的flashloader就是个傀儡flashloader而已。

为了让这个傀儡flashloader更通用一些,是按如下方式实现三个主要flashloaderAPI的,其中FlashInit()函数里故意没有加SEMC模块初始化代码,就是为了让这个flashloader适用所有类型的RAM(ITCM/DTCM/OCRAM/SDRAM/PSRAM/HyperRAM),外设初始化工作放在傀儡 flashloader配套宏文件里去完成。

FlashInit()   - 什么都不做,直接返回

FlashWrite()  - 用memcpy 函数实现

FlashErase()  - 用memset 函数实现

最终RAM型通用flashloader源码工程地址如下:

https://github.com/JayHeng/imxrt-tool-flash-algo/tree/master/boards/nxp_evkmimxrt1060_rev.a1/ram_algo/IAR

我们把新生成的SDRAM flashloader相关的所有文件(.out/.flash/.mac)放到对应IAR系统目录下,并且修改原来的FlashIMXRT1060_EVK_FlexSPI.board 文件,加入SDRAM 相关的部分:

  1. FlashIMXRT1060_SEMC.mac文件基本沿用evkmimxrt1060_sdram_init.mac文件,只是setup宏函数从execUserPreload换到execUserFlashInit

  2. FlashIMXRT1060_SEMC.flash文件内容按FlashIMXRT1060_FlexSPI1.flash写即可,注意文件后缀一定要是 .flash,IAR只认这个后缀。

下载调试

现在再去下载调试,就一切正常了,说明双Flashloader解决方案生效了。

本例是以IAR flashloader为例的,如果用J-Link flashloader也是可以的,一样的原理制作两个Flashloader即可。

下载调试

 

原文标题:IAR环境下无法直接下载调试i.MX RT分散链接工程的解决方案

文章出处:【微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。

  审核编辑:汤梓红
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分