分散鏈接與加載一直是嵌入式領(lǐng)域比較勸退新手的難題,在恩智浦i.MX RT系列為代表的多存儲器架構(gòu)的MCU上,分散鏈接問題體現(xiàn)得尤為明顯,畢竟你在鏈接應(yīng)用程序各種段(section)時可能會面對包括內(nèi)部ITCM/DTCM/OCRAM和外部 Flash/SDRAM/PSRAM/HyperRAM等多種存儲器空間選擇。
雖然存儲器空間選擇很多,但是一個最終可離線啟動的i.MX RT程序(即能被下載進(jìn)外部非易失存儲器,且能被BootROM加載啟動)其readonly段應(yīng)該是一段連續(xù)的數(shù)據(jù)(SREC/HEX格式鏡像文件里僅能包含一段空間地址),即要鏈接在一個主存儲器空間里,這也意味著其它鏈接在非主存儲器空間的 .text 段應(yīng)該使用重定向方法來實現(xiàn),不可直接原地鏈接,參考文章 《IAR下將源文件代碼重定向到任意RAM中的方法》。最近有一個i.MX RT1060客戶,他們就遇到了分散鏈接工程調(diào)試問題,工程readonly段被直接分散鏈接到了兩個不同的外部存儲器空間,沒有用重定向方法,這雖然不符合離線啟動要求,但是在IAR下直接下載調(diào)試也會報錯,這是怎么回事? 1. 客戶的問題我們再進(jìn)一步描述客戶工程分散鏈接問題,下圖包含了i.MX RT架構(gòu)下程序段的全部鏈接選擇,根據(jù)這些選擇組合,我們能產(chǎn)生多種不同的工程鏈接文件。
先來看不涉及分散鏈接的簡單情況,即readonly段全在Flash里,readwrite段在一個或多個RAM空間里,這種情況下IAR下載調(diào)試沒有什么特殊注意事項,flashloader會負(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段分散在多個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 readwritedata2/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)試無法進(jìn)行。
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
2. 復(fù)現(xiàn)客戶問題
我們在恩智浦官方MIMXRT1060-EVK板上復(fù)現(xiàn)一下客戶問題,使用SDK_2.11.0_EVK-MIMXRT1060oardsevkmimxrt1060demo_appshello_worldiar工程,原工程有很多Build,我們就選用flexspi_nor_sdram build,它用到了兩塊外部存儲器,符合客戶場景。
在這個build里readonly段都鏈在外部Flash里,readwrite段都鏈接在外部SDRAM里,顯然這個情況屬于第一節(jié)介紹的case1:
-
Flash初始化工作:IARSystemsEmbedded Workbench9.10.2armconfigflashloaderNXPFlashIMXRT1060_FlexSPI.out
-
SDRAM初始化工作:SDK_2.11.0_EVK-MIMXRT1060oardsevkmimxrt1060demo_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ù),但是只要單步進(jìn)放到SDRAM空間的函數(shù)里時,程序就會跑飛進(jìn)hardfault,因為SDRAM中根本就沒有正確的.sdramCodeSection段數(shù)據(jù)。
3. 僅借助宏文件(.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也無法正常下載。
4. 借助雙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)三個主要flashloaderAPI的,其中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源碼工程地址如下:
我們把新生成的SDRAM flashloader相關(guān)的所有文件(.out/.flash/.mac)放到對應(yīng)IAR系統(tǒng)目錄下,并且修改原來的FlashIMXRT1060_EVK_FlexSPI.board 文件,加入SDRAM 相關(guān)的部分:
-
FlashIMXRT1060_SEMC.mac文件基本沿用evkmimxrt1060_sdram_init.mac文件,只是setup宏函數(shù)從execUserPreload換到execUserFlashInit
-
FlashIMXRT1060_SEMC.flash文件內(nèi)容按FlashIMXRT1060_FlexSPI1.flash寫即可,注意文件后綴一定要是 .flash,IAR只認(rèn)這個后綴。
現(xiàn)在再去下載調(diào)試,就一切正常了,說明雙Flashloader解決方案生效了。
本例是以IAR flashloader為例的,如果用J-Link flashloader也是可以的,一樣的原理制作兩個Flashloader即可。
原文標(biāo)題:IAR環(huán)境下無法直接下載調(diào)試i.MX RT分散鏈接工程的解決方案
文章出處:【微信公眾號:恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
-
mcu
+關(guān)注
關(guān)注
146文章
17358瀏覽量
352817 -
恩智浦
+關(guān)注
關(guān)注
14文章
5884瀏覽量
108475 -
IAR
+關(guān)注
關(guān)注
5文章
354瀏覽量
36806 -
下載調(diào)試
+關(guān)注
關(guān)注
0文章
2瀏覽量
6527
原文標(biāo)題:IAR環(huán)境下無法直接下載調(diào)試i.MX RT分散鏈接工程的解決方案
文章出處:【微信號:NXP_SMART_HARDWARE,微信公眾號:恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
STM32H750如何使用IAR調(diào)試運行在外部SDRAM的程序?
VSCODE可使用ESP32C3 USB接口直接下載嗎?
iar jlink連接am1808
IAR下對MSP430G2553程序下載與調(diào)試
IAR軟件下載程序報錯怎么解決
ESP32 C3 VSCODE USB接口可以直接下載嗎?
IAR軟件下載程序出現(xiàn)彈窗報錯 “FATAL error:Failed to re-initialize Session aborted“初始化失敗的問題總結(jié)
![<b class='flag-5'>IAR</b>軟件<b class='flag-5'>下載</b>程序出現(xiàn)彈窗<b class='flag-5'>報錯</b> “FATAL error:Failed to re-initialize Session aborted“初始化失敗的問題總結(jié)](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
IAR定位函數(shù)內(nèi)容時報錯“包含錯誤的路徑”
![<b class='flag-5'>IAR</b>定位函數(shù)內(nèi)容時<b class='flag-5'>報錯</b>“包含錯誤的路徑”](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論