加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

技術(shù) | IAR在線調(diào)試時(shí),什么情況下需要雙Flashloader?

2022/05/20
596
閱讀需 15 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家分享的是IAR環(huán)境下無法直接下載調(diào)試i.MXRT分散鏈接工程的解決方案。

分散鏈接與加載一直是嵌入式領(lǐng)域比較勸退新手的難題,在恩智浦 i.MXRT 系列為代表的多存儲(chǔ)器架構(gòu)的 MCU 上,分散鏈接問題體現(xiàn)得尤為明顯,畢竟你在鏈接應(yīng)用程序各種段(section)時(shí)可能會(huì)面對(duì)包括內(nèi)部 ITCM/DTCM/OCRAM 和外部 Flash/SDRAM/PSRAM/HyperRAM 等多種存儲(chǔ)器空間選擇。

雖然存儲(chǔ)器空間選擇很多,但是一個(gè)最終可離線啟動(dòng)的 i.MXRT 程序(即能被下載進(jìn)外部非易失存儲(chǔ)器,且能被 BootROM 加載啟動(dòng))其 readonly 段應(yīng)該是一段連續(xù)的數(shù)據(jù)(SREC/HEX格式鏡像文件里僅能包含一段空間地址),即要鏈接在一個(gè)主存儲(chǔ)器空間里,這也意味著其它鏈接在非主存儲(chǔ)器空間的 .text 段應(yīng)該使用重定向方法來實(shí)現(xiàn),不可直接原地鏈接,參考痞子衡文章 《IAR下將源文件代碼重定向到任意RAM中的方法》。

最近有一個(gè) i.MXRT1060 客戶,他們就遇到了分散鏈接工程調(diào)試問題,工程 readonly 段被直接分散鏈接到了兩個(gè)不同的外部存儲(chǔ)器空間,沒有用重定向方法,這雖然不符合離線啟動(dòng)要求,但是在 IAR 下直接下載調(diào)試也會(huì)報(bào)錯(cuò),這是怎么回事?

一、引出客戶問題

我們?cè)龠M(jìn)一步描述客戶工程分散鏈接問題,下圖包含了 i.MXRT 架構(gòu)下程序段的全部鏈接選擇,根據(jù)這些選擇組合,我們能產(chǎn)生多種不同的工程鏈接文件。

 

先來看不涉及分散鏈接的簡(jiǎn)單情況,即 readonly 段全在 Flash 里,readwrite 段在一個(gè)或多個(gè) RAM 空間里,這種情況下 IAR 下載調(diào)試沒有什么特殊注意事項(xiàng),flashloader 會(huì)負(fù)責(zé)外部 Flash 初始化,并將 readonly 段數(shù)據(jù)下載進(jìn) Flash,然后宏文件負(fù)責(zé)外部 RAM 初始化,在線調(diào)試一切正常。

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

再來看第二種情況,這里開始涉及分散鏈接,readonly 段分散在多個(gè) RAM 空間,readwrite 段在一個(gè)或多個(gè) RAM 空間里。這種情況下因?yàn)闆]有鏈接在 Flash 空間,因此無需 flashloader,完全由宏文件將相關(guān)外部 RAM 初始化好,多個(gè) readonly 段都能正常下載,在線調(diào)試一切正常。

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

第三種情況再?gòu)?fù)雜一點(diǎn),readonly 段除了在 Flash 空間外,還有一部分放在了內(nèi)部 RAM 里,然后 readwrite 段依然在一個(gè)或多個(gè) RAM 空間里。這種情況下 IAR 下載調(diào)試感覺上應(yīng)該沒問題,因?yàn)閮?nèi)部 RAM 無需初始化可直接訪問,兩個(gè)不連續(xù) readonly 段原則上可以下載,但是很遺憾,IAR 會(huì)報(bào)錯(cuò),其 flashloader 無法處理放在內(nèi)部 RAM 的 readonly 段,調(diào)試無法進(jìn)行。

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

最后一種分散鏈接的情況最復(fù)雜,也是客戶的問題所在,readonly 段除了在 Flash 空間外,還有一部分放在了外部 RAM,然后 readwrite 段在一個(gè)或多個(gè) RAM 空間里。這種情況下 IAR 下載調(diào)試一定會(huì)出問題,默認(rèn) flashloader 只做了 Flash 初始化,并不負(fù)責(zé)初始化外部 RAM,因此部分 readonly 段往外部 RAM 下載時(shí)會(huì)報(bào)錯(cuò),工程宏文件雖然負(fù)責(zé)初始化外部 RAM,但其執(zhí)行階段在 flashloader 作用之后,鞭長(zhǎng)莫及。

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

二、復(fù)現(xiàn)客戶問題

我們?cè)诙髦瞧止俜?MIMXRT1060-EVK 板上復(fù)現(xiàn)一下客戶問題,使用 SDK_2.11.0_EVK-MIMXRT1060boardsevkmimxrt1060demo_appshello_worldiar 工程,原工程有很多 Build,我們就選用 flexspi_nor_sdram build,它用到了兩塊外部存儲(chǔ)器,符合客戶場(chǎng)景。在這個(gè) build 里 readonly 段都鏈在外部 Flash 里,readwrite 段都鏈接在外部 SDRAM 里,顯然這個(gè)情況屬于第一節(jié)介紹的 case1:

1. Flash初始化工作:IAR SystemsEmbedded Workbench 9.10.2armconfigflashloaderNXPFlashIMXRT1060_FlexSPI.out
2. SDRAM初始化工作:SDK_2.11.0_EVK-MIMXRT1060boardsevkmimxrt1060demo_appshello_worldiarevkmimxrt1060_sdram_init.mac

 

