[計算機硬件及網(wǎng)絡]44B0x的BSP是如何調(diào)成的_第1頁
[計算機硬件及網(wǎng)絡]44B0x的BSP是如何調(diào)成的_第2頁
[計算機硬件及網(wǎng)絡]44B0x的BSP是如何調(diào)成的_第3頁
[計算機硬件及網(wǎng)絡]44B0x的BSP是如何調(diào)成的_第4頁
[計算機硬件及網(wǎng)絡]44B0x的BSP是如何調(diào)成的_第5頁
已閱讀5頁,還剩39頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、打造你的44b0 bsp-概述1.vxworks bsp概述-vxworks板級支持包(bsp)是為vxworks操作系統(tǒng)與硬件平臺之間提供一個接口的軟件包,它可以使vxworks運行于特定的硬件平臺,包含了一系列的硬件相關的函數(shù):1)目標板硬件初始化 內(nèi)存控制器初始化 堆棧初始化 外圍設備初始化(io、interrupt)2)異常向量處理3)cache操作4)硬件設備的底層驅(qū)動 定時器驅(qū)動 串口驅(qū)動 end驅(qū)動 flash驅(qū)動 lcd驅(qū)動本文檔說明了vxworks bsp for s3c44b0開發(fā)板(簡稱bsp)的開發(fā)過程。vxworks的bsp應和wrs(windriver system

2、)的產(chǎn)品兼容,因而最好有一個可參考的模板,在此基礎上修改bsp相關的文件。我參考的模板為windriver for 4510 bsp wrsbcarm7,這些修改主要有:系統(tǒng)必需1) cpu寄存器定義2) 板級配置定義3) 系統(tǒng)配置文件4) 啟動代碼5) 中斷處理模塊6) 定時器驅(qū)動模塊7) 串口驅(qū)動模塊可選模塊8) end驅(qū)動模塊9) tffs驅(qū)動模塊10) lcd驅(qū)動模塊1.2 創(chuàng)建bsp步驟-1) 拷貝模板bsp至targetconfigs3c44b0目錄下2) 為清晰起見cpu相關的文件應改名,并修改相關文件3) 編譯調(diào)試1.3 bootrom啟動流程-1) 上電reset系統(tǒng)上電,c

3、pu從0x0地址開始執(zhí)行2) rominit(rominit.s)rominit在文件在文件rominit.s中。它是系統(tǒng)運行的入口,所以對于系統(tǒng)能否運行至關重要。它實現(xiàn)初始化cpu、判斷啟動類型、配置內(nèi)存和外圍設備的讀寫時序、設置堆棧指針等。在bsp中無法進行調(diào)試嗎?很多大蝦推薦通過閃燈來判斷代碼執(zhí)行正確與否。對于44b0,由于gpio眾多,配置也較為復雜,且點燈只能大致知道故障位置而不能知道ram和cpu寄存器的具體值,導致調(diào)試的難度很大,后面我會介紹一種調(diào)試方法,只要你有jtag下載線就能使用adw調(diào)試,且不需燒寫flash。rominit在函數(shù)結(jié)尾跳入romstart。3) romst

4、art(bootinit.c)romstart在bootinit.c文件中。它是系統(tǒng)運行的第一個c函數(shù)。這一部分是vxworks提供的標準程序一般不需改動。該函數(shù)是c的入口函數(shù),由rominit調(diào)用,主要完成清內(nèi)存,將rom中的程序拷貝到ram,解壓并跳至解壓后的程序處運行。4) usrinit(bootconfig.c)usrinit在bootconfig.c文件中。它主要是實現(xiàn)硬件的初始化、cache初始化、異常向量初始化、內(nèi)核初始化等。此部分代碼都是在關閉中斷狀態(tài)下,多任務系統(tǒng)還沒啟動時執(zhí)行的,故而只能進行初始化工作,不能調(diào)用延時、等待或和中斷相關的函數(shù),如串口打印只能用poolmode

5、。之后多任務系統(tǒng)啟動,并運行第一個任務usrroot。5) usrroot(bootconfig.c)usrroot在bootconfig.c文件中。它主要是實現(xiàn)vxworks文件的下載,并且跳轉(zhuǎn)到下載的vxworks image的入口地址,從而啟動操作系統(tǒng)。它初始化tty串口設備,根據(jù)boot_line加載相應的模塊,創(chuàng)建交互shell,啟動image下載。獨門秘笈bsp調(diào)試-進行過bsp開發(fā)的兄弟,一定有過痛苦的經(jīng)歷,那就是明明是一小段代碼,卻怎么也得不到正確的結(jié)果,點燈也只能知道死在哪里,你要問到底出了什么事,對不起你問我我問誰?而且bsp調(diào)試只能不停的修改代碼編譯燒寫運行調(diào)試再修改再燒

6、寫這問題也折磨了我好久,最后我找到了一個獨門秘笈,才得以順利的搞定bsp??吹綁由希约敖o我發(fā)email的很多迷茫兄弟的痛苦狀,不敢私藏1) 修改bsp config.h和makefile的rom_base_adrs為ram_high_adrs2) 編譯bootrom為bootrom_uncmp3) 打開adw,加載image,就可以進行仿真或在線調(diào)試了這樣做的原理是bootrom_uncmp是被拷貝到ram的ram_high_adrs處,如果我們編譯時直接定位于ram_high_adrs,則image的地址就和拷貝的地址一致。而rominit是pic的(位置無關的),它可以在任何地址運行,

7、所以這就和從rom啟動情況一樣,自然可以運行啦!eking 20040416欲知后事,且聽下回分解44b0x的bsp是如何調(diào)成的(1)工欲善其事, 必先利其器一.制作44b0x的vxworks的bsp需要以下硬件和軟件的準備1. 44b0x的開發(fā)板, 可選擇的很多, 這里就不用說了.2. tornado ide 2.0/2.2, 我用的是2.2, 注意的是2.2只能安裝在windows 2k/xp下, 生成的文件是elf格式, 2.0可以在98下安裝, 生成的文件是coff格式, 2.0如果補充幾個文件, 也可以下載2.2生成的elf格式vxworks3. ice或者wiggler, 我用的是

8、wiggler, 魚的wiggler就不錯,51eda的板子隨板帶一個jtag小板,簡單jtag, 支持sdt251,也可以用4. source insight, 編寫代碼5. ultraedit, 查看二進制文件, 運行bat文件6. beyond compare, 版本文件比較(修改了文件代碼, 突然發(fā)現(xiàn)不能工作的時候, 就需要它了)7. sdt251, 實際上只需要adw8. 2k/xp下的jtag.exe, 可以到51eda下載9. 燒寫軟件 flashpgm或者fluted, flashp(推薦使用, 不用換線), 使用flashpgm+wiggler燒寫速度快, 但每次都要換jta

9、g的連接線, 太麻煩; 不如用flashp, 速度還可以, 燒一個bootrom_uncmp.bin幾秒左右10. 交叉串口線2條, 就是5<->5, 2<->3, 3<->2的那種11. 參考bsp, 用wrsbcarm712. manual, 44b0x的manual, demo代碼(samsung網(wǎng)站下載), vxworks programmer manual, bspkit, tornado reference13. 其他, (有很多內(nèi)容可以參考借鑒), (信息查找) 碰到我困惑的問題, 基本上就是這2個工具. 特別是google.目標:實現(xiàn)boot

10、rom和tsfs加載vxworks映像, 使用com2二.千里之行, 始于足下在targetconfig目錄下, 建一文件夾, 名字隨你便, 我的是44xbsp, 把wrsbcarm7目錄下文件全拷貝過來, 再把all文件夾也拷貝過來, 刪除或者注釋掉makefile中的mach_extra = sngks32cend.oextra_define修改為extra_define = -o0 -wall -wcomment -dcpu_7tdmi -darmmmu=armmmu_none -darmcache=armcache_none文件名可以先不用改sysled.c 和syslcd.c基本上不

