標題: ADS調(diào)試心得(LPC2478的調(diào)試) [打印本頁]

作者: liuda    時間: 2015-1-23 03:59
標題: ADS調(diào)試心得(LPC2478的調(diào)試)
1、在調(diào)試“E:\htwang\smart2200v201\ARM嵌入式系統(tǒng)實驗教程()\開發(fā)板出廠編程程序\液晶顯示程序\LCM_Disp”的程序時,想使用外部RAM進行仿真調(diào)試,在將ADS1.2中的“DebugInExram Settings…->Arm Linker -> Output -> Equivalent Command Line”的“-info totals -entry 0x8100000 -scatter .\src\mem_b.scf”改為“-info totals -entry 0x80000000 -scatter .\src\mem_b.scf”時,編譯時總是出現(xiàn)錯誤信息“Error: L6206E: Entry point(0x80000000) lies outside the images”,經(jīng)梁工(寶瓊)提示:“這是由于程序空間超出范圍,需要改一個參數(shù)!
       打開關于外部RAM調(diào)試的分散加載文件“mem_b.scf”發(fā)現(xiàn)所有的程序調(diào)試地址都是指向0x81000000Flash地址空間,而不是0x80000000RAM地址空間(此時硬件電路板上的短路片RAMCS0、Flash CS1),后把0x81******全部改為0x80******,編譯調(diào)試都正常。
2、不正,F(xiàn)象:在調(diào)試“SmartARM2200 V2.02”實驗箱時,每次實驗箱斷電或實驗箱上復位按鍵后,H-FlashLoad操作都要重新執(zhí)行一遍(或者簡單一點:只要在H-Flash -> Programming -> Check 按鈕上點擊一下也可以),否則下載程序后實驗箱運行不了。
(先是在選用DebugInExram出現(xiàn)這種情況,后選用RelOutChip則不會出現(xiàn)這種情況。)
       <2008-9-12> 另外,每次重新啟動H-JTAGH-Flash后,都要將H-Flash重新設一遍。
3、  現(xiàn)象:在調(diào)試GB_Disp工程時,程序無法正常運行。
分析:當調(diào)試的程序中包含中斷時,分散加載文件“mem_*.scf”的“IRAM ”項設置不能從0x40000000開始,而應該從0x40000040開始(給中斷向量留下空間),否則程序無法調(diào)試。(先是在選用RelOutChip出現(xiàn)這種情況,后選用DebugInExram也出現(xiàn)這種情況。)
< 2008-9-12 htwang: 上面的解釋并不正確,因為在調(diào)試其他中斷實驗的過程中,配置文件“mem_*.scf”的“IRAM ”項設置成從0x40000000開始也可以正常運行。(估計可能是存儲器映射的問題)
打開GB_Disp工程“target.c”文件,果然發(fā)現(xiàn)在函數(shù)“void TargetResetInit(void)”中將存儲器映射寄存器初始化成“MEMMAP 0x2”,這是選用的用戶RAM模式,中斷向量也從靜態(tài)RAM重新映射。如果想映射到用戶外部存儲器模式,應該改為“MEMMAP 0x3”(見《ARM嵌入式系統(tǒng)基礎教程》P166 或《****ARM7—LPC2200P119)。按此方式更改后,實際調(diào)試也正常。
>
2008-9-12結論:要么把該工程文件 mem_bscf 中的“IRAM ”項改成從0x40000040開始;要么把該工程文件“target.c”中的存儲器映射初始化為“MEMMAP 0x3”。
4、在調(diào)試中斷程序時,如果使用IRQ.S中的匯編宏定義程序和“IRQ_Eint3_Handler  HANDLER IRQ_Eint3”代替原來的C語言函數(shù)中斷方式(當然同時將代碼“VICVectAddr0 = (uint32)IRQ_Eint3;”改為“VICVectAddr0 = (uint32)IRQ_Eint3_Handler; ”),則應將C語言中斷函數(shù) void   __irq IRQ_Eint3(void)”改寫成“void   IRQ_Eint3(void)”。
       否則調(diào)試是出現(xiàn)的情況就是程序在“IRQ_Eint3_Handler HANDLER IRQ_Eint3”和中斷函數(shù)“void   __irq IRQ_Eint3(void){}”里面反復執(zhí)行,再也退不出來。
