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; 
}

  void _ttywrch(int ch)
  {
    ch = ch;
  }

//重定義fputc函數
int fputc(int ch, FILE *f) { HAL_UART_Transmit(&DEBUG_UART, (uint8_t *)&ch, 1, 0x200);  //根據使用的庫重定向
  return ch; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM