[英]How to make printf work on STM32F103?
我是STM32F103的新手。 我有一個STM32F103的演示代碼,正在使用arm-none-eabi進行編譯。
我嘗試了在Google上可以找到的東西,但到目前為止沒有任何效果。 我已經花了三天時間解決這個問題。
任何人都可以給我一個有關printf的演示代碼,它可以正常工作嗎?
我的makefile的一部分:
CFLAG = -mcpu=$(CPU) -mthumb -Wall -fdump-rtl-expand -specs=nano.specs --specs=rdimon.specs -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group
LDFLAG = -mcpu=$(CPU) -T ./stm32_flash.ld -specs=nano.specs --specs=rdimon.specs -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group
編寫自己的printf
實現是一種選擇,並且據我而言可能是最推薦的選擇。 從標准庫實現中獲得一些啟發,並編寫自己的版本,僅能滿足您的要求。 通常,您需要做的是,首先將putc
函數重新定位為通過串行接口發送char。 然后使用putc
自定義實現覆蓋printf
方法。 也許,一種非常簡單的方法是通過遞歸調用putc
函數以字符方式發送字符串。
最后但並非最不重要的一點是,您可以找到一些輕量級的printf
實現。 這些輕量級實現提供的代碼大小和功能集位於自定義的書面printf
函數和常規標准printf
函數(即野獸)之間。 我最近嘗試了這個Tiny Printf ,並對其在內存占用和所需執行周期數方面的性能感到非常滿意。
-PS
從我自己的著作中復制過來的。
看那里 。 這是來自glib
printf
。 但是你有微控制器。 因此,您可以編寫自己的printf
,其中vfprintf
將結果返回到緩沖區,然后將數據從緩沖區發送到UART。 的種類
void printf( const char * format, ... )
{
char buffer[256];
va_list args;
va_start (args, format);
vsprintf (buffer,format, args);
send_via_USART1 (buffer);
va_end (args);
}
您也可以編寫自己的vsprintf
。 Standart vsprintf
非常重。 通常很少使用vsprintf
功能。
鏈接: 如何在STM32F10x上重新定位printf()?
嘗試劫持_write函數,如下所示:
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
int _write(int file, char *ptr, int len)
{
switch (file)
{
case STDOUT_FILENO: /*stdout*/
// Send the string somewhere
break;
case STDERR_FILENO: /* stderr */
// Send the string somewhere
break;
default:
return -1;
}
return len;
}
原始的printf將通過此函數(當然,取決於您使用的庫)。
通過包括以下鏈接器標志:
LDFLAGS += --specs=rdimon.specs -lc -lrdimon
看來您正在嘗試使用所謂的半主機 。 您正在告訴鏈接器包括系統調用庫。
半主機是一種機制,它使運行在ARM目標上的代碼能夠通信並使用運行調試器的主機上的輸入/輸出功能。
這些功能的示例包括鍵盤輸入,屏幕輸出和磁盤I / O。 例如,您可以使用此機制在C庫中啟用諸如printf()和scanf()之類的函數,以使用主機的屏幕和鍵盤,而不是在目標系統上具有屏幕和鍵盤。
由於您在STM32開發中使用openSource工具(Makefile和arm-none-eabi),因此我假設您也在使用openOCD對微控制器進行編程。 openOCD要求您也使用以下命令啟用半主機:
arm semihosting enable
您可以在命令中使用openOCD腳本,以確保您終止配置階段並使用“ init”命令進入運行階段。 以下是openOCD腳本(適用於STM32F103)的示例:
source [find target/stm32f1x.cfg]
init
arm semihosting enable
這里提到的其他解決方案也可以並且可能將fputc()
函數重新定位為UART接口。 半主機可在所有最新的ARM Cortex-M上運行,但需要一些編譯器和調試器配置(請參見上文)。 將fputc()
函數重新定位為UART接口將適用於任何編譯器,但您必須檢查每個電路板的引腳配置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.