1. 程式人生 > 其它 >stm32 不使用MircoLib情況下使用printf方法

stm32 不使用MircoLib情況下使用printf方法

不使用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, 1
, 0x200); //根據使用的庫重定向 return ch; }
Talk is cheap, show me the code