九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
【轉(zhuǎn)】用openocd jtag并口小板調(diào)試qq2440
轉(zhuǎn)載:用openocd+jtag并口小板調(diào)試qq2440

   openocd是一個開源的調(diào)試工具,支持一些主流的CPU,不過目前來看,支持ARM是比較多的。其主頁為http://openocd.berlios.de/ . 目前openocd開發(fā)得還比較頻繁,我現(xiàn)在用的svnrevision是1833。當(dāng)然,如果有新的話,最好嘗試最新的revision。如果遇到了問題,比如編譯通不過之類的,可以再試試稍微舊一點的版本。
    編譯和安裝openocd的方法:
    首先從svn 上將最新的代碼checkout下來:
    svn co svn://svn.berlios.de/openocd/trunk openocd

    這會將代碼checkout到當(dāng)前目錄的openocd目錄中,然后,可以進入到openocd目錄中開始編譯和安裝:
    cd openocd
    ./bootstrap
    ./configure --enable-parport
    make
    sudo make install

   上面的./configure--enable-parport是指編譯對并口jtag轉(zhuǎn)換小板的支持,如wiggler。openocd也支持其他一些jtag轉(zhuǎn)換板,可以使用./configure --help查看。因為我只有qq2440自帶的那個并口小板,所以啟用了并口支持。


*關(guān)于gdb
 
  用gdb調(diào)試arm程序,需要一個專門針對arm的gdb,而一般x86系統(tǒng)上安裝的是針對x86的gdb,是不能用來調(diào)試arm代碼的。這同交叉編譯的概念是一致的,我們需要這樣一個gdb,他運行在我們的開發(fā)平臺上,一般是X86 PC機,但他針對的調(diào)試對象是ARM的。
   arm-linux-gdb的編譯:
   首先從ftp://ftp.gnu.org上去下載最新的gdb源碼,我下載的是gdb-6.8.tar.bz2。編譯安裝的過程是:
   tar -jxf gdb-6.8.tar.bz2
   cd gdb-6.8
   ./configure --target=arm-linux --program-prefix=arm-linux-
   make
   sudo make install

   這樣就得到了arm-linux-gdb, 不過我一般不使用makeinstall將這個arm-linux-gdb裝到系統(tǒng)里面去,而是直接運行源碼里面編譯出來的gdb可執(zhí)行文件。怎么樣方便就看你的習(xí)慣了。



*關(guān)于jtag并口小板
    
    
  其實目前的一些并口小板,絕大多數(shù)用的都是一個原理,就是直接利用PC機的并口來模擬JTAG時序。之所以會有這么多的變體,主要的差別是接法不一樣,也就是說用的并口上數(shù)據(jù)端口的不同的bit,但是本質(zhì)上是沒有區(qū)別的。
   openocd的parport驅(qū)動支持一些常見的并口小板,在openocd的src/jtag/parport.c里面,有一個這樣的數(shù)組:

