Semihosting技術將應用程序中的IO請求通過一定的通道傳送到主機(host),由主機上的資源響應應用程序的IO請求, 而不是像在主機上執行本地應用程序一樣,由應用程序所在的計算機響應應用程序IO請求, 也就是將目標板的輸入/輸出請求從應用程序代碼傳遞到遠程運行調試器的主機的一種機制。 簡單來說,目標開發板上通常不會有輸入/輸出這些外設,開發板運行的代碼想要將結果打印出來, 或者獲得用戶的輸入,可以通過請求遠程主機IO設備來實現,如:顯示器,鍵盤等。 目標開發板執行代碼中加入對輸入/輸出設備進行訪問函數,如:printf,scanf等, 這些函數並不是目標開發板的庫函數,而是遠程主機交叉編譯器中帶有的庫函數,這些庫函數被編譯時,編譯成一條軟件中斷指令。 當目標開發板上電運行之后,執行到請求訪問輸入/輸出設備指令時,產生特定中斷號的軟件中斷SWI, 與開發板相連的調試器會先截獲目標板SWI請求,由於開發板程序中也可能存在用戶自定義軟件中斷, 為了區分二者,調試器會根據SWI的軟中斷號來判斷是不是semihosting模式IO請求, 如果是,則取出R0寄存器里代表的具體請求號,然后使用遠程主機來響應目標板具體IO請求, 而不是開發板本身去處理setmihosting請求。 semihosting僅僅是一種調試手段,它的工作原理就是利用調試器捕捉目標環境運行過程中產生SWI中斷, 然后向遠程主機調試環境發送對應的調試信息。 也就是說目標開發板通過特定的軟件中斷指令,借用了遠程主機的輸入輸出設備實現IO請求的訪問。
Semihosting半主機調試模式,只能使用在開發板和調試主機通過仿真器連接的情況下, 也就是說脫離了主機調試環境上述代碼不能正常運行。 目標開發板上執行的IO實際上是交給了遠程主機來處理實現,正是因為如此,這種方式只適合在調試模式下, 真正的嵌入式系統不可能依賴於主機實現IO處理的,嵌入式系統要想獨立出來實現IO請求的處理, 這就需要將輸入輸出庫函數的底層相關硬件實現重定向。
使用ITM機制實現調試,實現printf與scanf, ITM是ARM在推出semihosting之后推出的新一代調試機制。
ITM機制要求使用SWD方式接口,並需要連接SWO線。
半主機是用於 ARM 目標的一種機制,可將來自應用程序代碼的輸入/輸出請求傳送至運行調試器的主機。 例如,使用此機制可以啟用 C 庫中的函數,如 printf() 和 scanf(),來使用主機的屏幕和鍵盤,而不是在目標系統上配備屏幕和鍵盤。
MDK中通常使用以下兩種方法:
#pragma import(__use_no_semihosting) //不使用半主機模式 //標准庫需要的支持函數 struct __FILE { int handle; }; FILE __stdout; //定義_sys_exit()以避免使用半主機模式 _sys_exit(int x) { x = x; } //重定義fputc函數 int fputc(int ch, FILE *f) { USART_SendData(USART1,ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); return ch; }

大部分資料都是禁用了半主機模式,沒有使用過半主機模式借助主機的鍵盤輸入參數,看了很多資料,都是講半主機的,但講的內容太淺顯,
在keil5中,不管是否使用Semihosting,使用printf,scanf,fopen,fread等都需要自己填充底層函數,以printf為例,需要補充定義fputc(Keil是否不支持Host-semi機制,即不支持直接在IDE打印字符串?)
特別注意:在keil中串口打印窗口和邏輯分析窗口僅在軟件仿真的時候可用,而MDK5對STM32F4的軟件仿真,基本上不支持(故本教程直接沒有對軟件仿真進行介紹了),所以,基本上這兩個窗口用不着。但是對STM32F1的軟件仿真,MDK5是支持的,在F1開發的時候,可以用到。所以基於STM32F4的軟件仿真在keil5中很少用到。
在IAR中,選擇Semihosting后,不用自己實現填充printf,scanf,fopen,fread等底層函數,就可以在terminal I/O界面實現prrint,scanf等的測試,可以在工程目錄下實現文件操作。
疑問研究后的結論:
使用keil在半主機模式下,若是使用printf、 fopen等庫函數庫函數調用,會進入半主機模式,發生軟件異常,若此時有半主機調試環境的支持(RealView ISS、ISSM、RealView ICE 和 RealMonitor)進而通過調試器與主機進行交互,則可以進入半主機模式。但是本人使用的是JLINK V9調試器,此調試器應該是不支持半主機的調試。所以程序會進入一個錯誤的BKPT 0xAB狀態。得出結論:並不是keil5完全不支持半主機調試,是需要完全具備半主機調試的所有軟硬件平台條件后才可以用半主機來調試代碼。所以,大多數情況下,需要使用相關宏(#pragma import(__use_no_semihosting))和重定義底層IO函數的方法來避免使用半主機。
參考鏈接:
http://www.eeworld.com.cn/mcu/article_2016122632650.html
以及keil5的官方幫助文檔。
另外:IAR、KEIL都可以使用ITM跟蹤調試功能,可參考下面鏈接
https://www.jianshu.com/p/0255097f594e
。