0

我是 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
4

4 回答 4

2

编写自己的printf实现是一种选择,在我看来,这可能是最推荐的选择。从标准库实现中获得一些灵感并编写自己的版本,以满足您的要求。通常,您要做的是,首先重新定位一个putc函数以通过您的串行接口发送 char 。printf然后使用putc自定义实现覆盖该方法。putc也许,一个非常简单的方法是通过递归调用函数来逐字符发送字符串。

最后但同样重要的是,您可以找到一些轻量级printf的实现。这些轻量级实现提供的代码大小和功能集介于自定义编写printf函数和标准printf函数(又名野兽)之间。我最近试用了这个Tiny Printf,对它在 ARM 内核上的内存占用和所需执行周期数方面的性能非常满意。

-PS

以前从我自己的著作中复制的。

于 2016-09-26T21:52:02.183 回答
2

通过包含以下链接器标志:

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

看起来您正在尝试使用所谓的semihosting。您正在告诉链接器包含系统调用库。

半主机是一种机制,它使运行在 ARM 目标上的代码能够通信并使用运行调试器的主机上的输入/输出工具。

这些设施的示例包括键盘输入、屏幕输出和磁盘 I/O。例如,您可以使用这种机制来启用 C 库中的函数,例如 printf() 和 scanf(),以使用主机的屏幕和键盘,而不是目标系统上的屏幕和键盘。

由于您使用开源工具进行 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 接口将适用于任何编译器,但您必须检查每个板的引脚配置。

于 2016-12-19T21:52:55.523 回答
1

看那里。这是printfglib。但是你有微控制器。所以你应该自己写printfvfprintf将结果返回到缓冲区,接下来你将从缓冲区发送数据到 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特征。

于 2016-09-25T15:24:06.707 回答
1

链接:如何在 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 将通过此功能(当然取决于您使用的库)。

于 2016-12-13T08:56:06.297 回答