1、Heap region was used, but no heap region was defined
工程中,我使用的是自己的分散加載文件,并且沒有定義ARM_LIB_STACKHEAP,ARM_LIB_STACK,ARM_LIB_HEAP這些符號(hào),因?yàn)槲易约阂匦露x堆棧,就沒有使用這些符號(hào),因此在C代碼中加入下述代碼:
//不使用ARM提供的堆函數(shù) __asm(".global__use_no_heap");
但是編譯的時(shí)候還是報(bào)錯(cuò):Error: L6915E: Library reports error: Heap region was used, but no heap region was defined。最初我以為是分散加載文件的問題,后來(lái)查看分析,覺得分散加載沒問題,于是就換個(gè)方向思考。
因?yàn)槲以贑代碼中添加了不使用ARM提供的堆函數(shù)的聲明,然而ARM_LIB_STACKHEAP,ARM_LIB_STACK,ARM_LIB_HEAP這些符號(hào)會(huì)在ARM官方代碼的堆棧初始化函數(shù)中進(jìn)行使用,那么我只要分析出是誰(shuí)在調(diào)用ARM官方的堆棧初始化函數(shù),就能夠解決這個(gè)問題了。
后來(lái)發(fā)現(xiàn)我的啟動(dòng)代碼中少寫了一個(gè)函數(shù)__rt_entry,這個(gè)函數(shù)的作用就是一些初始化工作,當(dāng)然也就包括初始化堆棧了。這個(gè)函數(shù)在ARM官方庫(kù)中已經(jīng)實(shí)現(xiàn),由于我沒有自定義__rt_entry函數(shù),因此在啟動(dòng)時(shí)會(huì)調(diào)用ARM官方的__rt_entry函數(shù),也就自然會(huì)調(diào)用ARM庫(kù)中的堆棧初始化函數(shù),在鏈接的過(guò)程中,當(dāng)發(fā)現(xiàn)分散加載文件沒有定義ARM_LIB_STACKHEAP,ARM_LIB_STACK,ARM_LIB_HEAP這些符號(hào)就報(bào)錯(cuò):Error: L6915E: Library reports error: Heap region was used, but no heap region was defined。
解決方法:自然是在我的啟動(dòng)文件中自定義一個(gè)__rt_entry函數(shù),該函數(shù)會(huì)調(diào)用main()函數(shù)。
2、啟動(dòng)過(guò)程中出現(xiàn)總線異常
在解決了上面第1個(gè)問題后,工程能夠成功的編譯和鏈接,但是程序運(yùn)行時(shí)會(huì)出現(xiàn)總線錯(cuò)誤,而且有時(shí)候代碼量減小又不會(huì)出現(xiàn)這個(gè)問題。最開始分析這個(gè)問題,花費(fèi)了不少時(shí)間,也沒有摸著門道。后來(lái)也是在我組長(zhǎng)的指點(diǎn)下才解決的。
首先分析下為什么這個(gè)總線異常問題有時(shí)會(huì)出現(xiàn),有時(shí)不會(huì)出現(xiàn)。這就得說(shuō)說(shuō)分散加載文件中加載域和執(zhí)行域中的一個(gè)標(biāo)志:NOCOMPRESS,AC6.12的armlink文檔中有對(duì)這個(gè)標(biāo)志的描述:
RW data compression is enabled by default. The NOCOMPRESS keyword enables you to specify that RW data in an execution region must not be compressed in the final image.
大致意思,默認(rèn)情況下RW數(shù)據(jù)會(huì)被壓縮放置在image中,只有在分散加載文件中相關(guān)的加載域與執(zhí)行域中使用標(biāo)志NOCOMPRESS時(shí),才不會(huì)對(duì)RW數(shù)據(jù)進(jìn)行壓縮。
因?yàn)槲覜]有使用NOCOMPRESS標(biāo)志,因此會(huì)對(duì)RW數(shù)據(jù)進(jìn)行壓縮,因此在image中的RW數(shù)據(jù)會(huì)比實(shí)際的長(zhǎng)度小一些。由于是我自己在啟動(dòng)代碼中初始化data和bss,因此在將flash中的RW data拷貝到RAM中時(shí),RW data的長(zhǎng)度我仍然使用的是未壓縮的數(shù)據(jù)長(zhǎng)度,該長(zhǎng)度大于壓縮數(shù)據(jù)的長(zhǎng)度,在將flash中的RW data拷貝到RAM中時(shí),當(dāng)長(zhǎng)度超過(guò)壓縮數(shù)據(jù)的長(zhǎng)度,flash就會(huì)產(chǎn)生保護(hù),從而觸發(fā)一個(gè)總線異常,而且異常的地址存儲(chǔ)在BFAR中。
解決方法:這里有兩種解決方法。
方法1:最簡(jiǎn)單的就是在分散加載文件中RW data相關(guān)的加載域和執(zhí)行域使用NOCOMPRESS標(biāo)志,當(dāng)然了這個(gè)方法的缺點(diǎn)就是產(chǎn)生的image文件會(huì)大一些。
方法2:可以在啟動(dòng)代碼中配置好sp,然后就不用去對(duì)RW data和bss進(jìn)行處理(屏蔽掉自己寫的RW data和bss的處理代碼),這些工作ARM官方庫(kù)會(huì)自行處理的(壓縮的RW data在拷貝到RAM中時(shí),ARM官方庫(kù)會(huì)進(jìn)行解壓縮的,這些ARM庫(kù)代碼在編譯和鏈接的時(shí)候會(huì)自動(dòng)的加入到image中)。
審核編輯:劉清
-
ARM
+關(guān)注
關(guān)注
134文章
9167瀏覽量
369208 -
RAM
+關(guān)注
關(guān)注
8文章
1369瀏覽量
115007
原文標(biāo)題:基于ARM編譯器版本5的工程遷移與適配到ARM編譯器版本6.12 后續(xù)2 - 堆棧初始化以及總線異常問題
文章出處:【微信號(hào):嵌入式那些事,微信公眾號(hào):嵌入式那些事】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論