基於ARM編譯器版本5的工程遷移與適配到ARM編譯器版本6.12 後續2 - 堆棧初始化以及總線異常問題

By: Ailson Jack
Date: 2019.12.31
個人博客:http://www.only2fire.com/
本文在我博客的地址是:http://www.only2fire.com/archives/111.html,排版更好,便於學習,也可以去我博客逛逛,興許有你想要的內容呢。

爲了描述方便,將ARM Compiler 5簡稱爲AC5,將ARM Compiler 6.12簡稱AC6.12

       目前,我自己的工程已經可以成功的使用AC6.12進行編譯和調試了。在適配工程的尾聲,也遇到了兩個問題,在這裏記錄下來,以便後面查證。

我這裏使用的開發環境如下:

    CPU:LPC55S69

    Keil:5.27

    ARM Compiler:AC6.12

1Heap region was used, but no heap region was defined

    工程中,我使用的是自己的分散加載文件,並且沒有定義ARM_LIB_STACKHEAP,ARM_LIB_STACK,ARM_LIB_HEAP這些符號,因爲我自己要重新定義堆棧,就沒有使用這些符號,因此在C代碼中加入:__asm(".global __use_no_heap"); //不使用ARM提供的堆函數,但是編譯的時候還是報錯:Error: L6915E: Library reports error: Heap region was used, but no heap region was defined。最初我以爲是分散加載文件的問題,後來查看分析,覺得分散加載沒問題,於是就換個方向思考。

    因爲我在C代碼中添加了不使用ARM提供的堆函數的聲明,然而ARM_LIB_STACKHEAP,ARM_LIB_STACK,ARM_LIB_HEAP這些符號會在ARM官方代碼的堆棧初始化函數中進行使用,那麼我只要分析出是誰在調用ARM官方的堆棧初始化函數,就能夠解決這個問題了。

    後來發現我的啓動代碼中少寫了一個函數__rt_entry,這個函數的作用就是一些初始化工作,當然也就包括初始化堆棧了。這個函數在ARM官方庫中已經實現,由於我沒有自定義__rt_entry函數,因此在啓動時會調用ARM官方的__rt_entry函數,也就自然會調用ARM庫中的堆棧初始化函數,在鏈接的過程中,當發現分散加載文件沒有定義ARM_LIB_STACKHEAP,ARM_LIB_STACK,ARM_LIB_HEAP這些符號就報錯:Error: L6915E: Library reports error: Heap region was used, but no heap region was defined

    解決方法:自然是在我的啓動文件中自定義一個__rt_entry函數,該函數會調用main()函數。

2、啓動過程中出現總線異常

    在解決了上面第1個問題後,工程能夠成功的編譯和鏈接,但是程序運行時會出現總線錯誤,而且有時候代碼量減小又不會出現這個問題。最開始分析這個問題,花費了不少時間,也沒有摸着門道。後來也是在我組長的指點下才解決的。

    首先分析下爲什麼這個總線異常問題有時會出現,有時不會出現。這就得說說分散加載文件中加載域和執行域中的一個標誌:NOCOMPRESS,AC6.12的armlink文檔中有對這個標誌的描述:

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.大致意思,默認情況下RW數據會被壓縮放置在image中,只有在分散加載文件中相關的加載域與執行域中使用標誌NOCOMPRESS時,纔不會對RW數據進行壓縮。

    因爲我沒有使用NOCOMPRESS標誌,因此會對RW數據進行壓縮,因此在image中的RW數據會比實際的長度小一些。由於是我自己在啓動代碼中初始化databss,因此在將flash中的RW data拷貝到RAM中時,RW data的長度我仍然使用的是未壓縮的數據長度,該長度大於壓縮數據的長度,在將flash中的RW data拷貝到RAM中時,當長度超過壓縮數據的長度,flash就會產生保護,從而觸發一個總線異常,而且異常的地址存儲在BFAR中。

    解決方法:這裏有兩種解決方法。

    方法1:最簡單的就是在分散加載文件中RW data相關的加載域和執行域使用NOCOMPRESS標誌,當然了這個方法的缺點就是產生的image文件會大一些。

    方法2:可以在啓動代碼中配置好sp,然後就不用去對RW databss進行處理(屏蔽掉自己寫的RW databss的處理代碼),這些工作ARM官方庫會自行處理的(壓縮的RW data在拷貝到RAM中時,ARM官方庫會進行解壓縮的,這些ARM庫代碼在編譯和鏈接的時候會自動的加入到image中)。

       如果覺得文章寫的不錯,對你有幫助,歡迎點贊,關注博主喲!

排版更好的內容見我博客的地址:http://www.only2fire.com/archives/111.html
注:轉載請註明出處,謝謝!^_^

發佈了79 篇原創文章 · 獲贊 25 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章