新聞中心

        EEPW首頁 > 嵌入式系統 > 牛人業話 > linux下ARM處理器對16位FPGA的訪問問題

        linux下ARM處理器對16位FPGA的訪問問題

        作者: 時間:2016-08-10 來源:網絡 收藏

          有一個朋友在調試arm和FPGA接口的時候碰到了一個奇怪的問題,向我尋求幫助。

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

          問題描述:

          arm使用s3c2440,fpga和arm的接口為16位,使用地址線,片選線為ncs3,操作系統使用-2.4

          測試程序為:test.c

          #define FPGA_Address 0x18000000

          int main( )

          {

          unsigned char *sp;

          unsigned short mem;

          int memfd;

          memfd=open ("/dev/mem",O_RDWR);

          sp=(unsigned char *)mmap(0,10000,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,FPGA_Address);

          *(unsigned short*)(sp+0x20c)=0x5678;

          *(unsigned short*)(sp+0x20e)=0x1234;

          munmap(sp,10000);

          close(memfd);

          }

          程序說明:因為下對不能對物理絕對地址進行訪問,需要使用mmap函數進行內存映射;

          編譯方法:arm--gcc -o test test.c

          該程序在運行的時候不能正確的向fpga的地址內部寫入16位的shor類型,經過邏輯分析儀觀察,發現在向16位的地址空間寫入0x5678的時候,實際上是向fpga內部寫了兩次,一次是:0x5656,另外一次是0x7878;同理,當寫0x1234的時候,也是分為兩次寫入的:一次是0x1212,另外一次是0x3434。

          如果將上述程序修改一下,在ads下直接編譯運行,程序能夠成功。這說明程序是沒有問題的,fpga對arm的接口時序也應該是沒有問題的。

          這讓我困惑不已。

          明明是一個16位的short類型,arm和fpga的接口也是16位的,為什么要分為兩次送入,看來是編譯器的問題,準備使用反匯編的工具看看源代碼。在ads下,可以直接看到反匯編后的代碼,在linux下,

          發現arm-linux-objdump工具也可以對目標代碼進行反匯編:用法為

          arm-linux-objdump -d -t test >aa

          使用>aa重定向將輸出信息打印到文件中:

          841c: e50b0010 str r0, [fp, -#16]

          8420: e3a03f83 mov r3, #524 ; 0x20c

          8424: e51b2010 ldr r2, [fp, -#16]

          8428: e0833002 add r3, r3, r2

          842c: e3a02078 mov r2, #120 ; 0x78

          8430: e3a01056 mov r1, #86 ; 0x56

          8434: e5c32000 strb r2, [r3]

          8438: e5c31001 strb r1, [r3, #1]

          843c: e3a03f83 mov r3, #524 ; 0x20c

          8440: e2833002 add r3, r3, #2 ; 0x2

          8444: e51b2010 ldr r2, [fp, -#16]

          8448: e0833002 add r3, r3, r2

          844c: e3a02034 mov r2, #52 ; 0x34

          8450: e3a01012 mov r1, #18 ; 0x12

          8454: e5c32000 strb r2, [r3]

          8458: e5c31001 strb r1, [r3, #1]

          通過反匯編,果然看到了使用了兩條strb的指令將一個16位的數據分為兩個8bit的數據送出;

          strb指令:從源寄存器將一個8bit的數據送到存儲器,該字節為源寄存器的低8位。

          問題找到了,如何將一個16位的數據一次性的輸出呢,在網絡搜索了一下,發現有一篇文章也談到了這個問題

          http://blog.csdn.net/liuqx/archive/2008/10/18/3094962.aspx

          只要在編譯的時候指明-march=armv4選項即可:

          使用下面的命令重新編譯:

          arm-linux-gcc -march=armv4 -o test test.c

          反匯編后得到的指令為:

          8494: e3a02c56 mov r2, #22016 ; 0x5600

          8498: e2822078 add r2, r2, #120 ; 0x78

          849c: e1a01002 mov r1, r2

          84a0: e1c310b0 strh r1, [r3]

          84a4: e3a03f83 mov r3, #524 ; 0x20c

          84a8: e2833002 add r3, r3, #2 ; 0x2

          84ac: e51b2010 ldr r2, [fp, -#16]

          84b0: e0833002 add r3, r3, r2

          84b4: e3a02c12 mov r2, #4608 ; 0x1200

          84b8: e2822034 add r2, r2, #52 ; 0x34

          84bc: e1a01002 mov r1, r2

          84c0: e1c310b0 strh r1, [r3]

          strh指令:從源寄存器將一個16bit的數據送到存儲器,該字節為源寄存器的低16位。



        關鍵詞: linux ARM

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 扶风县| 阳朔县| 铜川市| 积石山| 那曲县| 安福县| 刚察县| 开化县| 巫溪县| 海伦市| 古蔺县| 罗城| 商丘市| 简阳市| 佛坪县| 卓尼县| 静海县| 高清| 乃东县| 潞西市| 筠连县| 南召县| 凌海市| 敦煌市| 东兰县| 余干县| 和林格尔县| 建昌县| 杂多县| 怀远县| 维西| 竹溪县| 固安县| 潢川县| 称多县| 金山区| 阆中市| 刚察县| 依兰县| 肥东县| 莆田市|