2016-09-23 119 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接口可以与任何编译器一起使用,但是您必须检查每个电路板的引脚配置。