11、需要下面就是具體的修改工作了, 定義好所以的44b0x的寄存器宏, 注意看手冊, 按照手冊的要求做, 除了串口, rtc的某些寄存器外需要是char類型訪問的, 其他都是32位訪問的性子急的, 可能1天不到就改好了, 然后興沖沖燒到flash, 打開超級終端, 設置好串口, 然后復位板子, 怎么樣?啥也沒有(跟我一樣), 如果一下子什么都出來, 看到wdb: ready.了, 那真的是水平又高又幸運了我用了差不多一個星期(不是每天都做)把這些文件基本上改好, 編譯通過支持tsfs加載需要修改config.h#ifndef include_tsfs_boot#define include_tsf

12、s_boot#endif /* tsfs */#undef num_tty#define num_tty n_sio_channels /* 2 serial ports */#undef console_tty#define console_tty 0#undef console_baud_rate#define console_baud_rate 38400/* tsfs */#ifdef include_tsfs_boot#undef console_tty#define console_tty 0#undef wdb_tty_channel#define wdb_tty_channel

13、 1#undef wdb_comm_type#define wdb_comm_type wdb_comm_serial#undef wdb_tty_baud#define wdb_tty_baud 38400 /* 115200 */#define wdb_tty_dev_name "/tyco/1"#endif#define force_default_boot_line#define default_boot_line "tsfs(0,0)host:vxworks"undef一切涉及到flash, lcd, led, end, network的宏#d

14、efine rom_base_adrs 0x00000000 /* base of flash/eprom 16 mb */#define rom_text_adrs 0x00000000 /* code start addr in rom */#define rom_size 0x00100000 /* size of rom holding vxworks 512k */#define rom_copy_size rom_size#define rom_size_total 0x00200000 /* total size of rom 2mb */#define ram_low_adrs

15、 0x0c001000 /* vxworks image entry point */#define ram_high_adrs 0x0c500000 /* ram address for rom boot */注意要和makefile一致忘了一句, makefile要增加一句config_all的宏,位置是#mach_extra = sngks32cend.omach_extra = #config_all = c:tornado2.2targetconfig44xbspallconfig_all = all44b0x的bsp是如何調(diào)成的(2)三.不入虎穴,焉得虎子大家都知道44b0x是不能

