stm32 不使用MircoLib情況下使用printf方法
阿新 • • 發佈:2021-12-16
不使用Microlib導致卡死的原理
在使用CubeMX初始化程式碼時,生成的工程預設是使用Microlib的,正常情況下,在STM32CubeMX通過成的.s檔案裡可以看到一個__main函式,這個就是microlib的入口地址,他會完成建立棧空間,建立堆空間,初始化使用者可能用到的系統庫等初始化動作,最後跳轉到我們熟悉的main,當使用Microlib時,__main連結的是Microlib,當不使用Microlib時,__main連結的是標準庫的C/C++;
至此,還並沒有出現什麼問題,但是,一旦在程式中呼叫printf等函式時,會讓MCU進入半主機模式,進而程式會在__main位置卡死,這也就是為什麼程式正常編譯正常燒錄正常除錯,但是執行不起來而且Debug卡死在__main位置的原因。
使用C標準庫(stdio.h)中的函式,例如printf()之類的函式,會進入半主機模式,發生軟體異常,會導致程式無法執行。半主機是這麼一種機制,它使得在ARM目標上跑的程式碼,如果主機電腦運行了偵錯程式,那麼該程式碼可以使用該主機電腦的輸入輸出裝置。 這點非常重要,因為開發初期,可能開發者根本不知道該 ARM 器件上有什麼輸入輸出裝置,而半主基機制使得你不用知道ARM器件的外設,利用主機電腦的外設就可以實現輸入輸出除錯。 所以要利用目標 ARM器件的輸入輸出裝置,首先要關掉半主機機制。然後再將輸入輸出重定向到 ARM 器件上。
解決辦法:
1、使用Microlib
2、關閉標準庫下的半主機模式
這裡我們就學習一下如何不使用Microlib,關閉半主機模式
在main.c檔案或者其他任何一個檔案中新增如下程式碼段
#pragma import(__use_no_semihosting) //標準庫需要的支援函式 struct __FILE { int handle; }; FILE __stdout; //定義_sys_exit()以避免使用半主機模式 void _sys_exit(int x) { x = x; } //重定義fputc函式 int fputc(int ch, FILE *f) { HAL_UART_Transmit(&DEBUG_UART, (uint8_t *)&ch, 1Talk is cheap, show me the code, 0x200); //根據使用的庫重定向 return ch; }