Skip to content

[SUCCESS] Possible to use this to communicate with Pico board on jailbroken iOS via tty? #7

@badger200

Description

@badger200

Hi I’m working with Raspberry Pi Pico/W boards and unfortunately there is no way to program them on an iOS device, when I connect a USB-C to Micro-USB cable to physically connect my jailbroken iPad Pro to the Pico, it lacks the USB serial driver that would otherwise create a /dev/cu.usbmodem1411 device that common Arduino and MicroPython command line development tools use to communicate with the boards, like rshell and mpremote.

I am a little familiar with libusb because I’ve used it in the past to get my iPad taking to a guest iPhone via Apple USB-C to Lightning cable with tools like libimobiledevice and irecovery , and I had to add some specific entitlements to the binary before it successfully read the iPhone device ID etc.

Right now I have to use a Mac to program the Pico via USB but I wonder if I could somehow use this software to create my own tty as your Readme suggests a /tmp/device will be created, which seems like I could tell my mpremote/rshell to simply use that as “serial port”??

UPDATE: SUCCESS! Wow!! This is a total game changer!! Now I can program microcontrollers in the field simply using my iPad! I was able to use mpremote to successfully ls the Pico’s onboard flash, as well as running a local (on my iPad) MicroPython script! Also:

  • Resetting the board works
  • hot plugging the board works!
  • There are bugs where certain strings cause undefined behavior where suddenly your MicroPython REPL starts outputting garbage interspersed with stuff you’re not supposed to see... will need to investigate

but bottom line: it WORKS! Just incredible.

87AA84B9-545A-43FE-BF6D-4CC39529FA81

iOS 13+ binary and script :
picotty.tgz.txt (I couldn’t get this to upload unless I renamed it .txt)

Compiled with clang-15.0.7 with:
cc loader.cpp -lusb-1.0 -lc++ -std=c++17 -o picotty

It will fail to connect due to iOS system restrictions, with dmesg complaining:
System Policy: a.out(1572) deny(1) iokit-open AppleUSBHostDeviceUserClient

Fix this with:
ldid -S/usr/share/entitlements/iokit.ent -K/usr/share/jailbreak/signcert.p12 picotty

Note this command is extremely particular, no spaces allowed after the -S or -K. The -K signcert.p12 might not be necessary.

I made an iokit.ent entitlement plist, mine is overkill but I believe the relevant lines are:

        <array>
                <string>AppleUSBHostDeviceUserClient</string>
                <string>AppleUSBHostInterfaceUserClient</string>
                <string>IOUserClient</string>
        </array>
        <key>com.apple.security.iokit-open</key>
        <true/>

This is the command I use to start the loader which creates the tty for our USB serial Pico W:
./loader -v 0x2e8a -p 0x0005 --driver cdcacm -o /tmp/pico

This command will very likely work for anyone with a Pico W (and probably a Pico as long as it has the same USB vendor and product ID as the Pico W). Note this command must be exact, without the 0x prefix it crashes libc++ in argparse.hpp.

Leave the loader running, and in another terminal you can run programs that talk to it. (There’s probably an easy way to make it run as a background daemon but I’m not that advanced).

These all work with the python mpremote (tested on python3.10):

mpremote connect /tmp/pico ls
mpremote connect /tmp/pico reset
mpremote connect /tmp/pico run myprogram.py
mpremote connect /tmp/pico cp :/main.py . 

The last one copies an onboard main.py from the Pico to your current iOS terminal directory. Notice the peculiar syntax :/ required to address the Pico board filesystem.

You can copy a program to your Pico for auto-loading whenever the Pico is powered, stand-alone, with this:
mpremote connect /tmp/pico cp myprogram.py :/main.py

rshell and mpremote list-devices commands do not auto detect the board, probably because this tty is too weird and nonstandard (it’s not a ttyUSB) so we just manually specify it. The loader actually creates a new /dev/ttys03 which it symlinks at /tmp/pico.

This worked for rshell:
rshell -p /tmp/pico

Hardware used:

  • iPad Pro 11” 2018 A12X jailbroken with unc0ver 8.0.2
  • iOS 14.4
  • A generic USB-C to USB-B female port adapter (I don’t think it’s MFi? It came with a random device that has nothing to do with iOS).
  • Standard USB-B to USB Micro cable
  • MicroPython 1.20.0 firmware
  • Raspberry Pi Pico W microcontroller
  • Python mpremote (pretty sure this is available on pip, otherwise rshell should work)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions