我是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
答案 0 :(得分:2)
编写自己的printf
实现是一个选项,根据我的说法,这可能是最推荐的选项。从标准库实现中获取灵感并编写您自己的版本,仅满足您的要求。通常,您需要做的是,首先重新定位putc
函数以通过串行接口发送char。然后使用printf
自定义实现覆盖putc
方法。也许,一种非常简单的方法是通过putc
函数的递归调用来逐字符发送字符串。
最后但并非最不重要的是,您可以找到一些轻量级printf
实现。这些轻量级实现提供的代码大小和功能集位于自定义编写的printf
函数和库存标准printf
函数(也称为beast)之间。我最近尝试了这个Tiny Printf,并且非常满意它在ARM内核上的内存占用和所需的执行周期数。
-PS
某个时候从我自己的writings复制。
答案 1 :(得分:1)
Look there。这是来自printf
的{{1}}。但你有微控制器。因此,您可以编写自己的glib
,其中printf
将结果返回缓冲区,然后您将数据从缓冲区发送到UART。
vfprintf
你也可以写自己的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);
}
。 Standart vsprintf
非常沉重。通常使用vsprintf
功能的一小部分。
答案 2 :(得分: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将通过此功能(取决于您使用的库当然)。
答案 3 :(得分:0)
包含以下链接器标志:
LDFLAGS += --specs=rdimon.specs -lc -lrdimon
看起来您正在尝试使用所谓的半主机。您告诉链接器包含系统调用库。
半主机是一种机制,它使在ARM目标上运行的代码能够在运行调试器的主机上进行通信和使用输入/输出功能。
这些设施的示例包括键盘输入,屏幕输出和磁盘I / O.例如,您可以使用此机制启用C库中的函数,例如printf()和scanf(),以使用主机的屏幕和键盘,而不是在目标系统上使用屏幕和键盘。
由于您正在使用openSource工具进行STM32开发(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接口将适用于任何编译器,但您必须检查每个板的引脚配置。