|
| 1 | +# Pico-series microcontroller Command Line Setup |
| 2 | + |
| 3 | +This script gives you an easy way to setup your Raspberry Pi to be able to build and run programs on your Pico-series microcontroller from the command line. Compatibility with any systems not running Raspberry Pi OS or Raspberry Pi OS Lite is not guaranteed or maintained. |
| 4 | + |
| 5 | +To download & run this script, you can use the following commands: |
| 6 | +```bash |
| 7 | +wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh |
| 8 | +chmod +x pico_setup.sh |
| 9 | +./pico_setup.sh |
| 10 | +``` |
| 11 | + |
| 12 | +For manual command line setup instructions for other operating systems, see [Basic Setup on Other Operating Systems](#basic-setup-on-other-operating-systems) |
| 13 | + |
| 14 | +If you want to use a GUI instead of the command line, then see the [pico-vscode](https://github.com/raspberrypi/pico-vscode) extension instead of this script - this supports 64-bit Windows, MacOS, Raspberry Pi OS, and most common Linux distros. This is documented in the [Getting Started Guide](https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf). |
| 15 | + |
| 16 | +## Compiling and running an example |
| 17 | + |
| 18 | +After running the setup script, you'll want to run an example to check everything's working. First go into pico-examples: |
| 19 | +```bash |
| 20 | +cd pico/pico-examples |
| 21 | +``` |
| 22 | + |
| 23 | +Depending on the board you're using (eg pico2), replace `build_pico` with the relevant build directory (eg `build_pico2`) in the following commands. |
| 24 | + |
| 25 | +> If you're not using one of the default boards (pico, pico_w, pico2, or pico2_w), you'll need to create a new build directory for your board - you can do this with this command (replace `$board` with the board you are using): |
| 26 | +> ``` |
| 27 | +> cmake -S . -B build_$board -GNinja -DPICO_BOARD=$board -DCMAKE_BUILD_TYPE=Debug |
| 28 | +> ``` |
| 29 | +
|
| 30 | +To build the blink example, run the following command: |
| 31 | +```bash |
| 32 | +cmake --build build_pico --target blink |
| 33 | +``` |
| 34 | +This builds the specified target `blink` in the build folder `build_pico` |
| 35 | + |
| 36 | +Then to run it, attach a Pico-series microcontroller in BOOTSEL mode, and run: |
| 37 | +```bash |
| 38 | +picotool load build_pico/blink/blink.uf2 -vx |
| 39 | +``` |
| 40 | +This loads the file into Flash on the board, then verifies it was loaded correctly and reboots the board to execute it |
| 41 | + |
| 42 | +You should now have a blinking LED on your board! For more info on the `picotool` command which is used to load and query binaries on the device, see its [README](https://github.com/raspberrypi/picotool?tab=readme-ov-file#readme) |
| 43 | + |
| 44 | +## Console Input/Output |
| 45 | + |
| 46 | +To view console output, you can either connect the UART output to a [Debug Probe](https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html#getting-started) (or similar) and use `stdio_uart` (see the hello_serial example), or you can use `stdio_usb` (see the hello_usb example). |
| 47 | + |
| 48 | +First, build & run the example for your `stdio` choice on your Pico-series microcontroller with the same commands as before: |
| 49 | +```bash |
| 50 | +cmake --build build_pico --target hello_serial |
| 51 | +picotool load build_pico/hello_world/serial/hello_serial.uf2 -vx |
| 52 | +``` |
| 53 | + |
| 54 | +Then attach `minicom` to view the output: |
| 55 | +```bash |
| 56 | +minicom -b 115200 -D /dev/ttyACM0 |
| 57 | +``` |
| 58 | +The port number may be different, so also try `/dev/ttyACM1` etc - and on other OSes may be entirely different (eg `/dev/tty.usbmodem0001` on MacOS) |
| 59 | + |
| 60 | +To exit minicom, type Ctrl+A then X |
| 61 | + |
| 62 | +## Debugging with OpenOCD and GDB |
| 63 | + |
| 64 | +To debug programs on the Pico-series microcontroller, you first need to attach a debugger such as the [Debug Probe](https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html#getting-started). Once that's done, you can attach OpenOCD to your Pico-series microcontroller with: |
| 65 | +```bash |
| 66 | +openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" |
| 67 | +``` |
| 68 | + |
| 69 | +In a separate window, you can run GDB and connect to that OpenOCD server: |
| 70 | +```bash |
| 71 | +gdb -ex "target extended-remote localhost:3333" |
| 72 | +``` |
| 73 | + |
| 74 | +Then in GDB, run the following (replacing blink.elf with the path to blink.elf if it's not in the current directory) |
| 75 | +```console |
| 76 | +file blink.elf |
| 77 | +monitor reset init |
| 78 | +load |
| 79 | +continue |
| 80 | +``` |
| 81 | + |
| 82 | +To exit GDB, use Ctrl+D twice. This will leave your Pico-series microcontroller in the halted state, so you will need to unplug and replug it to get it running again. To leave the device running, you can use: |
| 83 | +```console |
| 84 | +monitor reset run |
| 85 | +``` |
| 86 | +before exiting to leave the Pico running the code. |
| 87 | + |
| 88 | +### Useful GDB Commands |
| 89 | +To configure the GDB layout, the following commands can be useful: |
| 90 | +* `layout src` - displays the source code |
| 91 | +* `layout split` - displays the source code and the assembly instructions |
| 92 | +* `layout regs` - displays the current register contents |
| 93 | + |
| 94 | +To step through code, you can use: |
| 95 | +* `step` or `s` - step to the next line of code, and into any functions |
| 96 | +* `next` or `n` - step to the next line of code, without stepping into functions |
| 97 | +* `finish` or `fin` - step out of the current function |
| 98 | + |
| 99 | +To step through assembly instructions, you can use: |
| 100 | +* `stepi` or `si` - step to the next assembly instruction, and into any functions |
| 101 | +* `nexti` or `ni` - step to the next assembly instruction, without stepping into functions |
| 102 | + |
| 103 | +While stepping, you can just press enter again to repeat the previous command |
| 104 | + |
| 105 | +To set breakpoints, use the `break` or `b` command plus the location of the breakpoint. The location can be: |
| 106 | +* A function name - `break main` |
| 107 | +* A line of code - `break 12` |
| 108 | +* Either of those in a specific file - `break blink.c:48`, `break blink.c:main` |
| 109 | +* A specific memory address - `break *0x10000ff2` |
| 110 | + |
| 111 | +For more details on debugging with GDB, see the [GDB docs](https://sourceware.org/gdb/current/onlinedocs/gdb.html/) |
| 112 | + |
| 113 | +## Multiple Terminals |
| 114 | + |
| 115 | +When debugging or viewing serial output, you might want multiple programs open different terminals, as they all need to run at the same time. |
| 116 | + |
| 117 | +On Raspberry Pi OS Lite, you can switch between different terminals with Alt+F1,F2,F3,F4 etc. |
| 118 | + |
| 119 | +Alternatively you can use something like `screen` or `tmux` to allow you to open new terminals and detach from them - for example using `screen`: |
| 120 | +* `screen -S minicom` - open a new terminal called `minicom` |
| 121 | +* Ctrl+A then D - detach from the current terminal |
| 122 | +* `screen -r minicom` - re-attach to an existing terminal called `minicom` |
| 123 | +* `screen -ls` - list existing terminals |
| 124 | + |
| 125 | +## Basic Setup on Other Operating Systems |
| 126 | + |
| 127 | +### Prerequisites |
| 128 | +#### Windows |
| 129 | + |
| 130 | +If you're on Windows, it is **strongly recommended** to use [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) and then follow the [Linux instructions](#linux) inside that. You should also install [usbipd](https://github.com/dorssel/usbipd-win) to access USB devices inside WSL2 (see the docs there for instructions). |
| 131 | + |
| 132 | +If you're not using WSL2, then you'll need to install the following tools: |
| 133 | +* [Arm GNU Toolchain](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads) |
| 134 | + * Pick Windows -> AArch32 bare-metal target (arm-none-eabi) -> the .exe file |
| 135 | +* [CMake](https://cmake.org/download/) |
| 136 | +* [Microsoft Visual Studio](https://visualstudio.microsoft.com/downloads/) |
| 137 | + * When running the installer, select Desktop Development with C++ |
| 138 | + |
| 139 | +Then follow the [manual setup instructions](#setup-sdk--picotool). You will need to run all commands from the "Developer PowerShell for VS ..." terminal, not your usual terminal. For the first cmake configuration in each project (eg `cmake ..`), you will need to replace `-GNinja` with `-G "NMake Makefiles"`, and anything with `sudo` needs to be run as administrator. Also, you should use as short a path as possible due to path length limits on Windows. |
| 140 | + |
| 141 | +#### MacOS |
| 142 | + |
| 143 | +Install [Homebrew](https://brew.sh/) and run these commands |
| 144 | +``` |
| 145 | +xcode-select --install |
| 146 | +brew install cmake ninja |
| 147 | +brew install --cask gcc-arm-embedded |
| 148 | +``` |
| 149 | + |
| 150 | +Then follow the [manual setup instructions](#setup-sdk--picotool). |
| 151 | + |
| 152 | +#### Linux |
| 153 | + |
| 154 | +If you have `apt`, then running the [pico_setup.sh](./pico_setup.sh) script should hopefully work for you, and you won't need to do any manual setup. |
| 155 | + |
| 156 | +If it doesn't work, or you don't have `apt`, then you can manually install the `GIT_DEPS` (`git` & `git-lfs`) and `SDK_DEPS` (`cmake`, `gcc-arm-none-eabi`, `gcc`, `g++` & `ninja-build`) from the script. You may also need to install a cross-compiled `newlib` if it isn't included in `gcc-arm-none-eabi`, such as `libnewlib-arm-none-eabi` & `libstdc++-arm-none-eabi-newlib`. Once those are installed, follow the [manual setup instructions](#setup-sdk--picotool). |
| 157 | + |
| 158 | +### Setup SDK & Picotool |
| 159 | + |
| 160 | +#### SDK |
| 161 | +Run this from the path you want to store the SDK: |
| 162 | +```bash |
| 163 | +git clone https://github.com/raspberrypi/pico-sdk.git |
| 164 | +git -C pico-sdk submodule update --init |
| 165 | +``` |
| 166 | + |
| 167 | +Then set `PICO_SDK_PATH` environment variable to that path - on MacOS or Linux, just add the following to your `.zshrc` (MacOS) or `.bashrc` file: |
| 168 | +```bash |
| 169 | +export PICO_SDK_PATH=/path/to/pico-sdk |
| 170 | +``` |
| 171 | +then reload your terminal window. |
| 172 | + |
| 173 | +On Windows, from an administrator PowerShell run: |
| 174 | +```powershell |
| 175 | +[System.Environment]::SetEnvironmentVariable('PICO_SDK_PATH','/path/to/pico-sdk', 'Machine') |
| 176 | +``` |
| 177 | + |
| 178 | +#### Picotool |
| 179 | +Run this from the path you want to store picotool: |
| 180 | +```bash |
| 181 | +git clone https://github.com/raspberrypi/picotool.git |
| 182 | +``` |
| 183 | + |
| 184 | +Then install libusb |
| 185 | +* On Windows, download and extract libUSB from here https://libusb.info/ (hover over Downloads, and click Latest Windows Binaries), and set LIBUSB_ROOT environment variable to the extracted directory. |
| 186 | +* On MacOS `brew install libusb` |
| 187 | +* On Linux `apt install libusb-1.0-0-dev` |
| 188 | + |
| 189 | +Then build and install picotool using these commands |
| 190 | +```bash |
| 191 | +cd picotool |
| 192 | +cmake -S . -B build |
| 193 | +cmake --build build |
| 194 | +sudo cmake --install . |
| 195 | +``` |
| 196 | + |
| 197 | +To use picotool without sudo on Linux, you'll also need to install the picotool udev rules from the picotool/udev folder. |
| 198 | + |
| 199 | +For more details on building & installing picotool, see its [README](https://github.com/raspberrypi/picotool?tab=readme-ov-file#readme) |
| 200 | + |
| 201 | +### Test it's working with pico-examples |
| 202 | +Clone pico-examples |
| 203 | +```bash |
| 204 | +git clone https://github.com/raspberrypi/pico-examples.git |
| 205 | +cd pico-examples |
| 206 | +``` |
| 207 | + |
| 208 | +Build them, replacing `$board` with the pico board you are using |
| 209 | +```bash |
| 210 | +cmake -S . -B build_$board =GNinja -DPICO_BOARD=$board -DCMAKE_BUILD_TYPE=Debug |
| 211 | +cmake --build build |
| 212 | +``` |
| 213 | + |
| 214 | +Put your board in BOOTSEL mode and use `picotool` to load the blink example: |
| 215 | +```bash |
| 216 | +picotool load build/blink/blink.uf2 -vx |
| 217 | +``` |
| 218 | +You should now have a blinking LED on your board |
0 commit comments