英文:
Why does printf work in the while loop, but not before on a raspberry pi pico?
问题
我已经在Raspberry Pi 4上为Raspberry Pi Pico安装了C/C++ SDK。然后,我通过USB成功编译并执行了hello world示例。我使用minicom监视输出,到目前为止一切都正常。
但是,在while循环之前添加printf语句时,没有任何效果。
以下是SDK示例及我的一行添加内容:
#include <stdio.h>
#include "pico/stdlib.h"
int main() {
stdio_init_all();
printf("Let's start\n"); // <-- 这是我的添加部分
while (true) {
printf("Hello, world!\n");
sleep_ms(1000);
}
return 0;
}
我在minicom中每秒看到Hello World!
,但没有Let's start
。可能的原因是什么,我该如何解决?
英文:
I have installed the C/C++ SDK for the Raspberry PI Pico on a Raspberry pi 4. Then I have compiled and executed the hello world example via USB successfully. I monitor the output using minicom and so far everything works fine.
However, when I add a printf before the while loop, it has no effect.
Here is the SDK Example with my 1 line addition:
#include <stdio.h>
#include "pico/stdlib.h"
int main() {
stdio_init_all();
printf( "Let's start\n" ); // <-- This is my addition
while (true) {
printf("Hello, world!\n");
sleep_ms(1000);
}
return 0;
}
I do see Hello World!
in minicom once a second as desired, but no Let's start
. What could be the reason and how can I overcome this?
UPDATE: Answers to some questions in the comments:
- I have also tried to add
fflush(stdout);
after the first printf. It didn't help - Usually, I connect minicom before I start the application. I restart the application several times with or without the debugger and it makes no difference. Minicom does not 'drop' between restarts. It seems the connection to the USB port is stable whatever I do. It shows the "hello world" part even if I launch minicom after the application on the pico has started
- Adding a numeric identifier to see if some of the 'hello world' drops: I did this in a more complicated app with timers and various interrupts. They work just fine and they all get called after the while loop starts
- I have also added a
sleep_ms(1000)
before the printf. This didn't help either
答案1
得分: 1
USB初始化可能还没有完成,导致在stdio_init_all()
返回时丢失了最初的打印输出。
在包含pico
头文件之前,定义PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS
来等待一定的时间。否则,pico/stdio_usb.h
会将其定义为0
。
#ifndef PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS
#define PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS (5000)
#endif
#include <stdio.h>
#include "pico/stdlib.h"
int main(void) {
_Bool result = stdio_init_all(); // 现在应该等待最多5秒
printf("开始。\n");
for(unsigned co = 0;; ++co) {
printf("你好,世界!%u\n", co); // Aconcagua的建议。你看到“0”了吗?
sleep_ms(1000);
}
return 0;
}
如果5秒不够长,请尝试无限等待,并且使用stdio_usb_init()
明确初始化USB,根据文档,“如果你不希望在连接建立之前丢弃任何初始标准输出,这是有用的”。
#ifndef PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS
#define PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS (-1)
#endif
#include <stdio.h>
#include "pico/stdlib.h"
int main(void) {
_Bool result = stdio_usb_init(); // 明确初始化USB
printf("开始。\n");
for(unsigned co = 0;; ++co) {
printf("你好,世界! 初始化:%d id:%u\n", (int)result, co);
sleep_ms(1000);
}
return 0;
}
有些USB驱动程序在连接建立后仍然会直接丢失I/O,因此pico库还有一个“post connect”延迟的define
。默认设置为50 (ms
),但你可以增加它:
// 这也需要在包含任何pico头文件之前完成:
#ifndef PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS
#define PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS (1500)
#endif
如果同时定义PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS (-1)
和PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS (1500)
没有帮助,那么在stdio_usb_init
返回后,你将别无选择,只能手动睡眠:
_Bool result = stdio_usb_init();
sleep_ms(PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS);
注:PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS
在以下提交中被添加:
commit 13be546dc393e6ae8154e127f2b5cc8f5ee8fd95
Author: Graham Sanderson <graham.sanderson@raspberrypi.com>
Date: Fri Oct 8 09:01:30 2021 -0500
并且需要重新编译pico sdk。连接建立后库中实际发生的事情只是:
sleep_ms(PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS);
英文:
The most likely cause is that the USB initialization isn't done when stdio_init_all()
returns. The first print outs will then be lost.
Define PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS
to make it wait for a certain amout of time. You must define it before including the pico
headers, otherwise, pico/stdio_usb.h
will define it to 0
.
// this must be done before indirectly including "pico/stdio_usb.h":
#ifndef PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS
#define PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS (5000)
#endif
#include <stdio.h>
#include "pico/stdlib.h"
int main(void) {
_Bool result = stdio_init_all(); // should now wait for up to 5 seconds
printf( "Let's start.\n" );
for(unsigned co = 0;; ++co) {
printf("Hello, world! %u\n", co); // Aconcagua's suggestion. Do you see "0"?
sleep_ms(1000);
}
return 0;
}
If 5 seconds isn't enough, try waiting indefinitely and instead initialize USB explicitly with stdio_usb_init()
which, according to the documentation, "is useful if you don't want any initial stdout output to be discarded before the connection is established".
#ifndef PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS
#define PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS (-1)
#endif
#include <stdio.h>
#include "pico/stdlib.h"
int main(void) {
_Bool result = stdio_usb_init(); // init USB explicitly
printf( "Let's start.\n" );
for(unsigned co = 0;; ++co) {
printf("Hello, world! Init: %d id: %u\n", (int)result, co);
sleep_ms(1000);
}
return 0;
}
Some USB drivers seems to still loose I/O directly after the connection has been established, so the pico library has a define
for a "post connect" delay too. It's set to 50 (ms
) by default, but you could increase it:
// this also needs to be done before including any pico headers:
#ifndef PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS
#define PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS (1500)
#endif
If defining both PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS (-1)
and PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS (1500)
doesn't help, then you'll have no other option than to sleep manually after stdio_usb_init
returns:
_Bool result = stdio_usb_init();
sleep_ms(PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS);
Note: PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS
was added in
commit 13be546dc393e6ae8154e127f2b5cc8f5ee8fd95
Author: Graham Sanderson <graham.sanderson@raspberrypi.com>
Date: Fri Oct 8 09:01:30 2021 -0500
and requires that you recompile the pico sdk. What happens in the library when a connection is established is actually just:
sleep_ms(PICO_STDIO_USB_POST_CONNECT_WAIT_DELAY_MS);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论