Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Major rewrite of pico_setup.sh #20

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,44 @@

Raspberry Pi Pico Setup provides a script for installing the Pico SDK and toolchain.

# How-To
## How-To

Download and run `pico_setup.sh`:

```shell
wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh
chmod +x pico_setup
./pico_setup
chmod +x pico_setup.sh
./pico_setup.sh
```

The script uses sudo, so you may need to enter your password.

After the script is complete, reboot to ensure that all changes take effect, such as the UART settings and environment variables.

If you want the testing script and documentation, you can clone the git repo too.

# Support
## Support

This script works on most Debian-derived Linux distros and macOS, running on common Raspberry Pi, PC, and Mac hardware. This ***DOESN'T*** mean that all of the pico tools work properly on these platforms. It just means that this script runs and passes its own tests.

Operating systems:

* Raspberry Pi OS (32-bit)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI I did test the "previous" pico_setup.sh on Raspberry Pi OS (64-bit) too, so it would be nice if that still worked (I'll do some testing myself later).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It really should work. I think the only explicit consideration to 32-bit vs 64-bit was part of the old VSCode installation. That's been refactored to rely on APT to get the right build.

I'm leaving this conversation open pending confirmation.

* Debian 10 (Buster)
* Ubuntu 20.10 (Groovy)
* Ubuntu 20.04 or later
* macOS 11 (Big Sur)
* Ubuntu 20.04 on Windows Subsystem for Linux on Windows Server 2019 Base
* Debian GNU/Linux 1.3.0.0 on Windows Subsystem for Linux on Windows Server 2019 Base

This script does not support Windows natively, only Windows Subsystem for Linux.
* Windows Subsystem for Linux

Hardware:
* Raspberry Pi 2/3/4/400/CM3/CM4

* Any model of Raspberry Pi
* PC (x86_64)
* Mac (both Intel and Apple Silicon)

Other OSes and hardware may work, but haven't been tested. Use at your own risk.
Visual Studio Code may not run well on Raspberry Pi 1 and Zero because of their smaller RAM capacity, but the rest of the toolkit works fine.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be surprised if VSCode ran (well?) on anything except the Raspberry Pi 4? I certainly don't have any experience on running it on anything else. Anyone?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I get a chance I'll test later today, but IIRC with VSCode being based on Electron, that probably means it only runs on ARMv7 and above which rules out the RPi 1 and Zero (which are ARMv6).

Copy link
Author

@michaelstoops michaelstoops Apr 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I certainly don't find GUI fun on any of the Raspberry Pis. My 8 GB Raspberry Pi 4 has a chance but it seems to be more interested in making a tiny sad little ticking sound than booting.


Other OSes and hardware _may_ work, but haven't been tested. Use at your own risk.

# Testing
## Testing

See [test/README.md](test/README.md).
119 changes: 60 additions & 59 deletions pico_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
# Phase 0: Preflight check
# Verify baseline dependencies

# Phase 1: Setup minimum dev environment
# Install the toolchain
# Phase 1: Setup dev environment
# Install the software packages from APT or Homebrew
# Create a directory called pico
# Download the pico-sdk repository and submodules
# Define env variables for repo: PICO_SDK_PATH
# Configure the Raspberry Pi UART for use with Raspberry Pi Pico
# Define env variables: PICO_SDK_PATH
# On Raspberry Pi only: configure the UART for use with Raspberry Pi Pico

# Phase 2: Setting up tutorial repos
# Download pico-examples, pico-extras, pico-playground repositories, and submodules
Expand All @@ -24,13 +24,19 @@
set -e
# Show all commands
set -x

# Trying to use an non-existent variable is an error
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"an" -> "a"

set -u

# Number of cores when running make
JNUM=4

# Where will the output go?
WORKING_DIR="$(pwd)/pico"
if printenv TARGET_DIR; then
echo "Using target dir from \$TARGET_DIR: ${TARGET_DIR}"
Comment on lines +40 to +41
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh? Didn't you say in a previous comment that you preferred reading things from command-line switches rather than environment variables? 😉
(although I've no actual objection to this change, as long as printenv works on every platform that you're targeting)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting point. printenv is part of GNU coreutils -- does it work on macOS out of the box? env is the POSIX alternative.

Copy link

@aallan aallan Apr 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Starting with macOS Catalina, Macs will now use zsh as the default login shell and interactive shell across the operating system. All newly created user accounts in macOS Catalina will use zsh by default. That said, mosts existing Mac users will be running bash. I know I am, the script will have to handle both cases.

But AFAIK printenv works out of the box on macOS. My machines aren't a good test of this though. Need to find someone that hasn't been using Macs-as-UNIX for the last 20 years and doesn't have a whole bunch of stuff installed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgive me, I was weak. I fell to temptation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, yes, printenv is always available. The final round of platform testing should confirm.

else
TARGET_DIR="$(pwd)/pico"
echo "Using target dir: ${TARGET_DIR}"
fi


linux() {
Expand Down Expand Up @@ -73,7 +79,7 @@ raspberry_pi() {
}

phase_0() {
# Preflight the check
# Preflight check
# Checks the baseline dependencies. If you don't have these, this script won't work.
echo "Entering phase 0: Preflight check"

Expand Down Expand Up @@ -108,12 +114,12 @@ phase_0() {
fi
}

install_toolchain_linux() {
# Install toolchain for Linux
install_dev_env_deps_linux() {
# Install development environment dependencies for Linux

DEPS="python3 git cmake gcc-arm-none-eabi build-essential gdb-multiarch automake autoconf build-essential texinfo libtool libftdi-dev libusb-1.0-0-dev"
DEPS="python3 git cmake gcc-arm-none-eabi build-essential gdb-multiarch automake autoconf build-essential texinfo libtool libftdi-dev libusb-1.0-0-dev minicom pkg-config"
michaelstoops marked this conversation as resolved.
Show resolved Hide resolved
if debian || ubuntu; then
DEPS="${DEPS} pkg-config libstdc++-arm-none-eabi-newlib"
DEPS="${DEPS} libstdc++-arm-none-eabi-newlib"
fi
sudo apt install -y ${DEPS}
}
Expand All @@ -124,51 +130,55 @@ brew_install_idempotent() {
return ${?}
}

install_toolchain_mac() {
# Install dependencies for mac
install_dev_env_deps_mac() {
# Install development environment dependencies for mac

brew_install_idempotent git cmake pkg-config libtool automake libusb wget pkg-config gcc texinfo
brew tap ArmMbed/homebrew-formulae
brew_install_idempotent arm-none-eabi-gcc
brew_install_idempotent git cmake pkg-config libtool automake libusb wget pkg-config gcc texinfo minicom ArmMbed/homebrew-formulae/arm-none-eabi-gcc
}

create_working_dir() {
# Creates ./pico directory if necessary

mkdir -p "${WORKING_DIR}"
mkdir -p "${TARGET_DIR}"
}

clone_repo() {
clone_raspberrypi_repo() {
# Clones the given repo name from GitHub and inits any submodules
# $1 should be the full name of the repo, ex: pico-sdk
# $2 should be the branch name. Defaults to master.
# all other args are passed to git clone
REPO_NAME="${1}"
if shift && [ "${1}" ]; then
if shift && [ ${#} -gt 0 ]; then
BRANCH="${1}"
# Can't just say `shift` because `set -e` will think it's an error and terminate the script.
shift || true
else
BRANCH=master
fi
if shift; then
# $* contains more args
true
fi

cd "${WORKING_DIR}"
# Save the working directory
pushd "${TARGET_DIR}" >> /dev/null
michaelstoops marked this conversation as resolved.
Show resolved Hide resolved

REPO_URL="https://github.com/raspberrypi/${REPO_NAME}.git"
DEST="${WORKING_DIR}/${REPO_NAME}"
DEST="${TARGET_DIR}/${REPO_NAME}"

if [ -d "${DEST}" ]; then
echo "Not cloning ${DEST} because it already exists. If you really want to start over, delete it: rm -rf ${DEST}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some other PR in this repo I suggested that if the repo already exists, it might be nice to do a git pull to update the repo? Is that possible / does it make sense to do that?

(my thinking being that if this script truly is idempotent, then re-running pico_setup.sh might be an easy way for a user to update all their pico-related repos?)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was on my PR, #11. I was going to update it to do git pull --ff-only. It would be nice to be able to use this script to update the repos as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love it. I'm going to do the small changes in one round, leaving this one for the following round. Leaving this thread open to remind me.

else
echo "Cloning ${REPO_URL}"
git clone -b "${BRANCH}" "${REPO_URL}" ${*}
if [ ${#} -gt 0 ]; then
git clone -b "${BRANCH}" "${REPO_URL}" ${*}
else
git clone -b "${BRANCH}" "${REPO_URL}"
fi

# Any submodules
cd "${DEST}"
git submodule update --init
fi

# Restore working directory
popd >> /dev/null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to do this pushd / popd thing in the other functions too :)

}

set_env() {
Expand All @@ -187,10 +197,8 @@ set_env() {

# ensure that appends go to a new line
if [ -f "${FILE}" ]; then
if tail -n 1 "${FILE}" | grep -q "^$"; then
echo "${FILE} exists and has trailing newline."
else
echo "${FILE} exists but has no trailing newline. Adding newline."
if ! ( tail -n 1 "${FILE}" | grep -q "^$" ); then
# FILE exists but has no trailing newline. Adding newline.
echo >> "${FILE}"
fi
fi
Expand All @@ -206,20 +214,15 @@ set_env() {
}

setup_sdk() {
# Downloads and builds the SDK
cd "${WORKING_DIR}"

clone_repo pico-sdk
# Download the SDK
clone_raspberrypi_repo pico-sdk

# Set env var PICO_SDK_PATH
REPO_UPPER=$(echo ${REPO_NAME} | tr "[:lower:]" "[:upper:]")
REPO_UPPER=$(echo ${REPO_UPPER} | tr "-" "_")
set_env "${REPO_UPPER}_PATH=$DEST"
set_env "PICO_SDK_PATH=${TARGET_DIR}/pico-sdk"
}

enable_uart() {
# Enable UART
sudo apt install -y minicom
echo "Disabling Linux serial console (UART) so we can use it for pico"
sudo raspi-config nonint do_serial 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it's worth checking that raspi-config is available on a Raspberry Pi in the preflight check?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've rolled this comment into the comment on line 244.

echo "You must run sudo reboot to finish UART setup"
Expand All @@ -230,26 +233,26 @@ phase_1() {
echo "Entering phase 1: Setup minimum dev environment"

if mac; then
install_toolchain_mac
install_dev_env_deps_mac
else
install_toolchain_linux
install_dev_env_deps_linux
fi

create_working_dir
setup_sdk

if raspbian && raspberry_pi; then
if raspberry_pi && which raspi-config >> /dev/null; then
enable_uart
else
echo "Not configuring UART because this is not running Raspberry Pi OS on a Raspberry Pi computer"
echo "Not configuring UART because this is not a Raspberry Pi computer, or raspi-config is unavailable."
fi
}

build_examples() {
# Build a couple of examples
echo "Building selected examples"

cd "$WORKING_DIR/pico-examples"
cd "$TARGET_DIR/pico-examples"
mkdir -p build
cd build
cmake ../ -DCMAKE_BUILD_TYPE=Debug
Expand All @@ -267,7 +270,7 @@ phase_2() {
echo "Entering phase 2: Setting up tutorial repos"

for REPO_NAME in pico-examples pico-extras pico-playground; do
clone_repo "${REPO_NAME}"
clone_raspberrypi_repo "${REPO_NAME}"
done

build_examples
Expand All @@ -277,10 +280,10 @@ setup_picotool() {
# Downloads, builds, and installs picotool
echo "Setting up picotool"

cd "${WORKING_DIR}"
cd "${TARGET_DIR}"

clone_repo picotool
cd "${WORKING_DIR}/picotool"
clone_raspberrypi_repo picotool
cd "${TARGET_DIR}/picotool"
mkdir -p build
cd build
cmake ../
Expand All @@ -294,10 +297,10 @@ setup_openocd() {
# Download, build, and install OpenOCD for picoprobe and bit-banging without picoprobe
echo "Setting up OpenOCD"

cd "${WORKING_DIR}"
cd "${TARGET_DIR}"

clone_repo openocd picoprobe --depth=1
cd "${WORKING_DIR}/openocd"
clone_raspberrypi_repo openocd picoprobe --depth=1
cd "${TARGET_DIR}/openocd"
./bootstrap
OPTS="--enable-ftdi --enable-bcm2835gpio --enable-picoprobe"
if linux; then
Expand All @@ -313,10 +316,10 @@ setup_picoprobe() {
# Download and build picoprobe. Requires that OpenOCD is already setup
echo "Setting up picoprobe"

cd "${WORKING_DIR}"
cd "${TARGET_DIR}"

clone_repo picoprobe
cd "${WORKING_DIR}/picoprobe"
clone_raspberrypi_repo picoprobe
cd "${TARGET_DIR}/picoprobe"
mkdir -p build
cd build
cmake ..
Expand All @@ -326,16 +329,14 @@ setup_picoprobe() {
install_vscode_linux() {
# Install Visual Studio Code

# VS Code is specially added to Raspberry Pi OS repos. Need to add the right repos to make it work on Debian/Ubuntu.
if debian || ubuntu; then
echo "Not yet implemented: testing Visual Studio Code on Debian/Ubuntu"
# VS Code is specially added to Raspberry Pi OS repos, but might not be present on Debian/Ubuntu. So we check first.
if ! apt list code; then
michaelstoops marked this conversation as resolved.
Show resolved Hide resolved
echo "It appears that your APT repos do not offer Visual Studio Code. Skipping."
return
fi

echo "Installing Visual Studio Code"

cd "${WORKING_DIR}"

sudo apt install -y code

# Get extensions
Expand Down Expand Up @@ -374,7 +375,7 @@ main() {
phase_2
phase_3

echo "Congratulations, installation is complete. 😁"
echo "Congratulations, installation is complete. :D"
}

main
Loading