2008-9-12 調(diào)試“SmartARM2200 V2.02實驗箱”心得:
5、現(xiàn)象:在自己編寫定時器中斷程序時,如果自己用工程模板“ARM Executable Image for lpc2200”建立工程并編寫中斷程序后,調(diào)試過程中總是不能進入中斷,但是用定時中斷的事例程序可以進入。
       原因:經(jīng)將自己建立的模板工程文件中的“Startup.s”文件和事例程序中的比較,發(fā)現(xiàn)在模板工程的“Startup.s”文件中的堆棧初始化代碼“InitStack  …”中有一行語句為:
    ;設置系統(tǒng)模式堆棧
        MSR     CPSR_c, #0xdf
        LDR     SP, =StackUsr
       這就將IRQFIQ都禁止了,需要將“MSR     CPSR_c, #0xdf”改為“MSR     CPSR_c, #0x5f”來打開IRQ中斷才行。
6、現(xiàn)象:用C語言編寫中斷函數(shù)時,如void   __irq Timer0Int(void){   },該中斷函數(shù)必須放在主函數(shù)main()的上方,否則編譯時會出現(xiàn)錯誤(因為主函數(shù)需要調(diào)用語句“VICVectAddr0 = (uint32)Timer0Int;”):
1Error: (Serious) C2933E: type disagreement for “Timer0Int”
2) Error: C2456E: undeclared name, inventing ‘extern int Timer0Int’
       解決方法:在主函數(shù)前面加上聲明“void  __irq Timer0Int(void);”(ZLG李工),此時編譯應該不會再出現(xiàn)上述的問題,但如果此時Debug運行時不正常,需在ADS1.2(編程軟件)執(zhí)行操作“Project -> Remove Object Code… ”后,再重新編譯調(diào)試。
       如果把C語言編寫的中斷函數(shù)放到其他文件中,也是類似的處理方法,如:“extern void  __irq Timer0Int(void);
