新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM/uClinux應用程序的開發

        ARM/uClinux應用程序的開發

        作者: 時間:2012-11-16 來源:網絡 收藏

          可以移植已有的程序還要感謝開放源代碼的弟兄,沒有這些C文件和H文件讓你重新編譯一下,怎么在你的CPU上跑?其實不止這些,后面還會看見開源組織的牛人專為程序可移植性所作的專門的工作。

          那么為什么要移植程序?

          問這問題就像問地上有個錢包為什么要撿一樣,答案不言而喻。現成的東西為什么不要。當然,移植程序可沒有撿錢包那么簡單,尤其是第一次,后面會說一些移植之前應該考慮的問題。(就像現在地上有個錢包也千萬別上去就揣自己兜里,說不定就是套)。另一方面,你給我你寫好的程序讓我拿去用,我還要考慮一下,或許里頭問題多的還不如自己寫一個。我這里所說的可移植的程序應該是維護比較好,比較成熟的源代碼(像我后面的所說的UCD-SNMP),目前的開放源代碼運動決不僅僅是把自己的程序公開就行了,而是有了一套成熟完整的版本控制,BUG報告和PATCH提交流程。

          這樣的代碼才有更大的使用價值。

          什么時候可以考慮移植程序? 在基于嵌入式操作系統進行開發時,具有一定規模的程序都可以到網上查一查都沒有成熟的源代碼可用。前面已經說到,程序的移植最終只針對CPU,其實和操作系統沒什么關系,但另一方面,因為代碼中可能會使用一些庫函數,這些庫會包括C語言標準庫和操作系統提供的API(接口)庫。假設源代碼中只包括C標準庫,那么該程序就可以跨操作系統去移植。例如hello world程序中使用了printf,因為該函數是C標準函數,所以在X86上使用TC(BC或VC)可以直接編譯運行,在平臺下也一樣,但如果程序中調用了vfork函數,那么只有linux一脈相承的操作系統支持這種特殊服務了,在window或dos操作系統下無法直接編譯該程序了。只能找該操作系統支持的類似的功能來實現。再進一步,硬件上的生理缺陷也會為移植帶來麻煩,S3C4510B不支持MMU,在其上運行的也不提供和MMU有關的服務(其實本身可以支持MMU),于是在移植前相關的函數(比如FORK)都要被替代掉(使用VFORK)。好在uClinux和linux提供的應用接口大部分還是相同的。所以這樣的工作還可以承受。

          由上可知,如果是在各種嵌入式linux(除了uClinux以外,還有好幾種)平臺上開發,那么針對該平臺以及linux平臺上的源代碼都可以使用,但是要牢記他們之間的差異。在我的系統中需要實現網絡監控,所以想使用snmp協議,該協議和http,ftp一樣屬于應用層的成熟協議,專用于網絡管理。目前已經有一些針對該協議成熟的代碼,最有名的是ucd-snmp,不光軟件本身功能強大,可移植性也比較好,在linux,unix等平臺上都可以移植,于是決定將它移植到+uClinux平臺上(別看現在說的這么輕松,當時接這活時都有點哆嗦)。
        簡單總結一下,移植的前提是有源代碼,移植的關鍵工具是編譯器,源代碼中和硬件平臺相關的東西越少越好(這里主要指使用了匯編,或做了針對自己平臺的事,比如將指針指向特定地址然后操作),另一方面,如果該程序是基于某個操作系統(利用了操作系統提供的特殊服務,即API),要看自己的操作系統是否提供了相關服務。

          下面簡單列出一些我認為移植時需要考慮的問題:

          (1) 自己的操作系統的特點以及在當前版本下支持的特性。
        例如:uClinux不支持MMU,同樣就無法支持相應的特性。

          (2) 硬件資源。

          因為嵌入式系統資源比較緊張,硬件資源考慮必須要周全:

          (1) 軟件存儲空間的大小

          這一般要等用目標編譯器重新編譯完以后可能才會知道,所以只能大概估算,但千萬不要看這個程序在linux下只有幾十k,就認為程序很小,這是因為linux下程序多時使用動態庫,而在嵌入式系統中,很有可能是把用到的庫都鏈接在一起,所以程序的尺寸會大大增加。

          (2) 程序運行空間。

          (3) 硬件以及相應的驅動是否完備

          以上工作應該盡量做,但有時事先無法把握,只能聽天由命了(有沒有搞錯!!)

          可能有人已經要暈菜了,振奮一下大家,如果找到了好的源代碼(可移植性好),那么剩下的如要工作就是玩轉你的編譯器,只要你能順利的把源代碼用你的編譯器重新編譯一下。90%的工作就完成了(不是嗎)

        上回已經介紹了一些編譯器方面的東西,下面針對我的編譯器的具體參數來講解一些編譯器主要參數的設置。
        加入我已經有了hello.c,在x86的linux平臺下編譯鏈接一下。

          gcc –c hello.c 產生.o

          gcc –o hello hello.o 產生可執行文件,上回說過,主機編譯器參數都有環境變量保存,所以看起來很簡單。這里我故意分兩個步鄹。
        下面看一下用我的編譯器編這個程序(心臟不好的先吃藥)。

          arm-elf-gcc -Iroot/uClibc/include -msoft-float -mcpu=arm7tdmi -fomit-frame-pointer -fsigned-char -mcpu=arm7tdmi -Os –Wall -DEMBED -D_uclinux_ -c hello.c

          這只是編譯,將參數逐一講解。

          Arm-elf-gcc 是gnu的arm編譯工具

          1)Include地址:參數:-I 值:root/uClibc/include(這是在主機上我的uClinux的頭文件路徑) 用法:-I root/uClibc/include-I參數保證后面的頭文件路徑在搜索系統頭文件路徑前被搜索從而有可能替代系統的頭文件,如果有多個這樣的參數,則搜索的順序是從左到右,然后是系統的頭文件。

          2)-m 是針對CPU的選項。

          -mcpu=arm7tdmi 說明CPU類型
          -msoft-float 產生包含浮點庫的輸出
          -fsigned-char 讓char類型有符號
          -fomit-frame-pointer 對所有不需要幀指針的函數都不將其保存在寄存器中。
          3) -Os –Wall

          -Wall:所有警告都顯示

          Os:優化尺寸,該選項使能所有所有不增加尺寸的O2優化,并且進一步根據尺寸優化

          4) = -DEMBED -D_uclinux_

          -D: 將-Dmacro 后的macro定義為字符串1。

          以下是鏈接:
          arm-elf-ld -L/root/uClibc/lib -L/usr/local/gnu/arm-elf/lib -L/usr/local/gnu/lib/gcc-lib/arm-elf/3.0.1 -elf2flt –o hello /root/uClibc/lib/crt0.o /usr/local/gnu/lib/gcc-lib/arm-elf/3.0.1/crtbegin.o hello.o
        /usr/local/gnu/lib/gcc-lib/arm-elf/3.0.1/crtend.o -lc -lgcc –lc

          其中
          1) 鏈接工具: arm-elf-ld

          2) -L指明需要鏈接的庫的路徑,用法和-I一樣,自己的庫的路徑也可以在這里加入。 -L/root/uClibc/lib -L/usr/local/gnu/arm-elf/lib -L/usr/local/gnu/lib/gcc-lib/arm-elf/3.0.1

          3) –o 后面緊跟生成的最終的文件名

          4)/root/uClibc/lib/crt0.o /usr/local/gnu/lib/gcc-lib/arm-elf/3.0.1/crtbegin.o OBJECTS.o
        /usr/local/gnu/lib/gcc-lib/arm-elf/3.0.1/crtend.o

        這是需要鏈接在一起的.o文件

          5) -lc -lgcc –lc -l 后面緊跟的是需要鏈接的庫的名字,一般庫的名字是libxxx.a,使用時為-lxxx即可,不加lib和.a。還要注意位置,自己的庫文件應該加在他的庫前面。

          編譯通過后,移植就算完成了,對于比較小的源代碼都可以這樣,即先分析他的編譯選項(用到了那些頭文件,庫文件等),然后用自己的編譯器對照相應參數重新編譯一下就行了。


        上一頁 1 2 下一頁

        關鍵詞: ARM uClinux 應用程序

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 那坡县| 布拖县| 岳西县| 监利县| 读书| 安义县| 富顺县| 辛集市| 蒙阴县| 镇平县| 沙坪坝区| 西畴县| 新晃| 巴楚县| 芦溪县| 安远县| 木兰县| 通化县| 涿鹿县| 谢通门县| 广元市| 旌德县| 娱乐| 淳安县| 若羌县| 泗水县| 崇文区| 上饶县| 武清区| 永城市| 志丹县| 诏安县| 西充县| 行唐县| 应城市| 南宁市| 紫阳县| 清苑县| 大石桥市| 辽源市| 通榆县|