我們現(xiàn)在要將工程稍微改動(dòng)一下,在工程源文件里定義一個(gè) sw_delay() 函數(shù)(記得要在 main 函數(shù)里調(diào)用一下),并且將其指定在自定義 .sdramCodeSection 段里:

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

然后在工程鏈接文件里將這個(gè)自定義 .sdramCodeSection 段放到 SDRAM 空間里,這樣我們?cè)谕獠?Flash 和 SDRAM 空間里就都有 readonly 段了,跟客戶情況一致了。

place in DATA3_region { section .sdramCodeSection };

板卡上電,直接用板載 DAP-Link 調(diào)試器在線下載工程(為了減少對(duì)板子設(shè)置的依賴,我們將調(diào)試器復(fù)位類型改為 Core),下載過程中 IAR 果然一直在報(bào)錯(cuò),如果你忽略錯(cuò)誤繼續(xù)調(diào)試,雖然斷點(diǎn)會(huì)停在 main 函數(shù),但是只要單步進(jìn)放到 SDRAM 空間的函數(shù)里時(shí),程序就會(huì)跑飛進(jìn) hardfault,因?yàn)?SDRAM 中根本就沒有正確的 .sdramCodeSection 段數(shù)據(jù)。

 

三、嘗試僅借助宏文件(.mac)解決問題

分析到這里,其實(shí)你應(yīng)該知道問題出在哪里了,工程配套宏文件 evkmimxrt1060_sdram_init.mac 本應(yīng)負(fù)責(zé) SDRAM 初始化,但是其執(zhí)行順序在 FlashIMXRT1060_FlexSPI.out 作用之后,所以沒有產(chǎn)生其該有的效果,這個(gè)具體可見痞子衡舊文 《IAR內(nèi)部C-SPY調(diào)試組件配套宏文件(.mac)用法介紹》 3.1 小節(jié),有非常詳細(xì)的解釋。

現(xiàn)在的解決思路就是,如何讓 evkmimxrt1060_sdram_init.mac 里的 SDRAM 初始化語(yǔ)句在 flashloader 作用之前生效,所以我們很自然地想在 flashloader 配套的宏文件 FlashIMXRT1060_FlexSPI.mac 里的 execUserFlashInit() 接口里將 SDRAM 初始化語(yǔ)句都加上,但是很遺憾,這招不湊效,其實(shí)在第一節(jié)介紹的 case3 里就應(yīng)該認(rèn)清現(xiàn)實(shí)了,內(nèi)部 RAM 無需初始化 IAR 也無法正常下載。

 

四、借助雙Flashloader解決問題

其實(shí) IAR 軟件設(shè)計(jì)里,對(duì)于兩個(gè) readonly 段,只要其中有一個(gè)段被放入了 Flash 里(即需要 flashloader),那么另外一個(gè)段不管是不是放在 Flash 里也需要有相應(yīng) flashloader,這里痞子衡要吐槽下 IAR 的設(shè)計(jì),有點(diǎn)呆板了。

所以本文案例里解決問題的關(guān)鍵就是為 SDRAM 也設(shè)計(jì)一個(gè) flashloader,具體制作方法可以參考痞子衡舊文 《串行NOR Flash下載算法(IAR EWARM篇)》。因?yàn)?SDRAM 擦寫其實(shí)也不需要什么特殊命令時(shí)序,就是單純 AHB 方式地寫就行了,所以這個(gè) SDRAM 版本的 flashloader 就是個(gè)傀儡 flashloader 而已。

痞子衡為了讓這個(gè)傀儡 flashloader 更通用一些,是按如下方式實(shí)現(xiàn)三個(gè)主要 flashloader API 的,其中 FlashInit() 函數(shù)里故意沒有加 SEMC 模塊初始化代碼,就是為了讓這個(gè) flashloader 適用所有類型的 RAM(ITCM/DTCM/OCRAM/SDRAM/PSRAM/HyperRAM),外設(shè)初始化工作放在傀儡 flashloader 配套宏文件里去完成。

FlashInit()   - 什么都不做,直接返回
FlashWrite()  - 用 memcpy 函數(shù)實(shí)現(xiàn)
FlashErase()  - 用 memset 函數(shù)實(shí)現(xiàn)

最終 RAM 型通用 flashloader 源碼工程地址如下:

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

我們把新生成的 SDRAM flashloader 相關(guān)的所有文件(.out/.flash/.mac)放到對(duì)應(yīng) IAR 系統(tǒng)目錄下,并且修改原來的 FlashIMXRT1060_EVK_FlexSPI.board 文件,加入 SDRAM 相關(guān)的部分:

1. FlashIMXRT1060_SEMC.mac 文件基本沿用 evkmimxrt1060_sdram_init.mac 文件,只是 setup 宏函數(shù)從 execUserPreload 換到 execUserFlashInit
2. FlashIMXRT1060_SEMC.flash 文件內(nèi)容按 FlashIMXRT1060_FlexSPI1.flash 寫即可,注意文件后綴一定要是 .flash, IAR 只認(rèn)這個(gè)后綴。

 

現(xiàn)在再去下載調(diào)試,就一切正常了,說明雙 Flashloader 解決方案生效了。本例是以 IAR flashloader 為例的,如果用 J-Link flashloader 也是可以的,一樣的原理制作兩個(gè) Flashloader 即可。

至此,IAR環(huán)境下無法直接下載調(diào)試i.MXRT分散鏈接工程的解決方案痞子衡便介紹完畢了,掌聲在哪里~~~

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

碩士畢業(yè)于蘇州大學(xué)電子信息學(xué)院,目前就職于恩智浦(NXP)半導(dǎo)體MCU系統(tǒng)部門,擔(dān)任嵌入式系統(tǒng)應(yīng)用工程師。痞子衡會(huì)定期分享嵌入式相關(guān)文章