013:ADS semihosting与硬件重定向(转)
轉(zhuǎn)自:http://www.linuxidc.com/Linux/2011-09/42019.htm
應用程序在執(zhí)行過程中經(jīng)常會和主機有IO交互請求,例如C程序中的printf,該系統(tǒng)函數(shù)被執(zhí)行時,會通過軟件中斷將printf請求提交給操作系統(tǒng)內(nèi)核,內(nèi)核將printf要打印的數(shù)據(jù)拷貝到內(nèi)核空間,通過調(diào)用顯示器驅(qū)動程序接口,將數(shù)據(jù)顯示到顯示器上。如下圖所示:
?
圖3-10本地主機IO請求示意圖
上述應用程序IO請求是最常見的一種本地主機請求方式,在嵌入式系統(tǒng)開發(fā)過程中還存在一種半主機請求模式semihosting。
1 ? semihosting半主機調(diào)試
Semihosting技術(shù)將應用程序中的IO請求通過一定的通道傳送到主機(host),由主機上的資源響應應用程序的IO請求,而不是像在主機上執(zhí)行本地應用程序一樣,由應用程序所在的計算機響應應用程序IO請求,也就是將目標板的輸入/?輸出請求從應用程序代碼傳遞到遠程運行調(diào)試器的主機的一種機制。簡單來說,目標開發(fā)板上通常不會有輸入/輸出這些外設,開發(fā)板運行的代碼想要將結(jié)果打印出來,或者獲得用戶的輸入,可以通過請求遠程主機IO設備來實現(xiàn),如:顯示器,鍵盤等。目標開發(fā)板執(zhí)行代碼中加入對輸入/輸出設備進行訪問函數(shù),如:printf,scanf等,這些函數(shù)并不是目標開發(fā)板的庫函數(shù),而是遠程主機交叉編譯器中帶有的庫函數(shù),這些庫函數(shù)被編譯時,編譯成一條軟件中斷指令。當目標開發(fā)板上電運行之后,執(zhí)行到請求訪問輸入/輸出設備指令時,產(chǎn)生特定中斷號的軟件中斷SWI(軟件中斷SWI指令請3.5系統(tǒng)調(diào)用與軟件中斷SWI的實現(xiàn)章節(jié)),與開發(fā)板相連的調(diào)試器會先截獲目標板SWI請求,由于開發(fā)板程序中也可能存在用戶自定義軟件中斷,為了區(qū)分二者,調(diào)試器會根據(jù)SWI的軟中斷號來判斷是不是semihosting模式IO請求,如果是,則取出R0寄存器里代表的具體請求號,然后使用遠程主機來響應目標板具體IO請求,而不是開發(fā)板本身去處理setmihosting請求。
代表Semihosting模式軟中斷號:
l 0x123456(ARM模式)
l 0xab(Thumb模式)
具體semihosting請求,通過寄存器R0里的值決定。
semihosting?僅僅是一種調(diào)試手段,它的工作原理就是利用調(diào)試器捕捉目標環(huán)境運行過程中產(chǎn)生的值為0x123456的SWI中斷,然后向遠程主機調(diào)試環(huán)境發(fā)送對應的調(diào)試信息。也就是說目標開發(fā)板通過特定的軟件中斷指令,借用了遠程主機的輸入輸出設備實現(xiàn)IO請求的訪問。如下圖所示。對于脫離調(diào)試環(huán)境開發(fā)板上運行的應用代碼來說,是沒有該機制的,也就是說是nonsemihost類型IO請求。
圖3-11 Semihosting遠程主機IO請求(一)
?
圖3-12 Semihosting遠程主機IO請求(二)
Semihosting實驗
Semihosting控制LED燈實驗
initstkhp.s:堆棧初始化函數(shù)
1 AREA initstkhp, CODE, READONLY 2 3 EXPORT __user_initial_stackheap ; 導出__user_initial_stackheap符號 4 5 __user_initial_stackheap ; 堆棧設置入口函數(shù) 6 7 LDR r0, =0x31000000 ; 堆地址為0x31000000 8 LDR r1, =0x33000000 ; 棧地址為0x33000000 9 mov PC, LR 10 11 ENDmain.c:
本程序首先初始化LED控制寄存器,使用標準C庫里的printf,scanf分別在AXD終端窗口打印信息和獲得用戶鍵盤輸入,根據(jù)用戶輸入數(shù)字,點亮對應的LED燈。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define GPBCON (*(volatile unsigned long *)0x56000010) 5 #define GPBDAT (*(volatile unsigned long *)0x56000014) 6 #define LEDS (1<<5|1<<6|1<<7|1<<8) 7 8 int main() 9 { 10 int i; 11 12 GPBCON = 0x00015400; 13 14 while (1) 15 16 { 17 printf("please input led number: "); 18 scanf("%d", &i); // 取得用戶輸入 19 20 21 switch (i) 22 { 23 case 1: // 輸入1,點亮Led1 24 GPBDAT=(GPBDAT&(~LEDS)) | (1<<6|1<<7|1<<8); 25 printf("led1 on/n"); 26 break; 27 28 case 2: // 輸入2,點亮Led2 29 GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<7|1<<8); 30 printf("led2 on/n"); 31 break; 32 33 case 3: // 輸入3,點亮Led3 34 GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<8); 35 printf("led3 on/n"); 36 break; 37 38 case 4: // 輸入4,點亮Led4 39 GPBDAT=(GPBDAT&(~LEDS)) | (1<<5|1<<6|1<<7); 40 printf("led4 on/n"); 41 break; 42 43 default: 44 printf("input error, please input 1 to 4/n"); 45 break; 46 47 } 48 } 49 } 50 51?
總結(jié):
Semihosting半主機調(diào)試模式,只能使用在開發(fā)板和調(diào)試主機通過仿真器連接的情況下,也就是說脫離了主機調(diào)試環(huán)境上述代碼不能正常運行。目標開發(fā)板上執(zhí)行的IO實際上是交給了遠程主機來處理實現(xiàn),正是因為如此,這種方式只適合在調(diào)試模式下,真正的嵌入式系統(tǒng)不可能依賴于主機實現(xiàn)IO處理的,嵌入式系統(tǒng)要想獨立出來實現(xiàn)IO請求的處理,這就需要將輸入輸出庫函數(shù)的底層相關(guān)硬件實現(xiàn)重定向。
轉(zhuǎn)載于:https://www.cnblogs.com/afeibfp/archive/2013/01/12/2857845.html
總結(jié)
以上是生活随笔為你收集整理的013:ADS semihosting与硬件重定向(转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cuckoo hash
- 下一篇: 使用Lubuntu开发Android应用