16、remap的, 就是它的flash空間是固定死的(除非硬件上做設計修改,論壇上有很多貼討論這個問題), 而vxworks是把異常向量都要放置到地址0處, 也就是flash地址開始的地方, 參考下圖vxworks的memory映像(或者參考file:/c:/tornado2.2/docs/vxworks/arm/arm.html#98246)vxworks system memory layout (arm) 此主題相關圖片如下:通常情況下, local_mem_local_adrs在bsp中定義為0, 異常向量放置在這里可以減少異常處理的延遲時間(sdram或者sram的讀取要比rom快),

17、還有其他好處, 動態(tài)和靈活等arm的體系結(jié)構(gòu)規(guī)定在異常發(fā)生時, 要從0地址開始處取相應的處理指令, 因此要對rominit.s文件的開始處進行修改(因為如果沒有remap, rominit.s是位于地址0處的)因此rominit.s開始幾句變成了這樣_arm_function(rominit)_rominit:     b       cold    b       _romundef  

18、0; b       _romswi    b       _romprefetch    b       _romdataabort    b       _romreserved       &#

19、160;      /* _romreserved */    b       _romirq    b       _romfiq              /* _romfiq     */col

20、d:    mov    r0, #boot_cold    /* fall through to warm boot entry */warm:    b    start我看有人用bootloader加載vxworks, 如果44b0x是可以remap的, 應該還沒有問題, vxworks可以自己把異常向量放置到地址0處; 但因為44b0x不能remap, 在bootloader的地址0處開始要放異常向量, 怎么和vxworks的處理函數(shù)我還

21、沒考慮過. 畢竟, vxworks和bootrom的關系還是比較緊密的, 而且vxworks可以是loadable和resident的.因為不知道vxworks是具體如何放置入口函數(shù)的, 因此只能提供調(diào)試的方法來把它找出來.使用ultraedit的advanced->dos command-, 輸入44xbsp.bat, working directory設置為bsp文件所在的目錄, 見下圖 此主題相關圖片如下:生成bootrom_uncmp.bin文件44xbsp.bat的文件內(nèi)容為rem command line build environmentsset wind_hos

22、t_type=x86-win32set wind_base=c:tornado2.2set path=%wind_base%host%wind_host_type%bin;%path%rem diab toolchain additionsset diablib=%wind_base%hostdiabset path=%diablib%win32bin;%path%上面的內(nèi)容可以從torvars.bat中copymake cleanmake bootrom_uncmp.bin把這個bootrom_uncmp.bin燒到flash中, 不管三七二十一, 先復位板子再說, 正常情況下, 超級終端啥

23、也沒有, 死水一潭(實際上都沒有必要去看超級終端輸出, 還差著多呢)修改config.h和makefile, 把ram_high_adrs的定義改一下, 如#define ram_high_adrs        0x0c100000因為我要用adw進行ram調(diào)試, 而已經(jīng)燒到flash的bootrom_uncmp在boot的時候有一個copy的過程, 如果還是這個地址不變的話, 會把正在調(diào)試的區(qū)域給覆蓋掉, 所以要避開, 這樣用adw就可以dowload boot_uncmp(注意不是bin文件,是elf格式的那個)進行調(diào)

24、試了下面的工作就是用adw一步一步地跟蹤調(diào)試了, 這個過程需要耐心和細致. 在執(zhí)行完romstart的copylongs后(這個函數(shù)可以step, 不用step in了), 進入usrinit函數(shù)(在bootconfig.c文件中, 不是usrconfig.c中的那個), 進入usrinit后會清bss段, 設置啟動類型, 然后進入excvecinit (), 在其前面的intvecbaseset (funcptr *) vec_base_adrs); /* set vector base table */對arm體系來說,什么作用也沒有step in進入excvecinit(), 這里在每個

25、步驟執(zhí)行后就要注意觀察各個寄存器的內(nèi)容了對那些只靠點燈來調(diào)試的人來說由于不能觀察到這些, 所以很難了解excvecinit究竟干了什么, 盡管網(wǎng)上有vxworks的core source code, 但那是for x86的, 只能參考那些和cpu無關部分的代碼, 在這里還用不上使用命令來觀察boorom_uncmp的匯編代碼, 我也把它做成了bat文件, 內(nèi)容如下set wind_host_type=x86-win32 set wind_base=c:tornado2.2 set path=c:tornado2.2hostx86-win32bin;c:tclbin;c:program file

26、sarmadsv1_2bin;c:windowssystem32;c:windows;c:windowssystem32wbem;c:program filesexecutive softwarediskeeper;c:arm251bin;c:tornado2.2hostx86-win32binvslickwin;c:flashfxp;c:program filesultraedit rem diab toolchain additions set diablib=c:tornado2.2hostdiab set path=c:tornado2.2hostdiabwin32bin;c:torn

27、ado2.2hostx86-win32bin;c:tclbin;c:program filesarmadsv1_2bin;c:windowssystem32;c:windows;c:windowssystem32wbem;c:program filesexecutive softwarediskeeper;c:arm251bin;c:tornado2.2hostx86-win32binvslickwin;c:flashfxp;c:program filesultraedit objdumparm -sd bootrom_uncmp使用ultraedit的查找功能, 找到excvecinit,

28、內(nèi)容如下0c506404 <excvecinit>: c506404: e92d4800  stmdb sp!, r11, lr c506408: e24dd008  sub sp, sp, #8 ; 0x8 c50640c: ebffff8e  bl c50624c <arminitexceptionmodes> c506410: e59fb4d4  ldr r11, pc, #1236 ; c5068ec <$d> <- r11= excentertbl  c

