新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM開發過程中最最需要注意的問題

        ARM開發過程中最最需要注意的問題

        作者: 時間:2016-11-11 來源:網絡 收藏
        平時大家接觸最多的可能是X86平臺,在這種系統上寫程序幾乎不需要考慮太多問題,但ARM上就不一樣了,最常見也最容易被忽略的問題可能就是字節的對齊,即使像我這樣有六七年程序開發經驗的才手也時常難于提防,最近就有一個BUG,花了一天時間最終發現是對齊引發的,在此與大家分享,但愿大家能夠注意到。

          我在EBOOT中讀取存在HARD DISK上的nk.bin文件,從而從HARD DISK上LOAD WINCE系統,在這個過程中總是有check sum錯誤,但從ethernet下載時不會有錯,所以問題應該還是在我加的這部分代碼上,而且同樣的代碼在PC上能正常運行。經過檢查代碼的邏輯關系是正確的。接著我在出錯時將那些數據全部用調試信息打出來,發現從文件開始算起第4096個字節被丟掉了,而其它的字節都是對的。初步判斷是對齊引發的問題,所以去查每一個BUFFER,最終發現是在讀取硬盤數據時BUFFERR并沒有按雙字節對齊,而硬盤以16BIT讀取數據,而引發了錯誤。

        實際上,這類問題在ARM系統上很常見,讓人防不勝防,以下是我的一些例子。

        1,解析數據流時應該時刻注意。如果需要把一個數據流(BUFFER)轉化成結構進行取值,就應該把這個結構定義為按字節存取.考慮如下結構:

        struct a{

        char a;
        short b;
        long c;
        };
        如果某個數據流中包含這樣的結構,而且我們要直接將數據流的指針轉化成該結構的指針,然后直接取結構成員的值,我們就應該將這個結構定義成按字節訪問,即將其夾在語句
        #pragma pack(push,1)
        ...

        #pragma pack(pop)
        之中。如果我們不這樣做,編譯器會將成員b的地址對齊到short指針的地址,即在a之后加上一個char即8位的成員,將C對齊到LONG,即在B之后再加一個char成員。如此一來,成員B和成員C就得不到正確的值了。

        如果我們定義一個普通的結構用來存放一些數據,則不用定義成按字節存取,編譯器會加上一些占位成員,但并不會影響程序的運行。從這個意義上講,在ARM中,將結構成員定義成CHAR和SHORT來節約內存是沒有意義的。

        一個典型的例子就文件系統的驅動程序,文件是以一些已經定義好的結構存放在存儲介質上的,它們被讀取到一個BUFFER中,而具體取某個文件、目錄結構時,我們會將地址轉化成結構而讀取其中的值。


        2,訪問外設時。
        例如,磁盤驅動通常以16BIT的方式存取數據,即每次存取兩個字節,這樣就要求傳給它的BUFFER是雙字節對齊的,驅動程序應該至上層傳來的指針做出正確的處理以保證數據的正確性。


        3.有時,我們沒有將數據流指針轉化為結構指針取值,但如果我們讀取的是雙字節或者是四字節的數據,同樣需要注意對齊的問題,例如,如果從一個BUFFER的偏移10處讀取一個四字節值,則實際得到的值是偏移8處的
        地址上的DWORD值。
        如何改wince裝驅動
        前邊說了如何在開發版上裝wince.現在我手上有一個usb的攝像頭,為了要他能在開發板上使用,我得給他裝上驅動.產家提供了dll和需要修改注冊表的說明.下邊說下步驟,

        打開之前做wince內核定制燒寫的工程,把驅動文件,假設叫A.dll, 拷貝到工程目錄下,D:WINCE420PUBLICwince工程RelDirSAMSUNG_SMDK2410_ARMV4Release 這個下邊.然后在pb工作環境中,找到ParameterView區,展開樹型列表,找到project.bib和project.reg兩個文件,要對他們進行修改.

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

        修改 project.bib 添加 A.dll $(_FLATRELEASEDIR)A.dll NK SH 這樣一行 .

        將產家提供的reg文件里的內容copy到project.reg里.

        以上做好后,因為我是pb4.2的環境,這時候點bulide菜單下的make image.等完成后,再重新燒寫一遍鏡像文件(nk) 到開發板上就可以了。注意我這里選make image而不是build platform。如果選build platform會抱錯的,說找不到dll等等幾個錯誤。我買的周立功的一本書上是在pb5.0環境下,到這一步時說 在菜單buuild os中,不選clean before building。然后再選擇sysgen重新編譯生成新的wince映像

        物理地址映射方法分為兩種,一種靜態映射另一種為動態映射。在OEMAddressTable中定義了物理地址與虛擬地址的映射關系屬于靜態映射,用VirtualCopy映射屬于動態映射,采用哪種辦法都可以。問題中提到的屬于靜態映射,2440的BSP在map.a文件中定義了IIC控制寄存器的物理起始地址和對應的虛擬地址如下:
        DCD 0x91400000, 0x54000000, 1 ;
        在OEMAddressTable中定義的虛擬地址范圍在0x8000 0000—0x9FFF FFFF,這部分可緩存,適合內核程序和應用程序使用,同時WINCE內核在0xA000 0000—0xBFFF FFFF中映射了另一份,指向了同樣的物理地址,這部分不可緩存,適合驅動程序使用。三星ARM處理器帶有L1級高速緩存,可緩存會提高執行效率。對于特殊的設備寄存器適合映射到不可緩存的虛擬地址。
        當驅動程序調用VirtualCopy對0xB1400000地址讀寫時,WINCE自動將這個地址減去0x2000 0000,也就是0x91400000,對應的物理地址就是0x54000000,也就是IIC控制寄存器的物理起始地址。




        關鍵詞: ARM開發過

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 周至县| 兴隆县| 盐池县| 洛宁县| 南通市| 乌什县| 河曲县| 德令哈市| 陈巴尔虎旗| 嘉善县| 凭祥市| 宁海县| 麻江县| 拜城县| 临漳县| 高邮市| 崇明县| 沙田区| 泸水县| 洪湖市| 苍梧县| 禹城市| 仙游县| 山西省| 正定县| 山丹县| 开封县| 新源县| 定南县| 竹北市| 莒南县| 个旧市| 青岛市| 都兰县| 宁安市| 理塘县| 馆陶县| 肃宁县| 永吉县| 横峰县| 莱芜市|