• 正文
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

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

2022/05/20
491
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

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

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

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

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

一、引出客戶問題

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

 

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

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

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

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

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

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

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

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

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

我們在恩智浦官方 MIMXRT1060-EVK 板上復(fù)現(xiàn)一下客戶問題,使用 SDK_2.11.0_EVK-MIMXRT1060boardsevkmimxrt1060demo_appshello_worldiar 工程,原工程有很多 Build,我們就選用 flexspi_nor_sdram build,它用到了兩塊外部存儲器,符合客戶場景。在這個 build 里 readonly 段都鏈在外部 Flash 里,readwrite 段都鏈接在外部 SDRAM 里,顯然這個情況屬于第一節(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)在要將工程稍微改動一下,在工程源文件里定義一個 sw_delay() 函數(shù)(記得要在 main 函數(shù)里調(diào)用一下),并且將其指定在自定義 .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 調(diào)試器在線下載工程(為了減少對板子設(shè)置的依賴,我們將調(diào)試器復(fù)位類型改為 Core),下載過程中 IAR 果然一直在報錯,如果你忽略錯誤繼續(xù)調(diào)試,雖然斷點會停在 main 函數(shù),但是只要單步進放到 SDRAM 空間的函數(shù)里時,程序就會跑飛進 hardfault,因為 SDRAM 中根本就沒有正確的 .sdramCodeSection 段數(shù)據(jù)。

 

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

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

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

 

四、借助雙Flashloader解決問題

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

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

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

FlashInit()   - 什么都不做,直接返回
FlashWrite()  - 用 memcpy 函數(shù)實現(xiàn)
FlashErase()  - 用 memset 函數(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)放到對應(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)這個后綴。

 

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

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

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

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