7、在ADS軟件中int類型占用4個字節(jié)的空間。
8、ALIGN=2 ,即定義2n次冪對齊方式(梅工(程宇))。(見ARM指令集ARM_zhiling.pdf
9、SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4 其中的SPACE為字節(jié)空間定義(梅工(程宇)),并用0對之進行初始化。(見ARM指令集ARM_zhiling.pdf
10、要想看到所有文件(函數(shù))對FLASHRAM的使用情況,在編譯選項設置->ARM Linker -> Listings -> Listings的“Image map”和“Symbols”前面的復選框選中,編譯后即可輸出想要的詳細信息(梅工(程宇))。
11、實驗箱上的ZLG7290芯片由于內(nèi)部鍵盤處理程序沒有去抖動和防連擊處理,所以用起來不太好用。(據(jù)說ZLG7290芯片只是ZLG用一款單片機寫了軟件貼了個商標)
2008-9-16 調(diào)試“SmartARM2200 V2.02實驗箱”心得:
12、中斷使能寄存器VICVectEnable寫入1,對應通道的中斷使能;寫入0,無效。如指令:
VICIntEnable = 1 << 6;
VICIntEnable = 1 << 4;
指令這兩條指令之后,通道6和通道4都被中斷使能。
       (課本《****ARM7--LPC2200》的P164有詳細說明)
13、在任務Task定義的局部變量與定義的靜態(tài)局部變量功能等同,因為任務不可能返回,只能被中斷(大部分是定時中斷,也可能是其他中斷)所打斷,這時中斷會保存相應的現(xiàn)場。(自我理解,沒有看到相關資料上如此解釋)
14、用typedef定義的結構體不能多次用#include 包含,否則會出現(xiàn)錯誤:
       Error(Serious) C2930E: duplicate definition of  ‘ ***’
<2008-9-16 htwang注:上述結論并不正確,出現(xiàn)這種情況是因為一個有typedef的頭文件在同一個文件中include包含了兩次。
>
2008-9-17 調(diào)試“SmartARM2200 V2.02實驗箱”心得:
15、因為任務創(chuàng)建成功后OSTaskCreate()即進行任務的調(diào)度OS_Sched(),因而與此相關的事件創(chuàng)建(如消息郵箱)程序要放在先創(chuàng)建的任務中,而不是放在即將創(chuàng)建的高優(yōu)先級任務中。
<2008-9-17 htwang注:上述結論不正確,因為任務創(chuàng)建后并不會馬上運行,它創(chuàng)建后的切換操作總是會切換到最高優(yōu)先級的任務運行,而一般我們都是用高優(yōu)先級的任務進行所有低優(yōu)先級任務的創(chuàng)建,因此任務仍然會返回起始任務繼續(xù)創(chuàng)建其它任務。所以與此相關的事件創(chuàng)建(如消息郵箱)程序必須要放在相關的即將創(chuàng)建的高優(yōu)先級任務中。
>
16、現(xiàn)象:在使用消息郵箱進行工程“E:\htwang\uCOS_Homework\uCOS_Homework”調(diào)試時,發(fā)現(xiàn)消息郵箱的指針DispMbox總是被不正常修改(因此程序也就不能正常運行)。
檢查調(diào)試:經(jīng)反復檢查調(diào)試,發(fā)現(xiàn)在一個任務中使用了一個100字節(jié)的字符數(shù)組,而給這個任務分配的堆棧長度只有64個字節(jié),分析應該是由于堆棧溢出造成的上述現(xiàn)象。于是把該任務的堆棧長度分配為256個字節(jié),不正常現(xiàn)象消失。
17、在調(diào)液晶顯示程序時,液晶顯示速率非常慢,經(jīng)查是由于uC/OS II工程模板的Startup.s文件中的總線速率配置太慢。原值為:
;IDCY = 0x0f(最大值), WST1 = 0x1f(最大值), WST2=0x1f(最大值)  
;RBLE=1(字節(jié)選擇有效),MW=1(16位寬總線)
        LDR     R0, =BCFG0
        LDR     R1, =0x1000ffef     
        STR     R1, [R0]
;IDCY = 0x0f(最大值), WST1 = 0x1f(最大值), WST2=0x1f(最大值)  
;RBLE=1(字節(jié)選擇有效),MW=1(16位寬總線)
        LDR     R0, =BCFG1
        LDR     R1, =0x1000ffef     
        STR     R1, [R0]
;IDCY = 0x0f(最大值), WST1 = 0x1f(最大值), WST2=0x1f(最大值)  
;RBLE=1(字節(jié)選擇有效),MW=2(32位寬總線)
;        LDR     R0, =BCFG2
;        LDR     R1, =0x2000ffef            
;        STR     R1, [R0]
;IDCY = 0x0f(最大值), WST1 = 0x1f(最大值), WST2=0x1f(最大值)  
;RBLE=1(字節(jié)選擇有效),MW=2(32位寬總線)
;        LDR     R0, =BCFG3
;        LDR     R1, =0x2000ffef
;        STR     R1, [R0]
修改后的總線配置為:
; 定義總線速度控制字
BCFG_DEF        EQU          0x10000400
IDCY                  EQU          (0x00<<0)
WST1                  EQU          (0x01<<5)
WST2                  EQU          (0x01<<11)
BCFG3_SET      EQU          (BCFG_DEF | IDCY | WST1 | WST2)
IDCYFS             EQU          (0x01<<0)
WST1FS             EQU          (0x03<<5)
WST2FS             EQU          (0x03<<11)
BCFG_FS     EQU           (BCFG_DEF | IDCYFS | WST1FS | WST2FS)
        
        LDR     R0, =BCFG0
        LDR     R1, =BCFG_FS
        STR     R1, [R0]
        LDR     R0, =BCFG1
        LDR     R1, =BCFG_FS
        STR     R1, [R0]
        LDR     R0, =BCFG2
        LDR     R1, =0x1000ffef
        STR     R1, [R0]
        LDR     R0, =BCFG3
        LDR     R1, =BCFG3_SET
        STR     R1, [R0]
分析:由于液晶接在CS3,而CS3的總線配置在uC/OS II工程模板的Startup.s文件中被分號所屏蔽,所以其值為默認值(最大延時)。把有關CS3的屏蔽去掉,也應該能加快液晶顯示速度。
結論:經(jīng)實際調(diào)試,把uC/OS II工程模板的Startup.s文件中有關CS3的總線配置屏蔽去掉并不能正常進行液晶顯示,因為原值為配置的32位總線寬度(見上面程序中后加的注釋分析),原總線類型配置值與液晶不匹配,必須要進行修改。
2008-09-19調(diào)試“E:\htwang\uCOS_Homework2”目錄下的工程心得:
18、互斥信號量是對共享資源的獨占,最好一次使用完必須立即釋放。如果不想一次使用完就釋放(需要該共享資源使用一段時間或好幾次循環(huán)),那么在另一個任務中對共享資源的請求當然可以采用OSMutexPend(RTCModifyMutex,0,&err) 的方法,但只需要該任務如果得不到共享資源就不能執(zhí)行其他操作;如果任務在得不到共享資源的情況下仍然需要執(zhí)行其他必須的操作,那么用ifOSMutexAccept(RTCModifyMutex,&err))的方法請求互斥信號量是一個很好的選擇。
19、信號量發(fā)送(包括互斥信號量)沒有廣播發(fā)送的方式,信號量集也沒有;只有消息和消息隊列有廣播發(fā)送的方式。
20、為什么在所有軟中斷和IRQ中斷只保存了R0-R3R12,其他的R4-R11為何沒有保存?(見《嵌入式實時操作系統(tǒng)uC/OS-II 原理及應用》的P220
2008-9-19 趙永科答)查看一個C語言函數(shù)編寫的反匯編代碼,如果使用了太多的局部變量等,C語言函數(shù)會在程序開始部分自動把R4-R11保存起來(不是全部,用到多少保存多少),如:
STMFD    r13!,{r4-r11,r14}   (其中一個C函數(shù)頭部的反匯編)
stmfd    r13!,{r1-r11,r14}  (其中一個C函數(shù)頭部的反匯編)
stmfd    r13!,{r3-r7,r14}    (其中一個C函數(shù)頭部的反匯編)
所以IRQ中斷只保存了R0-R3R12)。
<htwang注:在編譯階段的所有C語言函數(shù)里,函數(shù)會在開頭自動把R4-R11都保存起來,如:STMFD    r13!,{r4-r11,r14}   (編譯階段其中一個C函數(shù)頭部的反匯編)
而在調(diào)試階段的所有C語言函數(shù)里,函數(shù)會在開頭自動把R4-R11中用到的變量智能自動保存起來,如:
stmfd    r13!,{r1-r11,r14}  (調(diào)試階段其中一個C函數(shù)頭部的反匯編)
stmfd    r13!,{r3-r7,r14}    (調(diào)試階段其中一個C函數(shù)頭部的反匯編)
>
2008-09-20調(diào)試“E:\htwang\uCOS_Homework3”目錄下的工程心得:
21、使用內(nèi)存分區(qū)時,每“一組”數(shù)據(jù)都要申請一個內(nèi)存塊。(不是每一個數(shù)據(jù),存放每一個數(shù)據(jù)只需把申請到的對應的指針加1就行)
22、在調(diào)試“E:\htwang\uCOS_Homework3”目錄下的工程時:如果分配AD數(shù)據(jù)采樣任務TaskSamp的優(yōu)先級大于顯示任務TaskDisp的優(yōu)先級時,當AD數(shù)據(jù)采樣任務TaskSamp中在開始沒有延時(如OSTimeDly(1);)程序總會出現(xiàn)預取指中止;但當設置AD數(shù)據(jù)采樣任務TaskSamp的優(yōu)先級小于顯示任務TaskDisp的優(yōu)先級時,即使沒有延時OSTimeDly(1)程序也能運行。不知是什么原因。
       經(jīng)反復檢查調(diào)試,發(fā)現(xiàn)給AD數(shù)據(jù)采樣任務TaskSamp分配的堆棧太小(只有64個字節(jié)),當把該任務堆棧大小改為256個字節(jié)時,各種情況下調(diào)試都很正常。
       分析得出:當給任務分配的堆?臻g太小,在堆棧使用溢出后,會占用其他任務的堆?臻g。因此程序就會出現(xiàn)不可預料的結果。