29、506414: e3a01005  mov r1, #5 ; 0x5 <- 5次循環(huán) c506418: e59f04d0  ldr r0, pc, #1232 ; c5068f0 <$d+0x4><- r0=0xe59ff0f4, 這條指令的反匯編結(jié)果是 ldr pc, pc, 0xf4, 實際上是(指令后的pc)=0x8+0xf4+(當前的pc),如果把這個指令放在0x4的位置, 然后反匯編一下, 會發(fā)現(xiàn)它實際上要跳轉(zhuǎn)到0x8+0xf4+0x4=0x100處,  c50641c: e24bb008  sub r11,

30、r11, #8 ; 0x8 <- 下一個異常向量 c506420: e59b3008  ldr r3, r11, #8 c506424: e2511001  subs r1, r1, #1 ; 0x1 c506428: e5830000  str r0, r3 <- 把r0, 也是指令0xe59ff0f4放置到0x4處, 也就是, 如果有0x4(undef)的異常發(fā)生時, 它要跳轉(zhuǎn)到0x100處 c50642c: e59bc008  ldr r12, r11, #8 c506430: e59b

31、300c  ldr r3, r11, #12 <- r3=second element of excentertbl, r3=0c5062f4, 也就是excenterundef, c506434: e28bb008  add r11, r11, #8 ; 0x8 c506438: e58c30fc  str r3, r12, #252 <- 把excenterundef的入口指針放到 0x100處, 完成一個異常向量的初始化了, 再看一下前面的圖, exception pointer的位置在哪里?就是0x100,下面再進行4次循環(huán)

32、完成其他異常向量的初始化 c50643c: 1afffff7  bne c506420 <excvecinit+0x1c> c506440: e3a0c000  mov r12, #0 ; 0x0 c506444: e59f34a8  ldr r3, pc, #1192 ; c5068f4 <$d+0x8> c506448: e58c3000  str r3, r12 c50644c: e59fc4a4  ldr r12, pc, #1188 ; c5068f8 <

33、$d+0xc> c506450: e59cb01c  ldr r11, r12, #28 c506454: e35b0000  cmp r11, #0 ; 0x0 c506458: 0a000003  beq c50646c <excvecinit+0x68> c50645c: e3a00000  mov r0, #0 ; 0x0 c506460: e3a0101c  mov r1, #28 ; 0x1c c506464: e1a0e00f  mov lr,

34、 pc c506468: e1a0f00b  mov pc, r11 c50646c: e59f3488  ldr r3, pc, #1160 ; c5068fc <$d+0x10> <- r3 =0x0c506d98  =<excinthandle> c506470: e59fc488  ldr r12, pc, #1160 ; c506900 <$d+0x14> <- r12 = 0x0c52adc4= _func_armirqhandler c506474: e

35、58c3000  str r3, r12 <- _func_armirqhandler= excinthandle c506478: e3a00000  mov r0, #0 ; 0x0 c50647c: e28dd008  add sp, sp, #8 ; 0x8 c506480: e8bd8800  ldmia sp!, r11, pc0c5259c8 <excentertbl>: c5259c8: 00000004  andeq r0, r0, r4  

36、0;   <- 異常向量4 c5259cc: 0c5062f4  mrrceq 2, 15, r6, r0, cr4 <- excenterundef  c5259d0: 00000008  andeq r0, r0, r8 c5259d4: 0c506298  mrrceq 2, 9, r6, r0, cr8 <- excenterswi c5259d8: 0000000c  andeq r0, r0, r12 c5259dc: 0c5062e4  mrr

37、ceq 2, 14, r6, r0, cr4 <- excenterprefetchabort  c5259e0: 00000010  andeq r0, r0, r0, lsl r0 c5259e4: 0c5062d4  mrrceq 2, 13, r6, r0, cr4 <- excenterdataabort c5259e8: 00000018  andeq r0, r0, r8, lsl r0 c5259ec: 0c506c34  mrrceq 12, 3, r6, r0, cr4 <-

