Skip to content

Commit

Permalink
Adds support for Raspberry Pi 5 (#1868)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicomiguelino authored Dec 20, 2024
1 parent 389f1cc commit 4f0f8e5
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 14 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/docker-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
needs: run-tests
strategy:
matrix:
board: ['pi1', 'pi2', 'pi3', 'pi4', 'x86']
board: ['pi1', 'pi2', 'pi3', 'pi4', 'pi5', x86']
python-version: ["3.11"]
runs-on: ubuntu-latest

Expand Down Expand Up @@ -113,6 +113,12 @@ jobs:
cat docker-compose.balena.yml.tmpl | \
envsubst > balena-deploy/docker-compose.yml
# Remove bind mounts to `/dev/vchiq` for Raspberry Pi 5
if [ "${{ matrix.board }}" == "pi5" ]; then
sed -i '/devices:/ {N; /\n.*\/dev\/vchiq:\/dev\/vchiq/d}' \
balena-deploy/docker-compose.yml
fi
- uses: balena-io/deploy-to-balena-action@master
id: build
continue-on-error: true
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ See [this](/docs/installation-options.md) page for options on how to install Ant

We've tested Anthias and is known to work on the following platforms:

* Raspberry Pi 5 Model B - 64-bit Bookworm
* Raspberry Pi 4 Model B - 32-bit and 64-bit Bullseye, 64-bit Bookworm
* Raspberry Pi 3 Model B+ - 32-bit and 64-bit Bullseye, 64-bit Bookworm
* Raspberry Pi 3 Model B - 64-bit Bookworm and Bullseye
Expand Down
11 changes: 11 additions & 0 deletions ansible/roles/system/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,17 @@
- name: Set architecture
ansible.builtin.set_fact:
architecture: "{{ 'amd64' if ansible_architecture == 'x86_64' else 'armhf' }}"
when: |
device_type == "pi1" or
device_type == "pi2" or
device_type == "pi3" or
device_type == "pi4" or
device_type == "x86"
- name: Set architecture
ansible.builtin.set_fact:
architecture: "arm64"
when: device_type == "pi5"

- name: Add Docker repo
ansible.builtin.lineinfile:
Expand Down
3 changes: 2 additions & 1 deletion anthias_app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ def settings_page(request):
'auth_backend': settings['auth_backend'],
'auth_backends': auth_backends,
'ip_addresses': ip_addresses,
'host_user': getenv('HOST_USER')
'host_user': getenv('HOST_USER'),
'device_type': getenv('DEVICE_TYPE')
})

return template(request, 'settings.html', context)
Expand Down
14 changes: 12 additions & 2 deletions bin/deploy_to_balena.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ print_help() {
echo "Usage: deploy_to_balena.sh [options]"
echo "Options:"
echo " -h, --help show this help message and exit"
echo " -b, --board BOARD specify the board to build for (pi1, pi2, pi3, pi4)"
echo " -b, --board BOARD specify the board to build for (pi1, pi2, pi3, pi4, pi5)"
echo " -f, --fleet FLEET specify the fleet name to deploy to"
echo " -s, --short-hash HASH specify the short hash to use for the image tag"
echo " -d, --dev run in dev mode"
Expand All @@ -23,7 +23,7 @@ while [[ $# -gt 0 ]]; do
-b|--board)
export BOARD="$2"

if [[ $BOARD =~ ^(pi1|pi2|pi3|pi4)$ ]]; then
if [[ $BOARD =~ ^(pi1|pi2|pi3|pi4|pi5)$ ]]; then
echo "Building for $BOARD"
else
echo "Invalid board $BOARD"
Expand Down Expand Up @@ -86,6 +86,11 @@ function prepare_balena_file() {
cp balena.yml balena-deploy/
cat docker-compose.balena.yml.tmpl | \
envsubst > balena-deploy/docker-compose.yml

if [[ "$BOARD" == "pi5" ]]; then
sed -i '/devices:/ {N; /\n.*\/dev\/vchiq:\/dev\/vchiq/d}' \
balena-deploy/docker-compose.yml
fi
}

if ! balena whoami; then
Expand All @@ -109,5 +114,10 @@ else
cat docker-compose.balena.dev.yml.tmpl | \
envsubst > docker-compose.yml

if [[ "$BOARD" == "pi5" ]]; then
sed -i '/devices:/ {N; /\n.*\/dev\/vchiq:\/dev\/vchiq/d}' \
docker-compose.yml
fi

balena push $FLEET
fi
17 changes: 17 additions & 0 deletions bin/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,25 @@ function install_ansible() {
sudo ${SUDO_ARGS[@]} pip install "$ANSIBLE_VERSION"
}

function set_device_type() {
if [ ! -f /proc/device-tree/model ] && [ "$(uname -m)" = "x86_64" ]; then
export DEVICE_TYPE="x86"
elif grep -qF "Raspberry Pi 5" /proc/device-tree/model; then
export DEVICE_TYPE="pi5"
elif grep -qF "Raspberry Pi 4" /proc/device-tree/model; then
export DEVICE_TYPE="pi4"
elif grep -qF "Raspberry Pi 3" /proc/device-tree/model; then
export DEVICE_TYPE="pi3"
elif grep -qF "Raspberry Pi 2" /proc/device-tree/model; then
export DEVICE_TYPE="pi2"
else
export DEVICE_TYPE="pi1"
fi
}

function run_ansible_playbook() {
display_section "Run the Anthias Ansible Playbook"
set_device_type

sudo -u ${USER} ${SUDO_ARGS[@]} ansible localhost \
-m git \
Expand Down
4 changes: 3 additions & 1 deletion bin/upgrade_containers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ fi
# Detect Raspberry Pi version
if [ ! -f /proc/device-tree/model ] && [ "$(uname -m)" = "x86_64" ]; then
export DEVICE_TYPE="x86"
elif grep -qF "Raspberry Pi 5" /proc/device-tree/model; then
export DEVICE_TYPE="pi5"
elif grep -qF "Raspberry Pi 4" /proc/device-tree/model; then
export DEVICE_TYPE="pi4"
elif grep -qF "Raspberry Pi 3" /proc/device-tree/model; then
Expand Down Expand Up @@ -51,7 +53,7 @@ cat /home/${USER}/screenly/docker-compose.yml.tmpl \
| envsubst \
> /home/${USER}/screenly/docker-compose.yml

if [ "$DEVICE_TYPE" = "x86" ]; then
if [[ "$DEVICE_TYPE" =~ ^(x86|pi5)$ ]]; then
sed -i '/devices:/ {N; /\n.*\/dev\/vchiq:\/dev\/vchiq/d}' \
/home/${USER}/screenly/docker-compose.yml
fi
Expand Down
3 changes: 3 additions & 0 deletions docker/Dockerfile.viewer.j2
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ RUN --mount=type=cache,target=/root/.cache/pip \
RUN c_rehash

# QT Base from packages does not support eglfs

{% if board != 'pi5' %}
RUN curl "{{webview_base_url}}/qt{{qt_major_version}}-{{qt_version}}-{{debian_version}}-{{board}}.tar.gz" \
-sL -o "/tmp/qt{{qt_major_version}}-{{qt_version}}-{{debian_version}}-{{board}}.tar.gz" && \
curl "{{webview_base_url}}/qt{{qt_major_version}}-{{qt_version}}-{{debian_version}}-{{board}}.tar.gz.sha256" \
Expand All @@ -52,6 +54,7 @@ RUN curl "{{webview_base_url}}/qt{{qt_major_version}}-{{qt_version}}-{{debian_ve
sha256sum -c "qt{{qt_major_version}}-{{qt_version}}-{{debian_version}}-{{board}}.tar.gz.sha256" && \
tar -xzf "/tmp/qt{{qt_major_version}}-{{qt_version}}-{{debian_version}}-{{board}}.tar.gz" -C /usr/local && \
rm "qt{{qt_major_version}}-{{qt_version}}-{{debian_version}}-{{board}}.tar.gz"
{% endif %}

RUN curl "{{webview_base_url}}/webview-{{qt_version}}-{{debian_version}}-{{board}}-{{webview_git_hash}}.tar.gz" \
-sL -o "/tmp/webview-{{qt_version}}-{{debian_version}}-{{board}}-{{webview_git_hash}}.tar.gz" && \
Expand Down
4 changes: 3 additions & 1 deletion lib/device_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ def get_device_type():
with open('/proc/device-tree/model') as file:
content = file.read()

if 'Raspberry Pi 4' in content:
if 'Raspberry Pi 5' in content:
return 'pi5'
elif 'Raspberry Pi 4' in content:
return 'pi4'
elif 'Raspberry Pi 3' in content:
return 'pi3'
Expand Down
5 changes: 4 additions & 1 deletion lib/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,12 @@ def __init__(self):

def get_alsa_audio_device(self):
if settings['audio_output'] == 'local':
if get_device_type() == 'pi5':
return 'default:CARD=vc4hdmi0'

return 'plughw:CARD=Headphones'
else:
if get_device_type() == 'pi4':
if get_device_type() in ['pi4', 'pi5']:
return 'default:CARD=vc4hdmi0'
elif get_device_type() in ['pi1', 'pi2', 'pi3']:
return 'default:CARD=vc4hdmi'
Expand Down
8 changes: 6 additions & 2 deletions templates/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,14 @@ <h4 class="page-header text-white">
<select class="form-control" name="audio_output">
{% if audio_output == 'hdmi' %}
<option value="hdmi" selected="selected">HDMI</option>
<option value="local">3.5mm jack</option>
{% if device_type != 'pi5' %}
<option value="local">3.5mm jack</option>
{% endif %}
{% else %}
<option value="hdmi">HDMI</option>
<option value="local" selected="selected">3.5mm jack</option>
{% if device_type != 'pi5' %}
<option value="local" selected="selected">3.5mm jack</option>
{% endif %}
{% endif %}
</select>
</div>
Expand Down
2 changes: 1 addition & 1 deletion tools/image_builder/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
SHORT_HASH_LENGTH = 7
BUILD_TARGET_OPTIONS = ['pi1', 'pi2', 'pi3', 'pi4', 'x86']
BUILD_TARGET_OPTIONS = ['pi1', 'pi2', 'pi3', 'pi4', 'pi5', 'x86']
SERVICES = (
'server',
'celery',
Expand Down
36 changes: 32 additions & 4 deletions tools/image_builder/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ def get_build_parameters(build_target: str) -> dict:
'target_platform': 'linux/amd64',
}

if build_target == 'pi5':
return {
'board': 'pi5',
'base_image': 'balenalib/raspberrypi5-debian',
'target_platform': 'linux/arm64/v8',
}
if build_target == 'pi4':
return {
'board': 'pi4',
Expand Down Expand Up @@ -88,11 +94,25 @@ def get_test_context() -> dict:


def get_viewer_context(board: str) -> dict:
webview_git_hash = '5e556681738a1fa918dc9f0bf5879ace2e603e12'
webview_git_hash = (
'389f1ccc' if board == 'pi5'
else '5e556681738a1fa918dc9f0bf5879ace2e603e12'
)
releases_url = f'{GITHUB_REPO_URL}/releases/download'
webview_base_url = f'{releases_url}/WebView-v0.3.3'
webview_base_url = (
f'{releases_url}/WebView-v0.3.4' if board == 'pi5'
else f'{releases_url}/WebView-v0.3.3'
)

qt_version = '5.15.14'

if board == 'x86':
qt_version = '6.6.3'
elif board == 'pi5':
qt_version = '6.4.2'
else:
qt_version = '5.15.14'

qt_version = '6.6.3' if board == 'x86' else '5.15.14'
qt_major_version = qt_version.split('.')[0]

apt_dependencies = [
Expand Down Expand Up @@ -204,7 +224,13 @@ def get_viewer_context(board: str) -> dict:
'libswscale-dev',
]

if board != 'x86':
if board == 'pi5':
apt_dependencies.extend([
'qt6-base-dev',
'qt6-webengine-dev',
])

if board not in ['x86', 'pi5']:
apt_dependencies.extend([
'libraspberrypi0',
'libgst-dev',
Expand All @@ -229,6 +255,8 @@ def get_wifi_connect_context(target_platform: str) -> dict:
architecture = 'rpi'
elif target_platform in ['linux/arm/v7', 'linux/arm/v8']:
architecture = 'armv7hf'
elif target_platform == 'linux/arm64/v8':
architecture = 'aarch64'
elif target_platform == 'linux/amd64':
architecture = 'amd64'
else:
Expand Down

0 comments on commit 4f0f8e5

Please sign in to comment.