static cable_t cables[] =
{
        /* name                                 tdo   trst  tms   tck  tdi   srst  o_inv i_inv init  exit  led */
        { "wiggler",                    0x80, 0x10, 0x02, 0x04, 0x08,0x01, 0x01, 0x80, 0x80, 0x80, 0x00 },
        { "wiggler2",                   0x80, 0x10, 0x02, 0x04, 0x08,0x01, 0x01, 0x80, 0x80, 0x00, 0x20 },
        { "wiggler_ntrst_inverted",
                                                        0x80, 0x10,0x02, 0x04, 0x08, 0x01, 0x11, 0x80, 0x80, 0x80, 0x00 },
        { "old_amt_wiggler",    0x80, 0x01, 0x02, 0x04, 0x08, 0x10,0x11, 0x80, 0x80, 0x80, 0x00 },
        { "arm-jtag",                   0x80, 0x01, 0x02, 0x04, 0x08,0x10, 0x01, 0x80, 0x80, 0x80, 0x00 },
        { "chameleon",                  0x80, 0x08, 0x04, 0x01, 0x02,0x10, 0x00, 0x80, 0x00, 0x00, 0x00 },
        { "dlc5",                               0x10, 0x00, 0x04, 0x02,0x01, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00 },
        { "triton",                             0x80, 0x08, 0x04, 0x01,0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 },
        { "lattice",                    0x40, 0x10, 0x04, 0x02, 0x01,0x08, 0x00, 0x00, 0x18, 0x18, 0x00 },
        { "flashlink",                  0x20, 0x10, 0x02, 0x01, 0x04,0x20, 0x30, 0x20, 0x00, 0x00, 0x00 },
/* Altium Universal JTAG cable. Set the cable to Xilinx Mode and wire totarget as follows:
        HARD TCK - Target TCK
        HARD TMS - Target TMS
        HARD TDI - Target TDI
        HARD TDO - Target TDO
        SOFT TCK - Target TRST
        SOFT TDI - Target SRST
*/
        { "altium",                     0x10, 0x20, 0x04, 0x02, 0x01,0x80, 0x00, 0x00, 0x10, 0x00, 0x08 },
        { NULL,                         0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};

  這個接口提定義了一些常見的并口小板,可以看到,無非就是將jtag接口的信號接到了不同的數(shù)據(jù)位上。我看了下,qq2440所帶的并口小板接法對應(yīng)這個chameleon。不過我對這個小板又做了點改造,具體的看下面。


*關(guān)于jtag接口

   jtag接口中,必要的信號是TMS, TCK, TDI, TDO,TRST和SRST是可選的信號,其中TRST用來復(fù)位TAP控制器,SRST用來復(fù)位目標(biāo)CPU。正是因為這兩個信號是可選的,所以造成了一些混亂。對openocd來說,最理想的情況是,它能夠分別控制TRST和SRST兩個信號。這樣的話,他就可以先設(shè)置SRST并保持住,讓目標(biāo)CPU保持在復(fù)位的狀態(tài),然后用TRST信號復(fù)位TAP控制器,最后再取消SRST信號,這樣就可以讓目標(biāo)CPU復(fù)位后就處于debug狀態(tài)。這樣的前提是,目標(biāo)CPU和jtag小板都要支持這兩個信號,S3C2440以及qq2440的設(shè)計是支持這兩個信號的,但是,附帶的那個并口小板就有些問題了。并口小板上只連接了四個必要的信號,并沒有接TRST和SRST。我對這個小板的改造就是手工補焊上這兩根線。
  并口小板上的HC541是個8通道的驅(qū)動器,起電平轉(zhuǎn)換用,TMS,TCK,TDI,TDO,四個信號占用了4個通道,另四個通道空著,我所補焊的幾根線,就是利用其中的兩個通道補上TRST和SRST??梢钥纯瓷厦娴腸ables數(shù)組的定義,其中的chameleon定義和svn上的源碼是有點區(qū)別的。trst的對應(yīng)值是0x08,srst對應(yīng)的值是0x10,這可以看出補焊線的方法:我用并口8位數(shù)據(jù)口的第4位(0x08)作trst,第5位(0x10)作srst。有機會我在把改后的照片發(fā)上來,其實很簡單的,有點電路知識的人應(yīng)該可以自己搞定。


*openocd的使用
   
  關(guān)于openocd的說明,最好的辦法當(dāng)然是看openocd的文檔。我這里所列的,是目前我所能實現(xiàn)的一些東西,當(dāng)然還有很多我也在研究中,比如如何用他來燒寫flash。
   首先openocd需要一個配置文件,配置文件的寫法很靈活,可以使用一個文件,也可以使用-f參數(shù)指定的多個文件,還可以在一個配置文件中包含另一個文件。我這里用的是最直接的辦法,在當(dāng)前目錄下放一個openocd.cfg這樣,當(dāng)運行openocd的時候,默認就會找這個配置文件,我的配置文件的內(nèi)容為:


telnet_port     4000
gdb_port        3000
interface parport
parport_port 0x378
parport_cable chameleon
jtag_speed 0

source [find target/samsung_s3c2440.cfg]

$_TARGETNAME configure -event reset-init {
        mww 0x48000000 0x22111112
        mww 0x48000004 0x00000700
        mww 0x48000008 0x00000700
        mww 0x4800000c 0x00000700
        mww 0x48000010 0x00000700
        mww 0x48000014 0x00000700
        mww 0x48000018 0x00000700
        mww 0x4800001c 0x00018009
        mww 0x48000020 0x00018009
        mww 0x48000024 0x008e04eb
        mww 0x48000028 0x000000b2
        mww 0x4800002c 0x00000030
        mww 0x48000030 0x00000030
}

    前兩行指定了telnet 和gdb連接時所使用的端口,然后就指定了并口的地址和并口小板的類型。source用來包含另一個文件,find的默認查找路徑是/usr/local/lib/openocd。最后的reset-init定義了一個event,當(dāng)系統(tǒng)復(fù)位的時候,會執(zhí)行這些命令,以上這些命令用來初始化SDRAM控制器。

    準(zhǔn)備好配置文件后,可以在當(dāng)前目錄下運行openocd,注意要使用root權(quán)限,并確保jtag已經(jīng)連接好,開發(fā)板電源已經(jīng)打開。

fox@NA ~ $ sudo openocd
Open On-Chip Debugger 0.2.0-in-development (2009-05-19-10:39) svn:1833M


BUGS? Read http://svn.berlios.de/svnroot/repos/openocd/trunk/BUGS


$URL: svn://svn.berlios.de/openocd/trunk/src/openocd.c $
jtag_speed: 0
Info : JTAG tap: s3c2440.cpu tap/device found: 0x0032409d (Manufacturer:0x04e, Part: 0x0324, Version: 0x0)
Info : JTAG Tap/device matched
Warn : no tcl port specified, using default port 6666


    如果提示 “Info : JTAG tap: s3c2440.cpu tap/device found: 0x0032409d(Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)”,表示openocd已經(jīng)通過jtag連接上了目標(biāo)CPU,我們的任務(wù)也完成了一半,注意openocd會停在這個地方,是正常的,所以下面的操作要在另一個終端窗口里面進行。
    然后就可以用telnet連上openocd了:

fox@NA ~ $ telnet 127.0.0.1 4000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Open On-Chip Debugger
>

  在">"提示符后就可以輸入openocd的命令了,還是那句話,看openocd的文檔。輸入help也會出一個命令的幫助列表出來。常用的命令:

   reset [halt|init|run]          復(fù)位目標(biāo)CPU,復(fù)位后可以使halt,init或run。halt標(biāo)示立即掛起,init表示要運行init腳本,run標(biāo)示復(fù)位后不掛起CPU,讓CPU繼續(xù)運行。
   halt                           掛起目標(biāo)板的CPU。
   resume                         恢復(fù)CPU的運行
   step                           單步
   mdb/mdh/mdw              顯示內(nèi)存(字節(jié),半字,字)
   mwb/mwh/mww                  寫內(nèi)存(字節(jié),半字,字)
   reg                            顯示寄存器
   load_image                     載入數(shù)據(jù)到內(nèi)存中指定的地方


  上面的mdb/mdh/mdw/mwb/mwh/mww這些指令如果在CPU開啟了MMU的狀態(tài)下,后面的地址會被解釋為虛擬地址。如果想訪問物理地址,可以使用對應(yīng)的 arm920t mdb_phys, arm920t_mdh_phys等等,詳見help。



*用arm-linux-gdb配合openocd來調(diào)試程序
   
   目前,我對gdb的使用還不是很熟悉,基本上是摸著石頭過河的狀況。因此下面肯定有很多地方顯得比較笨拙,哎,這個只能在學(xué)習(xí)中慢慢改進了。
   首先啟動arm-linux-gdb,直接運行就可以,出現(xiàn)提示符后,可以在gdb里面連接上openocd:

GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "showcopying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu--target=arm-linux".
(gdb) target remote 127.0.0.1:3000
Remote debugging using 127.0.0.1:3000
0x00000038 in ?? ()

  還是按照我的習(xí)慣,先從最簡單的開始。這里就不調(diào)試什么kernel啊,從最簡單的裸奔程序開始,首先,來個只有匯編的。作為例子,下面這個簡單得不能再簡單了:

.text
.global _start
_start:
        mov r0, #0
        mov r1, #0
        mov r2, #0

loop:
        b loop

   文件保存為test1.S,注意是大寫的“S”, 然后用arm-linux-gcc進行編譯和連接:

   fox@NA ~ $ arm-linux-gcc -g -c test1.S -o test1.o
   fox@NA ~ $ arm-linux-ld -g -Ttext 0x30000000 test1.o -o test1.elf


   上面用 -Ttext指定了代碼的加載地址,0x30000000就是qq2440上SDRAM映射的地址。
  把編譯出來的目標(biāo)文件加載到SDRAM中有兩個方法,一個是用openocd的load_image命令,不過load_image命令不認識elf格式,所以要用objcopy將.text節(jié)從elf文件里面取出來,然后在用openocd的load_image將其加載到指定的地方,也就是0x30000000。
   還有一個方法,我一般在gdb里面直接載入elf文件,elf里面已經(jīng)包含了載入地址,入口點等信息,直接用gdb的load命令就可以了,如下:

(gdb) load test1.elf
Loading section .text, size 0x10 lma 0x30000000
Start address 0x30000000, load size 16
Transfer rate: 1 KB/sec, 16 bytes/write.
(gdb) file test1.elf
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Load new symbol table from "/home/fox/test1.elf"? (y or n) y
Reading symbols from /home/fox/test1.elf...done.
(gdb) i r
r0             0x0      0
r1             0x53000000       1392508928
r2             0x6      6
r3             0x50000010       1342177296
r4             0x0      0
r5             0x0      0
r6             0x0      0
r7             0x0      0
r8             0x594    1428
r9             0xf673eefd       4134792957
r10            0x33f12fb4       871444404
r11            0x0      0
r12            0x2      2
sp             0x33defe90       0x33defe90
lr             0x594    1428
pc             0x30000000       0x30000000 <_start>
fps            0x0      0
cpsr           0x6000005f       1610612831

    file指令是用載入符號和調(diào)試信息,后面用 ir來顯示寄存器信息,可以看到pc都已經(jīng)設(shè)置好了。用n命令就可以單步調(diào)試了,不過gdb我用的不太熟,還要摸索。



*用arm-linux-gdb調(diào)試c代碼

  如果要編寫調(diào)試一段裸奔的c代碼,其實很簡單,對于c代碼的運行,只需要一個條件,就是要準(zhǔn)備好棧。一般做法是寫一小段匯編引導(dǎo)程序,設(shè)置好棧之后,再跳轉(zhuǎn)到c代碼里面。匯編代碼test2.S如下:

.text
.global _start
_start:
        ldr sp, =0x34000000
        bl mymain
loop:
        b loop


    上面的  ldr sp, =0x34000000 就是將棧指針設(shè)置在64MSDRAM空間的最后,因為棧是向內(nèi)存地址小的方向增長的。bl用來跳轉(zhuǎn)到c代碼中, test2.c如下:

#define GPBCON  (*(unsigned long*)0x56000010)
#define GPBDAT  (*(unsigned long*)0x56000014)
#define GPBUP   (*(unsigned long*)0x56000018)

int mymain()
{
        volatile unsigned long v = GPBCON;
        v &= 0xFFFc03FF;
        v |= 0x00015400;
        GPBCON = v;


        v = GPBDAT;
        v |= 0x000001e0;
        GPBDAT = v;     /* turn off all LEDs */

        v &= ~0x000001e0;
        GPBDAT = v;    /* turn on all LEDs */

        return 0;
}


    編譯過程
    arm-linux-gcc -g -c test2.S -o test2.o
    arm-linux-gcc -g -c test2.c -o test2_main.o
    arm-linux-ld -g -Ttext 0x30000000 test2.o test2_main.o -o test2.elf

    在gdb環(huán)境中載入并調(diào)試的過程為:

GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "showcopying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu--target=arm-linux".
(gdb) target remote 127.0.0.1:3000
Remote debugging using 127.0.0.1:3000
0x3000009c in ?? ()
(gdb) load test2.elf
Loading section .text, size 0xa8 lma 0x30000000
Start address 0x30000000, load size 168
Transfer rate: 4 KB/sec, 168 bytes/write.
(gdb) file test2.elf
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from /home/fox/test2.elf...done.
(gdb) i r
r0             0x0      0
r1             0x104    260
r2             0x61e    1566
r3             0x56000014       1442840596
r4             0x20000  131072
r5             0x33f00000       871366656
r6             0x0      0
r7             0x0      0
r8             0x594    1428
r9             0xf673eefd       4134792957
r10            0xc8     200
r11            0x33fffffc       872415228
r12            0x34000000       872415232
sp             0x33ffffec       0x33ffffec
lr             0x30000008       805306376
pc             0x30000000       0x30000000 <_start>
fps            0x0      0
cpsr           0x800000d3       2147483859
Current language:  auto; currently asm
(gdb) b mymain
Breakpoint 1 at 0x3000001c: file test2.c, line 7.
(gdb) c
Continuing.

Breakpoint 1, mymain () at test2.c:7
7               volatile unsigned long v = GPBCON;
Current language:  auto; currently c
(gdb) n
8               v &= 0xFFFc03FF;
(gdb) n
9               v |= 0x00015400;
(gdb) n
10              GPBCON = v;
(gdb) n
13              v = GPBDAT;
(gdb) n
14              v |= 0x000001e0;
(gdb) n
15              GPBDAT = v;     /* turn off all LEDs */
(gdb) n
17              v &= ~0x000001e0;
(gdb) n
18              GPBDAT = v;    /* turn on all LEDs */
(gdb) n
20              return 0;
(gdb)


   可以看到,可以用b設(shè)置斷點,用n進行源碼級的調(diào)試,單步跟蹤,也能觀察到開發(fā)板上的所有LED先熄滅,再點亮。關(guān)于gdb的更多操作,也正在學(xué)習(xí)中。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
【轉(zhuǎn)】ubuntu linux下openocd gdb-insight 用Jlink調(diào)試arm程序
OpenJTAG+Eclipse 3.5+GDB+Mini2440圖文教程
Mini2440學(xué)習(xí)筆記(一)——Start
燒腦作品:如何對西數(shù)硬盤固件進行逆向分析?
Windows 下OpenJtag+OpenOCD+Eclipse 集成環(huán)境安裝
OpenOCD是一個開源的JTAG上位機程序
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服