Pico SDK 1.5.0 revamps IO over USB — and makes it work

The Raspberry Pi company released version 1.5.0 of the Pico SDK a week ago — right after I issued the latest version of my desktop computer-oriented I²C adaptor, which is based on the Pico’s RP2040 chip. If I’d have known about the SDK update, I would have held back — SDK 1.5.0 solves an irritating problem I’d faced with unexplained adaptor firmware hangs.

The RP2040 based I2C adaptor here running on a Pimoroni Tiny 2040 and with a matrix LED connected

Among the many improvements made by SDK 1.5.0 are some that centre on its support for stdio operations over UART and USB. My firmware uses the latter to receive control commands and data from a host computer and which it relays to connected I²C devices and GPIO pins.

It all works as expected — with one exception. Running scripts that frequently send commands and data to the adaptor will eventually cause the adaptor firmware to hang. This might happen after five commands or after 50, but it will occur. The board stops working — you can tell because the heartbeat flash of its LED or NeoPixel, depending on the board you’re using — will stop. The code running on the host computer loses contact with the board: it writes a command, but receives no response.

I’ve been struggling with this for some time. Manually sending a command to the board works perfectly, but scripts that send the commands would soon fail. Output from one of the board’s UARTs revealed my code wasn’t at fault, and upping the stack and heap sizes didn’t help. I couldn’t try monitoring the board with SWD because of long-running issues I’ve had getting Picoprobe to work.

So how does the new SDK help? Here’s the key text from the release notes: “pico_stdio allows for outputting from within an IRQ handler that creates the potential for deadlocks (especially with pico_stdio_usb)… The code has been revamped to avoid more deadlock cases, and a new define PICO_STDIO_DEADLOCK_TIMEOUT_MS has been added to catch remaining cases that might be caused by user level locking.”

So the SDK code underlying the adaptor firmware was getting caught in a cascade of interrupt requests making it unable to return to the initially interrupted code, or causing it to crash but not reboot.

SDK 1.5.0’s changes appear to eliminate the problem I was experiencing. As a test, I rebuilt the firmware with the new SDK, flashed it to an Adafruit Trinkey RP2040 with a four-digit, seven-segment LED attached and ran some Python code that displays the CPU utilisation every second. I set it going yesterday at around 3PM. It was still running at 9:30AM today. I have never seen that level of longevity before, and the minimal firmware changes I’ve made mean that it’s all down to the new SDK.

A Raspberry Pi testing the updated firmware built on the new SDK

Rather the relying folks re-compiling the firmware with the new SDK, I’ve pushed out a new version of the firmware code with improvements and architectural changes I was going to make anyway, and with an update to the CMake build system configuration files to highlight the need to update to SDK 1.5.0.

The new version is available at this GitHub repo, and you can read more about it here.

Future work will centre on exploring the callback-on-receipt-of-data functionality also added to the new SDK with a view to replacing the current polling mechanism.

Other to-do list items include supporting higher, non-standard UART bit rates on Linux, and trying to understand why at one point macOS release builds were failing when debug builds worked as expected. There’s always something to figure out and fix…

2 thoughts on “Pico SDK 1.5.0 revamps IO over USB — and makes it work

  1. Martin Crossley

    Hello mate – many thanks for your top quality writing and blog.

    Regarding PicoProbe, in case it’s of any help I’ve been using it successfully for quite a while with no issues under macOS 12.6.3 (Monterey) and VSCode. It’s worth persevering with: the integration VSCode for one touch code launching and step-thru debugging in particular is absolutely phenomenal.

    I didn’t have to do anything especially ‘clever’ to implement it; really I just followed ShawnHymel’s instructions here: https://www.digikey.be/en/maker/projects/raspberry-pi-pico-and-rp2040-cc-part-2-debugging-with-vs-code/470abc7efb07432b82c95f6f67f184c0 (NOTE: you might also want to check that the SDK paths etc are set up as per part 1 of that blog too, or make the necessary changes).

    There’s also a (very) simple VSCode pico+picoprobe template on my GitHub repo: https://github.com/mjcross/pico-template
    If you want any additional details, debug etc, then please feel free to ping me a mail.

    Keep up the great work

    1. smittytone Post author

      I have it working now. Back a while it worked too, then re-compilations started to fail. The errors appear to have been fixed in the recent PicoProbe code, certainly the pre-built version available from Raspberry Pi. So since writing the last post, I’m back up running. But thanks for the suggestions.

Comments are closed.