【问题标题】:RIOT OS - "stdout" for embedded platformsRIOT OS - 嵌入式平台的“标准输出”
【发布时间】:2018-01-31 15:11:53
【问题描述】:

我是第一次尝试 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;
}

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

【问题讨论】:

  • 对于 SO 来说并不太具体,但为了获得更好的答案,您需要准确说明所使用的工具链。
  • 你能解决你的问题吗?如果没有,首先尝试使用Docker 构建hello world 示例。之后调用 make BOARD=nucleo-f411re flash-only term 应该会烧录图像,打开终端并显示 hello world 消息。
  • 我最终没有解决这个问题。我正在从事的一个项目朝着不同的方向发展(不同的平台和操作系统)。这是在项目的评估阶段。如果 RIOT 超级好用,我会推荐它,但 MCU 供应商提供了“开箱即用”的 freeRTOS 示例。 (我的看法)

标签: c embedded riot-os


【解决方案1】:

在 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

【讨论】:

    【解决方案2】:

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

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

    顺便说一句,如果你想让malloc() et al 工作,你需要实现_sbrk_r()

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

    【讨论】:

    • 这对于所描述的情况并不是特别有用,因为 RIOT-OS 已经实现了这些,并且天生的流氓将继续在嵌入式设备上使用它是理所当然的。然后,重新定义它们只会导致构建问题。
    • @chrysn :注意点。似乎 Toons 的回答清楚地表明了这一点 - 似乎是 RTFM 的一个明显案例。
    【解决方案3】:

    在嵌入式系统上,用户必须实现函数 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

    【讨论】:

    • 我实现了一个 fputc() 函数,但它似乎并没有改变行为(UART 引脚上没有可观察到的活动)。我还从文件 uart.c 中添加了对 uart_init() 的调用
    【解决方案4】:

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

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

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

    【讨论】:

    • 我想我不确定如何在“RIOT OS”环境中做一个简单的 GPIO。我假设有一些标准方法,而不是特定于平台的函数调用?
    • @bornruffians 是时候学习了。不,没有标准方法,它取决于 MCU。您必须阅读友好的手册。
    猜你喜欢
    • 2015-09-17
    • 2011-12-17
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 2011-12-25
    • 2021-10-20
    相关资源
    最近更新 更多