新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Andes SAG應用實例

        Andes SAG應用實例

        作者: 時間:2014-12-04 來源:電子產品世界 收藏

          在開發中,系統軟件設計特別是各種的規劃是必不可少的一個環節,它也直接體現在鏈接腳本的撰寫上。 因鏈接腳本的語法相對復雜和篇幅較大,前期撰寫和后期維護對工程師來講難度都很大, 但對使用AndesCore做開發的工程師來講,Andes SAG是一大福音,它提供簡單直觀的描述語言替代了復雜的鏈接腳本。我們收到的反饋也證明,越來越多的工程師開始采用Andes SAG替代linker,之前我們有一篇技術文章對SAG的語法格式做了介紹并說明如何使用,本文將展示四個實際工程開發的例子,以幫助廣大開發者更好的熟悉和理解Andes SAG,同時可以作為開發時的參考。

        本文引用地址:http://www.104case.com/article/266369.htm

          1.將函數和變量指定到特定地址

          第一個例子是如何將函數和變量的地址指定到一個特定的地址,例子中的地址指運行地址——VMA。有這樣要求的原因有很多,諸如SOC的運行地址空間不連續,或者需要高效使用某一塊效率很高的等情況。解法分為兩步:一,在SAG文件中添加自定義的section,將此section的VMA設定到指定地址;二,在C語言中,將需要改變的函數和變量用特定的語法放在自定義的section。

          圖表1是在SAG中自定義section 的例子。第1行關鍵詞USER_SECTIONS表示后面接的這幾個sections都是由使用者自定義的sections。

            

         

            

         

          圖表1. Samp1.sag文件

          圖表1中,第4行至8行表示從0x0開始的區域是只讀區,包含程序代碼(.text section)及只讀數據段(.rodata section)。第9行,MYRAM0部分表示.mysection0的VMA從0x00014000開始。以此類推,MYRAM1和MYRAM2部分各自表示mysection1和.mysection2的VMA起始位置。第21行的RAM1里放的是.data及.bss sections,執行時期會從0x00010000開始,源代碼中須做到將data 的LMA地址copy至 VMA位置,可以使用 __data_lmastart 與 __data_start 來尋址。

          指定函數放在自定義section里,在源代碼的對應處要使用__attribute__((section(".mysection0")))語法,完整寫法請參考圖表2a。圖表2b是另外一種寫法。

            

         

          圖表2a. 指定函數放在自定義section

            

         

          圖表2b. 指定函數放在自定義section的另一種寫法

          指定全局變量gdata1放在自定義section .mysection1里,在源代碼的對應處要使用__attribute__((section(".mysection1")))語法,完整語法請參考圖表3。

            

         

          圖表3. 指定變量放在自定義section

          將函數和變量這樣指定后,編譯后的adx(elf)文檔可以清晰看到對應Section的LMA與VMA如圖表4.

            

         

          圖表4. ELF Header

          2.實現IVB在運行時切換

          有一個客戶需要系統在開機與正常運行時能有不同的ISR,即是同一個中斷的服務函數在開機和正常運行時會不一樣。對于這個問題的解法有很多,我們今天介紹是其中一種解決方法:設置一個新的Vector Table,新的Vector Table會跳到新的ISR;通過SAG將新的Vector Table指定到一個特定地址上;當程序開機完成,需要正常運行時,只需要去修改IVBASE (ir3)這個寄存器。

          所以完成這個例子的重點是如何在匯編代碼中建一個新的vector table 并指定到自定義的section中。表5是實例的寫法:

            

         

            

         

          圖表5 指定Vector table到自定義section

          圖表5重點是是第一行,.section 是用來定義非標準的section,.nds32_aa 即為非標準section的名稱,”a”表示allocable, “x”表示executable. 因為Andes的標準vector table一般會放在.nds32_init section,所以新的vector table 放.nds32_aa里,名稱不一樣能區別就好。接下來是讓新的自定義section .nds32_aa 運行在特定地址上,如圖表6所示。

            

         

            

         

          圖表6 指定自定義section到特定地址

          這樣新的vector table的首地址會被固定到0x10000的位置,當程序開機完成,只需要將IVBASE設定到這個地址,那么當有中斷進來,就會跳到新的Vector Table中。

          3.指定一個或幾個C檔的所有section到指定地址

          上兩個例子有共同點是通過編程將某一段程序放到自定義section,區別在于一個是指定C語言函數和變量到自定義section,一個指定匯編函數到指定的section,都需要改動源代碼。然而對于一些應用場景,比如不提供源代碼只有編譯好的.o或者.a 文件,如果想將.o檔里的section指定到特定地址運行,這個時候該如何做呢?請參考圖表7A的寫法,這表示我們要將hello.o的只讀區,包含程序代碼(.text section)及只讀數據段(.rodata section)放在LMA及VMA在0x10000的地址上。

            

         

          圖表7A 指定自定義section到特定地址

          在整個project 中如果將每個.o檔都列出來,那么整個SAG文檔將變得難以閱讀,而且在給后期維護帶來麻煩,這種解法不好。如果使用者只需要排除幾個.o檔,對于熟悉GNU linker的讀者會想到“EXCLUDE_FILE”這一語法,讓使用者可以很方便地在Linker中實現這一需求。Andes SAG也與時俱進地引入這一語法。圖表7B正是這樣一個例子,它將uart.o中所有的section 都放到一個特定地址去運行,而其它的保持不變。

            

         

          圖表7B 支持“EXCULDE_FILE”

          4、如何避免LMA或VMA的偏差

          在前三個例子中,都是舉例去說明如何實現將程序的某一部分的LMA或者VMA固定在某一個特定地址上,這是對鏈接這一動作的基本要求。軟件工程師需要知道,當某一section的LMA與VMA不相等時,那么在程序初始化時需要將這一section從LMA的地址拷貝到VMA的地址。初始化做拷貝時,這些section的LMA和VMA都是在鏈接腳本中賦值的,代碼中只是去做引用。

          Andes SAG同樣可以給變量賦值LMA和VMA,但如何賦值呢,是不是一個一個緊湊地排列下來?答案很顯然是不。很多工程師都知道,數據存放有Alignment的要求,比如4 Byte 的Word其存放的首地址需要是4 Byte Align;程序呢,因為優化的需要,比如在Andes 編譯器在-Os等級下,函數的首地址同樣強制4 Byte Align。既然有對齊的要求,就必然有gap存在,當然這里舉出的對齊因素只是讓讀者了解到鏈接器對某一section的LMA或VMA的數值確定不只是單純累加,Andes SAG能自動處理好大部分對齊狀況。但在一些較復雜的例子中,需要給Andes SAG更多指示,讓它工作正確。

          首先,我們來看圖表7所舉出的例子,這一行“LOADADDR NEXT __uart_lmastart”,有一個關鍵字“NEXT”。它的作用就是讓SAG知道,這個變量的取值是下一個Section的開始,而不是上一個Section的結束。為了讓讀者更明白所表示的含義,我們首先來看依照圖表7的SAG編譯出的elf(adx)檔header信息,如圖表8:

            

         

          圖表8 adx header

          可以看到.text_*uart.o 的LMA應該是0x1c60, 上一個section(.bss)的LMA結束地址應為:0x1c48+0x10=0x1c58,所以為了清晰地讓SAG知道__uart_lmastart代表.text_*uart.o的LMA開始而不是.bss的LMA結束,我們應該用NEXT去修飾它。

          然后,我們再來看圖表9的例子,這個例子中,使用“LMA_FORCE_ALIGN”的原因是因為可能某一個section的size 只有2 Byte(不是4 Byte的整數倍),但下一個section的VMA 起始地址需要4 Byte Align,這時就會出現沖突,為解決沖突,Andes SAG引入這一關鍵字“LMA_FORCE_ALIGN”,強制讓LMA與VMA用同一個值去做Align。

            

         

          圖表9 “LMA_FORCE_ALIGN”example

          我們用圖表9的SAG 例子去編譯對應的project,可以看到圖表10中section .sbss_b的LMA已經被從0x1d42調整到0x1d44。

            

         

          圖表10 “LMA_FORCE_ALIGN”的效果

          5、結語

          Andes提供通俗易用的SAG工具幫助工程師替代了復雜的鏈接腳本,可以大大提高在Andes core平臺上的軟件開發效率。本文從實際例子出發,介紹了Andes SAG 工具如何快速解決工程實際問題,說明了Andes SAG強大而且容易上手。然而工具的功能越強大,也就需要工程師多加深入了解功能設計的緣由,這也正是最后一個例子展現出來的道理,即是透徹了解就可以熟能生巧。希望廣大讀者能熟練掌握Andes SAG這樣一把利器,在軟件開發中發揮四兩撥千斤的作用。

          參考文檔:

          1: BSP321 programming guide link generator

          2: The GNU Linker Manual

        linux操作系統文章專題:linux操作系統詳解(linux不再難懂)

        可控硅相關文章:可控硅工作原理


        c語言相關文章:c語言教程


        比較器相關文章:比較器工作原理


        存儲器相關文章:存儲器原理




        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 大厂| 图们市| 明星| 彭泽县| 华安县| 宾川县| 文山县| 通榆县| 胶州市| 历史| 集安市| 睢宁县| 无棣县| 宜春市| 咸丰县| 佛山市| 六安市| 庐江县| 密云县| 石泉县| 博罗县| 无锡市| 九龙城区| 资阳市| 临清市| 吴桥县| 武汉市| 阿尔山市| 达孜县| 长岭县| 大姚县| 滦平县| 监利县| 甘孜县| 康保县| 金湖县| 石狮市| 汝城县| 上林县| 若尔盖县| 威宁|