2016-09-23 123 views
0

我是STM32F103的新手。我有一個STM32F103的演示代碼,我正在使用arm-none-eabi進行編譯。如何使printf在STM32F103上工作?

我嘗試了我可以在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 
+1

你是什麼意思「它不工作」?它是一個微控制器,您希望在哪裏打印文本?通常,在爲嵌入式目標進行編程時,您可以創建自己的使用UART(或其他通信協議)的「print」功能集。查找一些UART庫,或者可能使用調試器的一些調試庫(例如,如果您有Segger調試器,在您的PC上使用Segger RTT和JLink Viewer) – Tim

+0

我使用arm-none-eabi- to組合。那就是問題所在。我知道如何在keil項目中使用printf。我使用USART1輸出。你是否嘗試使用這個編譯器來建立一個bin文件。 –

回答

0

Look there。這是glibprintf。但你有微控制器。所以你應該寫自己的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。標準vsprintf非常重。通常使用vsprintf功能的一小部分。

2

編寫一個自己的printf實現是一個選項,可能是我最推薦的選項。從標準庫實現中獲得一些靈感,並編寫自己的版本,以滿足您的需求。一般來說,你必須做的是,首先重新定位一個putc函數,通過你的串行接口發送字符。然後通過使用putc自定義實現覆蓋printf方法。也許,一個非常簡單的方法是通過遞歸調用putc函數以字符方式發送字符串。

最後但並非最不重要的是,您可以找到一些輕量級的printf實現。這些輕量級實現提供的代碼大小和功能集位於自定義函數printf函數和股票標準函數之間(又名野獸)。我最近嘗試了這個Tiny Printf,並對它在ARM內核上的性能表現非常滿意,其內存佔用空間和所需的執行週期數量。

-PS

從我自己writings複製某個時候回來。

1

鏈接:How to retarget printf() on an STM32F10x?

嘗試劫持_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將通過此功能(取決於你用什麼庫當然)。

+0

我在STM32F072上使用這種方法。詳情在這裏。 http://electronics.stackexchange.com/questions/206113/how-do-i-use-the-printf-function-on-stm32/279945#279945 –

0

通過包括以下鏈接標誌:

LDFLAGS += --specs=rdimon.specs -lc -lrdimon 

它看起來像你正在嘗試使用所謂半主機。您正在告訴鏈接器包含系統調用庫。

半主機是一種機制,它使運行在ARM目標上的代碼能夠在運行調試器的主機上進行通信並使用輸入/輸出功能。

這些設施的示例包括鍵盤輸入,屏幕輸出和磁盤I/O。例如,您可以使用此機制來啓用C庫中的函數(如printf()和scanf()),以使用主機的屏幕和鍵盤,而不是在目標系統上具有屏幕和鍵盤。

由於您使用開源工具爲您的STM32開發(Makefile文件和手臂 - 無 - EABI),我假設你也在使用OpenOCD的你的單片機編程。 OpenOCD的要求您啓用半主機,以及使用以下命令:

arm semihosting enable 

你可以在命令你OpenOCD的腳本確保您終止配置階段,並與「初始化」命令進入運行階段。下面是一個OpenOCD的腳本示例(適用於STM32F103):

source [find target/stm32f1x.cfg] 
init 
arm semihosting enable 

這裏提到的其他解決方案,在您重新定位的fputc()功能UART接口還將努力和實力。 Semihosting可以在所有最新的ARM Cortex-M上運行,但需要一些編譯器&調試器配置(見上文)。將fputc()函數重新映射到UART接口可以與任何編譯器一起使用,但是您必須檢查每個電路板的引腳配置。