38、intentexcentertbl就是一個異常向量和對應處理函數(shù)入口的數(shù)據(jù)結(jié)構(gòu)慢慢地一步一步的跟蹤, 可以得到如下的大致結(jié)果, 我寫成偽代碼了exevecinit(void)  call arminitexceptionmodes /* init stack of different modes */ set tbl to excentertbl for (i=0;i<5;i+ )  依次設置各個異常向量的處理函數(shù) _func_armirqhandler= excinthandle return ok; arminitexcep

39、tionmodes都干些什么呢0c50624c <arminitexceptionmodes>: c50624c: e10f0000  mrs r0, cpsr c506250: e3c0103f  bic r1, r0, #63 ; 0x3f c506254: e3811080  orr r1, r1, #128 ; 0x80 c506258: e381201b  orr r2, r1, #27 ; 0x1b c50625c: e129f002  msr cpsr_fc, r2&#

40、160;c506260: e51fd02c  ldr sp, pc, #-44 ; c50623c <$a> c506264: e3812017  orr r2, r1, #23 ; 0x17 c506268: e129f002  msr cpsr_fc, r2 c50626c: e51fd034  ldr sp, pc, #-52 ; c506240 <l$_abortsavearea> c506270: e3812012  orr r2, r1, #18 ; 0x12 

41、;c506274: e129f002  msr cpsr_fc, r2 c506278: e51fd038  ldr sp, pc, #-56 ; c506248 <l$_irqstack> c50627c: e129f000  msr cpsr_fc, r0 c506280: e3a01000  mov r1, #0 ; 0x0 c506284: e92d0002  stmdb sp!, r1 c506288: e8dd2000  ldmia sp, sp c5

42、0628c: e1a00000  nop   (mov r0,r0) c506290: e28dd004  add sp, sp, #4 ; 0x4 c506294: e1a0f00e  mov pc, lr偽代碼arminitexceptionmodes(void) read cpsr and save cpsr ;/* in svc32 mode*/ clear and set some flag set cpsr to undef_mode set sp under undef_

43、mode set cpsr to abort_mode set sp under abort_mode set cpsr to irq32_mode set sp under irq32_mode restore cpsr /* return to svc32*/ return它做的事情就是初始化各個模式的堆棧但以上的處理是針對remap后的, 就是把sdram的地址remap為0地址后的正常處理, 對44b0x是不適用的, 但關鍵是找到了幾個異常向量處理的入口函數(shù)或者樁函數(shù), 這樣通過我們自己的代碼就可以把flash中的異常向量和v

44、xworks的異常處理函數(shù)關聯(lián)起來了再重復一下正常情況下 local_mem_local_adrs=0, 因此異常處理函數(shù)指針是在remap后放置在地址0x100開始處, 到0x120的空間內(nèi)而對44b0x, 不能remap, local_mem_local_adrs = 0x0c000000, 因此它的異常處理函數(shù)指針應該放置在local_mem_local_adrs+0x100開始處的地方, 就是0x0c000100開始的地方, 怎么放?這就是我們要寫的針對44b0x異常向量初始化函數(shù)了函數(shù)如下void s3cexcvecset(void)    int i;

45、    i = (int)&excenterundef;    *(volatile int*)(s3c_exc_base + 0x0) = i;    i = (int)&excenterswi;    *(volatile int*)(s3c_exc_base + 0x4) = i;    i = (int)&excenterprefetchabort;    *(volatile int

46、*)(s3c_exc_base + 0x8) = i;    i = (int)&excenterdataabort;    *(volatile int*)(s3c_exc_base + 0xc) = i;    i = (int)&intent;    *(volatile int*)(s3c_exc_base + 0x14) = i;return;    把它放在bootconfig.c的usrinit函數(shù)的excvecin