(堆棧分配太小還可能出現(xiàn)的情況,如本調(diào)試心得第15條)
2008-09-22調(diào)試“E:\htwang\uCOS_Homework3”目錄下的工程心得:
23、像程序中的函數(shù)“OSTimeDly(OS_TICKS_PER_SEC * 5); //5s采樣一次” (配置頭文件中定義:#define OS_TICKS_PER_SEC 200) ,其參數(shù)并不需要人工強制類型轉換,如“OSTimeDly((uint16)OS_TICKS_PER_SEC * 5);”調(diào)試階段的反匯編會自動將它們算好作為一個常量處理,如下面的實際反匯編:
[0xe3a00ffa]   mov      r0,#0x3e8  ;OS_TICKS_PER_SEC * 5 =200*5 =1000=0x3e8
[0xebffff4e]   bl       OSTimeDly
24、創(chuàng)建動態(tài)內(nèi)存分區(qū)時“OS_MEM  *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)”,需注意:
       1)、必須要指向一個具體的二維數(shù)組,如“uint8  ADCDataPart[10][100];”即addr不能為空;
       2)、每個內(nèi)存分區(qū)的塊數(shù)必須不能小于2,即nblks  >=  2
       3)、每個塊的大小必須至少能夠放下一個4字節(jié)的指針(void *),即blksize  >= sizeof(void *);
