RIOT OS - "stdout" 适用于嵌入式平台

RIOT OS - "stdout" for embedded platforms

我是第一次尝试 RIOT OS。下载源代码后,我可以非常轻松地构建应用程序,包括需要 ARM 工具链的目标。

hello-world 应用程序在我的 Linux 构建机器(使用 BOARD=native 构建)上运行良好,并在终端中打印。

当我切换到嵌入式平台(Nucleo F411,例如 ARM Cortex M4)时,我希望在哪里出现任何 puts() 或 printf() 调用?此外,如果 printf() 还没有转到 UART1,我该如何设置它呢?

如果这对 SO 来说太具体了,我们深表歉意。我不熟悉 RIOT OS 邮件列表,但我也会尝试一下。

编辑:hello-world 示例非常简单,如下所示:

#include <stdio.h>

int main(void)
{
    puts("Hello World!");

    printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
    printf("This board features a(n) %s MCU.\n", RIOT_MCU);

    return 0;
}

我正在使用 ARM GNU 工具链 gcc-arm-none-eabi-7-2017-q4 进行编译,遵循此处的安装说明:link。我想我需要一些额外的编译器标志,或者在上面的应用程序代码之外编辑电路板初始化函数。但是,在这个阶段,我不知道从哪里开始。我的最终目标是在将我的开发套件配置到那里后观察 "Hello World!" 和 "You are running..." 上的引脚 TX/D1。

嵌入式微控制器系统编译器属于称为独立实现的类别。这意味着他们不必提供像 stdio.h 这样的库,你也不能指望 printf 可用。

然而,有可能存在通过 UART 传输实现 stdio.h 的编译器库。你必须检查你的编译器是否实现了这个。

只是为了简单的测试和类似 "hello world" 的应用程序,使用 GPIO 引脚要容易得多。 "hello world" 的嵌入式系统相当于闪烁 LED。

在嵌入式系统上,用户必须实现函数 putchar(char chr) 来输出单个字符。此功能可以使用例如 UART。

该函数应如下所示:

int fputc(int ch, FILE *f)
{
    /* Place your implementation of fputc here */
    /* e.g. write a character to the USART */
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);

    return ch;
}

在这里您可以找到一个更复杂的 STM32F0 示例

https://github.com/bjornfor/stm32-test/blob/master/STM32F0xx_StdPeriph_Lib_V1.0.0/Project/STM32F0xx_StdPeriph_Examples/USART/Printf/main.c

您使用的工具链使用 Newlib C 库(而不是具有 POSIX 依赖项的 GNU 的 libc)。要将 newlib 移植到您的目标,一些标准函数需要重新实现至少一些系统调用存根。

要使stdout有效,您至少需要实施_write_r()。如果 UART 是您唯一支持的设备,您可以忽略文件描述符 - 对于 stdout,它将始终为 1(0 = stdin,2 = stderr)。

顺便说一句,如果你想让 malloc() 工作,你需要执行 _sbrk_r().

Bill Gatliff's article on embedded.com 为 uC/OS 提供了 Newlib 移植示例 - 原则可能与 RIOT OS 相似,但如果您的库 I/O 同样可以使它更简单不需要那么复杂。

在 RIOT OS 中,默认情况下 stdio 映射到 UART0。这可以在这里看到: https://github.com/RIOT-OS/RIOT/blob/master/sys/include/stdio_uart.h#L38

通过重新定义 STDIO_UART_DEV,您可以将 stdio 映射到不同的 UART。如果您想知道哪个 UART 映射到哪些引脚,请查看您的开发板的 periph_conf.h,如果是 Nucleo F411,则在此处: https://github.com/RIOT-OS/RIOT/blob/master/boards/nucleo-f411re/include/periph_conf.h#L56