47、it后面或者在syshwinit函數(shù)的第一句在rominit.s中_arm_function(romundef)_romundef: sub sp, sp, #4 stmfd sp!, r0 ldr r0, l$_promundef                ldr r0, r0            &

48、#160;str r0, sp, #4 ldmfd sp!, r0, pcl$_promundef:    .long     s3c_exc_base/* exception base */#define s3c_exc_base         0x0c000100這樣就把異常向量和vxworks的對應處理函數(shù)關聯(lián)起來了(待續(xù))44b0x的bsp是如何調(diào)成的(3)四.為伊銷得人憔悴中斷連接的問題解決了, 下一步是中斷的幾個回調(diào)函數(shù),

49、 timer和serial io的處理了, wrsbcarm7的中斷使用了3個回調(diào)函數(shù), 我自己又加了一個sysintlvlvecackrtn     = s3c44bintlvlack;  timer處理比較簡單, 就那幾個寄存器設置好就可以了, 還是那句話, 注意看手冊的說明, 注意中斷模式的設置, 要設置成非vector的方式和禁止fiq串口打印在最初時可以在makefile的編譯選項中定義debug宏, 使用pollmode發(fā)送一些串口信息, 主要是看波特率的設置是否正確, 如果能打印, 說明波特率的設置是正確的,發(fā)送方向的物理連接也是

50、好的; 同時在超級終端終端隨便敲哪個字符鍵, 看串口的接收buffer寄存器是否有數(shù)據(jù), 有, 說明接收方向的物理連接也是好的中斷怎么調(diào)?我這樣做, 算是粗調(diào)了, 在中斷入口程序處開一個計數(shù)器, 每進1次中斷, 計數(shù)器+1stmfd  sp!, r1    ldr r1 ,=0x0c300000    ldr r0, r1    add r0, r0,#0x1    str r0, r1復位板子后, 把adw打開, 直接查看0x0c300000處的值, 同時我在ti

51、mer中斷和串口發(fā)送中斷處理函數(shù)也加了計數(shù)器, 最初我發(fā)現(xiàn)0x0c300000的計數(shù)的值遠大于timer中斷計數(shù)和串口發(fā)送中斷的計數(shù), 懷疑有中斷重入了或者intlvlvecchk回調(diào)函數(shù)不對了, 這時只看統(tǒng)計計數(shù)是不行的了, 因此就這么改, 把第1次中斷的場景給記錄下了因此中斷入口程序又變成這樣了_romirq: sub sp, sp, #4 stmfd sp!, r0 ldr r0, =0x0c000114    /*l$_promirq     */ 

52、;ldr r0, r0 str r0, sp, #4str r14, sp,#-0xf0    str r0, sp, #-0x100 mrs r0, cpsr str r0, sp,#-0x104 mrs r0, spsr str r0, sp,#-0x108 str sp, sp,#-0x10c    stmfd  sp!, r1    ldr r1 ,=0x0c300000   

53、ldr r0, r1    add r0, r0,#0x1    str r0, r1    cmp r0, #0x1 /* first int */    bne byebye    str r14, sp,#-0x80    str r0, sp, #-0x84    mrs r0, cpsr str r0, sp,#-0x88 mrs r0, spsr 

54、;str r0, sp,#-0x8c str sp, sp,#-0x90 str pc, sp,#-0x94    ldr r0, =0x0c000114    /*l$_promirq     */ ldr r0, r0 str r0, sp, #-0x98    byebye:    ldmfd sp!, r1  sub r0, sp, #0x

55、110 str pc,  r0  ldmfd sp!, r0, pc后來發(fā)覺還是不行, 還是得不到很多具體的信息, 最后還是把每次中斷發(fā)生的"場景"都給錄下來了,變成這樣_romirq: sub sp, sp, #4 stmfd sp!, r0 ldr r0, l$_promirq    /*l$_promirq     */ ldr r0, r0 str 

56、r0, sp, #4    stmfd  sp!, r1    ldr r1 ,=0x0c300020     /* 0020-0080 for irq */    str r0, r1            /* irq handler =intent */    str r14, r1,#0x4 