<htwang注:也就是說每個塊有4個字節(jié)的空間被指針所用。即如果你定義了100個字節(jié)的塊空間大小,只能使用96個字節(jié)。這樣看來在《基于嵌入式實時操作系統(tǒng)的程序設計技術》的P130-P133的例程L8-7出現(xiàn)錯誤。
>
2008-09-22注:經(jīng)ZLG梅工(程宇)多方確認:原來的程序沒有錯誤。這個需要將OSMemCreate()、void  *OSMemGetOS_MEM *pmem, INT8U *err)和INT8U  OSMemPutOS_MEM  *pmem, void *pblk)三個函數(shù)聯(lián)系起來看。
OSMemGet()中,總是將指針OSMemFreeList指向下一個未用的空間,這樣申請到的塊中的所有空間(包括4個字節(jié)的指針空間)可以一起使用。原來申請到使用的塊的指針空間會在OSM emPut()中恢復。
OSMemPut()中會把在OSMemGet()中申請到的指針(指向該塊的首址)重新建立一個指向下一個塊(原OSMemFreeList指向的單元)的指針。
具體請看這3個函數(shù)的源代碼。
25、對按鍵的延時去抖和防連擊處理。參考了《基于嵌入式實時操作系統(tǒng)的程序設計技術》P163的按鍵處理例程。
26、(2008-9-23)在使用LPC2000系列ARMAD轉換部件時發(fā)現(xiàn):每個通道在進行AD轉換時,第1次采樣和第2次采樣有較大的誤差;而第3次采樣又和第1次一樣,第4次采樣和第2次一樣
如:1994mV,2036mV,1994mV,2036mV…
       因此,每次都應對同一個通道采樣兩次,然后舍棄前一個值。見《基于嵌入式實時操作系統(tǒng)的程序設計技術》P132AD采樣例程






歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1