Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork8.2k
ports/nrf: Consolidate stdio functions.#15158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
github-actionsbot commentedMay 29, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Code size report:
|
codecovbot commentedMay 29, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@## master #15158 +/- ##==========================================- Coverage 98.42% 98.39% -0.03%========================================== Files 161 161 Lines 21204 21204 ==========================================- Hits 20870 20864 -6- Misses 334 340 +6 ☔ View full report in Codecov by Sentry. |
This PR does not even build for a Arduino BLE 33 Sense or a SEEED XIAO NRF52 or NRF52840_MDK_USB_DONGLE. Compile errors: rivers/usb/usb_cdc.c: In function 'mp_usbd_port_get_serial_number': Rebasing to the current master branch fails as well due to conflicts in the make files of the other ports. Nothings difficult, just duplicating references to files, but it breaks rebase. If you look at the CI of this PR, you see that it fails as well in building the firmware. |
Ah yes it seems I rushed ahead with this, it was building previously before I went and consolidated some more settings to make UART and ble repl all work the same way. |
robert-hh commentedJun 2, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
The mpconfigboard.h file for the SEEED and Arduino board miss enabling of MICROPY_HW_ENABLE_USBDEV and MICROPY_HW_USB_CDC. |
Ah thanks for looking into that. I should make that define enabled by default if USB is enabled. |
bc97045
to32fbb18
CompareAdding |
This has been rebased on master (still on top / including the startup buffer PR). I haven't yet re-tested it however. |
Both SEEED NRF52 and Arduino Nanon 33 BLE build and run. Only I had to define MICROPY_HW_ENABLE_USBDEV as 1. |
andrewleech commentedJun 5, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Ah, I see now, those boards had just I think it makes sense more broadly to have For reference, the tinyusb update came in for#14485 and is needed for those features. I don't think it should matter for just this PR though, I really would have thought the previous tinyusb commit would be fine for the changes just made here. |
andrewleech commentedJun 5, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Ok that build failure:
Is caused by binutils:
Which was apparently fixed in binutils 2.33 Of note I don't have the issue at home with gcc 12.x so it's been fixed since then, but it's hard to tell exactly when. |
Also thanks@robert-hh your reports made it clear there were a number of build failures on nrf52840 when |
Building with that PR works fine for the SEEED and Arduino boards, linking is now almost instantly. Both run. However rebasing on top of the current master branch causes conflicts in shared/tinyusb/mp_usbd_cdc.c and differences in lib/tinyusb. P.S:: I'm using GCC 12.2 as the standard version of the OS. |
Thanks I've rebased again onto master now my previous PR has been merged! |
I compiled and ran this PR on two NRF52 boards. They build fine and work most of the times. But sometimes the boards do not register as USB devices any more, even when I do a full power cycle. The boards are connected to an external hub. Unplugging the hub from the PC and re-plugging helps most of the time. Connection the boards directly to the PC does not work. There are similar reports in the MIMXRT section on Discord/micropython. So it may be a generic problem of TinyUSB. Note to@projectgus. |
@andrewleech SO I see a strange behavior on the RP2040 port. If in main.py a script is started which enables a Pin IRQ (and disables), then after a hard reset or power up USB is blocked like detailed above. I have to disconnect the USB hub and reconnect it to get USB working again, and then I see at the next boot fragments of the messages created by scripts started from main.py. If I do not add this test script, everything is fine. Once booted, soft reset works without problems.
|
robert-hh commentedJun 14, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
The issue starts with the following commit: And actually the device is registered, as I shows up in lsusb, but REPL is locked. |
Thanks for the report and testing@robert-hh |
Some information about my test case: The above script is imported in main.py after having imported another python script. Sometimes it locks up, sometimes strange error messages pop up, like the one below, where importing the script should raise an error message. It was iperf3.py, which is not working at a plain RPI Pico. That all looks like having a uninitialized symbol.
|
robert-hh commentedJun 14, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
It seems that it does not have to be that specific script. It often happens if the imported script raises an exception. Then, the output it want to create plus the usual boot banner get lengthy, like 674 bytes. |
Another strange observation: |
With mprmote I get a REPL prompt, but with a part of the main.py being in the REPL input buffer, like:
The main.py I'm using now for tests is:
With upysh.py being from mircopython-lib, pye.py is my on-board editor, both being frozen in the firmware, and cs1237.py being the driver for a cs1237 ADC, at which I noticed the problem. attached. When starting it you must NOT attach the sensor. Without the sensor an error is raised. With the sensor, all is fine. Maybe a timing issue. In some tests, instead of importing that file a simple So it''s still kind of spooky. The problem may as well be somewhere in the file system or timing dependent. |
The "correct" behaviour of that new buffering changeis to to keep the most recent "full stdout" buffer worth of data from before a terminal is connected for display on-connection. So a failure in main that drops to repl should show the tail of the error message along with the repl prompt when you open a terminal. So yeah I'd expect that snippet of traceback, though probably not the content from main itself.... It would be interesting to increase the size of the buffer and see what else is shown then. This is defined in micropython/shared/tinyusb/tusb_config.h The lockups seen on picocom are definitely an issue that warrants deeper investigation also. |
robert-hh commentedJun 16, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
I see indeed the tail of output made during execution of main.py. But text from main.py should not be there, and the REPL history buffer must be empty. With Picocom, the REPL history buffer contains e.g.: from upysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fiberoupysh impo Fibe That looks very strange! |
Really strange! Was that after a soft reset or a hard boot? I'm wondering if there's some static buffers / memory pointers being reused without appropriate clearing on soft reset? I'm really not sure how the buffer change could do this either unless it's a buffer (mis) allocation issue that the explicit clear in tinyusb was hiding previously. Repl history buffer though seems like a separate issue to me, though might be a similar root cause. I don't think there should be any direct relation between repl history buffer and tinyusb tx buffer though. |
That all happens only after hard reset resp power cycle. Once it's working, soft reset behaves fine. It seems to be the initial set-up, which fails. And only if the start-up is delayed and/or an exception is raised by the code executed in main.py. May it be that some initialization only happens when input is requested from REPL? Or the opposite? It could be a timing effect. |
I think the root cause is in the linked issue above (found by debugging@robert-hh's case above and then refining it.) |
ports/nrf/modules/machine/uart.c Outdated
if (!nrfx_is_in_ram(buf_in)) { | ||
// EasyDMA requires that transfer buffers are placed in DataRAM, | ||
// NRFX_ERROR_INVALID_ADDR if the are not. | ||
buf = alloca(size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This seems pretty dangerous, the stack may overflow if the buffer is large.
Maybe limit it to 256 bytes alloca, and do a loop over the buffer to break it up and send it in chunks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Good catch! I had been thinking this was really just stuff like exception messages where it's sending const strings from the firmware. But looking forward, certainly when RomFS comes in there will be plenty of opportunity to send data directly from flash.
I've reworked this in a chunked send loop which was tested on a nrf52840 dev board (repl on uart).
ports/nrf/Makefile Outdated
@@ -259,6 +261,11 @@ SRC_C += $(addprefix lib/tinyusb/src/,\ | |||
portable/nordic/nrf5x/dcd_nrf5x.c \ | |||
) | |||
CFLAGS += \ | |||
-DCFG_TUSB_MCU=OPT_MCU_NRF5X \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Instead of defining this at this level I suggest (this may not work but worth a try):
- don't add the
INC += -I../../shared/tinyusb
line above (this will prevent the defaulttusb_config.h
from being included) - add
INC += -I./drivers/usb
- reuse the existing
drivers/usb/tusb_config.h
file and define thisCFG_TUSB_MCU
option there, and then do#include "shared/tinyusb/tusb_config.h"
to get the remaining config from the common file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Thanks, I had thought it was confusing to have two levels of this same header - but having the port one explicitely import the shared one does make it clearer for sure. It's certainly better to have this define in the header it belongs in rather than a global cflag.
I've made this change and yes it does work!
@@ -2,6 +2,8 @@ MCU_SERIES = m4 | |||
MCU_VARIANT = nrf52 | |||
MCU_SUB_VARIANT = nrf52840 | |||
SOFTDEV_VERSION = 6.1.1 | |||
FLASHER ?= jlink |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Is this line needed, since jlink is the default flasher?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Ah, not anymore that's true.
ports/nrf/mpconfigport.h Outdated
#endif | ||
#endif | ||
#if MICROPY_HW_ENABLE_USBDEV |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Any reason why this extra #if is needed here, can't the config below be part of the block just above with theMICROPY_HW_USB_CDC
config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Oh thanks, yes I'd moved the block above to that spot to consolidate the two, then forget the final cleanup.
ports/nrf/mpconfigport.h Outdated
#endif | ||
#ifndef MICROPY_HW_USB_CDC_TX_TIMEOUT | ||
#define MICROPY_HW_USB_CDC_TX_TIMEOUT (500) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This is the default so I'd say just leave this define out.
ports/nrf/mphalport.h Outdated
@@ -43,6 +44,9 @@ typedef enum | |||
extern const unsigned char mp_hal_status_to_errno_table[4]; | |||
extern int mp_interrupt_char; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Please includeshared/runtime/interrupt_char.h
instead of declaring this variable.
ports/nrf/mphalport.c Outdated
@@ -50,6 +54,14 @@ | |||
#include "soc/nrfx_coredep.h" | |||
#endif | |||
#ifndef MICROPY_HW_STDIN_BUFFER_LEN | |||
#define MICROPY_HW_STDIN_BUFFER_LEN 1024 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This seems large, especially since nrf parts don't usually have that much RAM.
Can we drop it down to 512 like rp2?
I know it's currently 1024 in master, but the new code in this PR usesringbuf_free(&stdin_ringbuf)
to never overflow this buffer, and also the CFG_TUD_CDC_RX_BUFSIZE/CFG_TUD_CDC_TX_BUFSIZE values are now 256 (in this PR) vs 64 (in master), so there's already more buffering.
@andrewleech I see you made changes. Is this ready for re-review? |
Not quite sorry@dpgeorge I need to test them still. |
ffe7814
to9614d45
Compare@dpgeorge I've addressed your review feedback thanks and re-tested on the nrf52840 dongle and dev board. I also tested USB without the poll after adding the |
Consolidate CDC, UART and NUS stdio interfaces into the one handler.Allows any/all of them to be enabled separately.Updates UART REPL to use similar define to other platforms:`MICROPY_HW_ENABLE_UART_REPL`.USB now uses the shared/tinyusb CDC implementation.Signed-off-by: Andrew Leech <andrew@alelec.net>
Signed-off-by: Andrew Leech <andrew@alelec.net>
Older gcc/binutils linker does not support lto with wrap.Signed-off-by: Andrew Leech <andrew@alelec.net>
Signed-off-by: Andrew Leech <andrew@alelec.net>
Thanks for updating, the changes now look good. I tested this on an
|
5e80416
intomicropython:masterUh oh!
There was an error while loading.Please reload this page.
# linker wrap does not work with lto on older gcc/binutils: https://sourceware.org/bugzilla/show_bug.cgi?id=24406 | ||
GCC_VERSION = $(shell arm-none-eabi-gcc --version | sed -n -E 's:^arm.*([0-9]+\.[0-9]+\.[0-9]+).*$$:\1:p') | ||
GCC_MAJOR_VERS = $(word 1,$(subst ., ,$(GCC_VERSION))) | ||
ifeq ($(shell test $(GCC_MAJOR_VERS) -ge 10; echo $$?),0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
@andrewleech this looks a bit funny to me. On my Arch system I have:
arm-none-eabi-gcc (Arch Repository) 14.1.0
ButGCC_VERSION
here evaluates to4.1.0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Ah drats, it worked on a few systems I'd tested on but yes my arch server is also at 14.1.0 and I get the same thing. Silly greedy regex. Easy fix...arm-none-eabi-gcc --version | sed -n -E 's:^arm.*([0-9]+\.[0-9]+\.[0-9]+).*$$:\1:p'
->arm-none-eabi-gcc --version | sed -n -E 's:^arm.* ([0-9]+\.[0-9]+\.[0-9]+).*$$:\1:p'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I wish there was a way to do this in a proper programatic way, but I couldn't find one.
Consolidate CDC, UART and NUS stdio interfaces into the one handler.
Allows any/all of them to be enabled separately.
Note there are some conflicts between UART and CDC REPL handling, particularly if hwfc is enabled on the UART.
This can block for long enough to cause the CDC connection to be broken. This is not a new bug as such, the current release of nrf port is restricted to not allow both CDC and UART to be enabled at the same time at all.
Updates UART REPL to use similar define to other platforms:
MICROPY_HW_ENABLE_UART_REPL
Uses shared/tinyusb cdc implementation.
Thie PR builds upon (and therefore include commits from)#14462 and#14485
It has currently only been tested on a nrf52840 dongle, however uart, cdc and nus support have individually all worked on this board.