57、0;                 mrs r0, cpsr    str r0, r1,#0x8    mrs r0, spsr    str r0, r1,#0xc    str sp, r1,#0x10    str r12, r1,#0x14     

58、;     ldr r0, r1,#0x18    stmfd sp!, r2,r3    ldr r2, =s3c44b_intpnd    ldr r2, r2    ldr r3, =0x0c400000    adds r3, r3,r0,lsl #2    str r2, r3    ldmfd sp!, r2,r3  

59、0;     add r0, r0,#0x1    str r0, r1,#0x18    #if 0    cmp r0, #0x1 /* first int */    bne byebye    str r14, r1,#0x1c        str r0, r1, #0x20       

60、 mrs r0, cpsr str r0, r1,#0x24  mrs r0, spsr str r0, r1,#0x28  str sp, r1,#0x2c str pc, r1,#0x30    ldr r0, l$_promirq    /*l$_promirq     */ ldr r0, r0 str r0, r1, #0x34    b

61、yebye:    #endif        ldmfd sp!, r1  ldr r0, =0x0c30003c str pc,  r0  ldmfd sp!, r0, pc這次可以看到每次中斷發(fā)生過程了, 把每次intpnd寄存器的值都記錄下來了, 發(fā)現(xiàn)timer中斷是ok的, 有一定的規(guī)律,每隔一定次數(shù)的串口發(fā)送中斷就有一次timer中斷, 但串口的打印還是不正確, 最后還是不行, 沒辦法, 只有跟蹤vxworks的樁處理函數(shù)了

62、在中斷入口函數(shù)加一個dead loop, 編譯, 燒寫, 復位板子, 啟動adw, 看pc是否停在了loopt:    cmp r0, #0x7    <- 這里加一個dead loop    bne loopt處, 是否是irq32模式如果是, ok, 繼續(xù)調(diào)試, 手動修改寄存器, r0=7, 這樣程序可以一步一步往下走了, 最后到ldmfd sp!, r0, pcstep in進入intent函數(shù)_romirq:    str sp, sp,#-0x50&

63、#160;sub sp, sp, #4 str sp, sp,#-0x54 stmfd sp!, r0    str sp, sp,#-0x58    ldr r0, sp    str r0, sp,#-0x70    ldr r0, sp, #4    str r0, sp,#-0x74     ldr r0, l$_promirq  

64、;  /*l$_promirq     */ ldr r0, r0 str r0, sp, #4    ldr r0, sp,#4    str r0, sp,#-0x78    str r0, sp,#-0x30    str sp, sp,#-0x34    ldr r0, =0x0c308000    ldr r0, r0

65、loopt:    cmp r0, #0x7    <- 這里加一個dead loop    bne loopt    stmfd  sp!, r1    str sp, sp,#-0x5c    ldr r1 ,=0x0c300020     /* 0020-0080 for irq */    str r0, r1 &

66、#160;          /* irq handler =intent */    str r14, r1,#0x4                   mrs r0, cpsr    str r0, r1,#0x8    mrs r0, spsr

67、0;   str r0, r1,#0xc    str sp, r1,#0x10    str r12, r1,#0x14          ldr r0, r1,#0x18    stmfd sp!, r2,r3    str sp, sp,#-0x60    ldr r2, =s3c44b_intpnd    ld

68、r r2, r2    ldr r3, =0x0c400000    adds r3, r3,r0,lsl #2    str r2, r3    ldmfd sp!, r2,r3    str sp, sp,#-0x64        add r0, r0,#0x1    str r0, r1,#0x18    #if 0&#

69、160;   cmp r0, #0x1 /* first int */    bne byebye    str r14, r1,#0x1c        str r0, r1, #0x20        mrs r0, cpsr str r0, r1,#0x24  mrs r0, spsr str r0, r1,#0x28  str sp, r1,#0x2c str pc, r1,#0x30    ldr r0, l$_promirq    /*l$_promirq     */ ldr r

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論