Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
ab4458d
bootloader script
hrfarmer Oct 3, 2025
3a788b2
automatic gds start wip
hrfarmer Oct 3, 2025
37e2932
wip changes
hrfarmer Oct 4, 2025
12a3b83
add wip yaml
hrfarmer Oct 4, 2025
770ed65
thing
hrfarmer Oct 4, 2025
2379653
oops
hrfarmer Oct 4, 2025
7e21232
a
hrfarmer Oct 4, 2025
dd669d8
d
hrfarmer Oct 4, 2025
c6bacc1
idk
hrfarmer Oct 4, 2025
f1bbea6
bruh
hrfarmer Oct 4, 2025
c61f8de
add token
hrfarmer Oct 4, 2025
43fc12a
delete decompress
hrfarmer Oct 4, 2025
27192a0
add make step
hrfarmer Oct 4, 2025
61a570c
add uv dependency
hrfarmer Oct 4, 2025
0e21bca
sure
hrfarmer Oct 4, 2025
72b0401
add back build dependency
hrfarmer Oct 4, 2025
6961c3a
sure
hrfarmer Oct 4, 2025
11a363a
ye
hrfarmer Oct 4, 2025
ef13ff7
add make submodules
hrfarmer Oct 4, 2025
8a57a9d
gh
hrfarmer Oct 4, 2025
cc5ec17
copy it
hrfarmer Oct 4, 2025
d18f209
ls
hrfarmer Oct 4, 2025
a1dfb75
orrect path
hrfarmer Oct 4, 2025
07b955e
c
hrfarmer Oct 4, 2025
773df56
jfkdljfkldajklfjsdkal
hrfarmer Oct 4, 2025
542af01
add the thingy
hrfarmer Oct 4, 2025
948ea12
longer sleep
hrfarmer Oct 4, 2025
60c6516
d
hrfarmer Oct 4, 2025
6a6209b
add picotool reboot
hrfarmer Oct 4, 2025
e08b727
test
hrfarmer Oct 4, 2025
051cfe6
uncomment dependencies
hrfarmer Oct 4, 2025
47b121e
Try dockerizing
nateinaction Oct 4, 2025
da9a07f
Reduce image load time
nateinaction Oct 4, 2025
2b3c38f
Fix Dockerfile
nateinaction Oct 4, 2025
7ec4580
Fix Dockerfile
nateinaction Oct 4, 2025
6b63c94
Change layer order to improve caching
nateinaction Oct 4, 2025
5fd5ab8
Fix Docker run
nateinaction Oct 4, 2025
836e6a6
a
hrfarmer Oct 4, 2025
8642eca
updates
hrfarmer Oct 5, 2025
4b9ead4
Merge branch 'main' of https://github.com/Open-Source-Space-Foundatio…
hrfarmer Oct 5, 2025
8964841
delete docker
hrfarmer Oct 5, 2025
ba3eb30
Merge branch 'main' into bootloader-script
hrfarmer Oct 5, 2025
3336e00
Add setup guide
nateinaction Oct 5, 2025
32c9e88
add note to setup guide
hrfarmer Oct 6, 2025
f31031b
Add sudo to picotool udev rules setup commands
hrfarmer Oct 6, 2025
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
180 changes: 100 additions & 80 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,96 +14,116 @@ jobs:
- name: Lint
run: |
make fmt

build:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: false # We'll handle submodules with smart caching
fetch-depth: 0
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: false # We'll handle submodules with smart caching
fetch-depth: 0

# - name: Cache bin
# id: cache-bin
# uses: actions/cache@v4
# with:
# path: |
# bin
# key: bin-${{ hashFiles('Makefile') }}-v3
# restore-keys: |
# bin-${{ hashFiles('Makefile') }}-
# bin-
# - name: Cache bin
# id: cache-bin
# uses: actions/cache@v4
# with:
# path: |
# bin
# key: bin-${{ hashFiles('Makefile') }}-v3
# restore-keys: |
# bin-${{ hashFiles('Makefile') }}-
# bin-

- name: Download bin tools
if: steps.cache-bin.outputs.cache-hit != 'true'
run: |
make download-bin
- name: Download bin tools
if: steps.cache-bin.outputs.cache-hit != 'true'
run: |
make download-bin

# - name: Cache submodules
# id: cache-submodules
# uses: actions/cache@v4
# with:
# path: |
# lib/fprime
# lib/fprime-zephyr
# lib/zephyr-workspace/zephyr
# key: submodules-${{ hashFiles('.gitmodules') }}-v3
# restore-keys: |
# submodules-${{ hashFiles('.gitmodules') }}-
# submodules-
# - name: Cache submodules
# id: cache-submodules
# uses: actions/cache@v4
# with:
# path: |
# lib/fprime
# lib/fprime-zephyr
# lib/zephyr-workspace/zephyr
# key: submodules-${{ hashFiles('.gitmodules') }}-v3
# restore-keys: |
# submodules-${{ hashFiles('.gitmodules') }}-
# submodules-

- name: Setup submodules
if: steps.cache-submodules.outputs.cache-hit != 'true'
run: |
make submodules
- name: Setup submodules
if: steps.cache-submodules.outputs.cache-hit != 'true'
run: |
make submodules

# - name: Cache python venv
# id: cache-python
# uses: actions/cache@v4
# with:
# path: fprime-venv
# key: python-venv-${{ runner.os }}-${{ hashFiles('requirements.txt') }}-v3
# restore-keys: |
# python-venv-${{ runner.os }}-
# python-venv-
# - name: Cache python venv
# id: cache-python
# uses: actions/cache@v4
# with:
# path: fprime-venv
# key: python-venv-${{ runner.os }}-${{ hashFiles('requirements.txt') }}-v3
# restore-keys: |
# python-venv-${{ runner.os }}-
# python-venv-

- name: Setup python venv
if: steps.cache-python.outputs.cache-hit != 'true'
run: |
make fprime-venv
- name: Setup python venv
if: steps.cache-python.outputs.cache-hit != 'true'
run: |
make fprime-venv

# - name: Cache Zephyr workspace and SDK
# id: cache-zephyr
# uses: actions/cache@v4
# with:
# path: |
# lib/zephyr-workspace/modules
# lib/zephyr-workspace/bootloader
# ~/zephyr-sdk-0.17.2
# key: zephyr-${{ hashFiles('west.yml') }}-${{ runner.os }}-v3
# restore-keys: |
# zephyr-${{ hashFiles('west.yml') }}-${{ runner.os }}-
# zephyr-
# - name: Cache Zephyr workspace and SDK
# id: cache-zephyr
# uses: actions/cache@v4
# with:
# path: |
# lib/zephyr-workspace/modules
# lib/zephyr-workspace/bootloader
# ~/zephyr-sdk-0.17.2
# key: zephyr-${{ hashFiles('west.yml') }}-${{ runner.os }}-v3
# restore-keys: |
# zephyr-${{ hashFiles('west.yml') }}-${{ runner.os }}-
# zephyr-

- name: Setup Zephyr
if: steps.cache-zephyr.outputs.cache-hit != 'true'
run: |
make zephyr-setup
env:
PIP_DISABLE_PIP_VERSION_CHECK: 1
PIP_NO_COMPILE: 1
- name: Setup Zephyr
if: steps.cache-zephyr.outputs.cache-hit != 'true'
run: |
make zephyr-setup
env:
PIP_DISABLE_PIP_VERSION_CHECK: 1
PIP_NO_COMPILE: 1

- name: Build
run: |
make generate-ci build-ci
- name: Build
run: |
make generate-ci build-ci

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: artifacts
path: |
build-artifacts/zephyr.uf2
build-artifacts/zephyr/fprime-zephyr-deployment/dict/ReferenceDeploymentTopologyDictionary.json
retention-days: 30
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: artifacts
path: |
build-artifacts/zephyr.uf2
build-artifacts/zephyr/fprime-zephyr-deployment/dict/ReferenceDeploymentTopologyDictionary.json
retention-days: 30
integration:
runs-on: [self-hosted, integration]
needs: build
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v5
- name: Set up dependencies
run: |
mkdir -p build-artifacts/zephyr/fprime-zephyr-deployment/dict && mv zephyr/fprime-zephyr-deployment/dict/ReferenceDeploymentTopologyDictionary.json build-artifacts/zephyr/fprime-zephyr-deployment/dict
make submodules
make fprime-venv
- name: Trigger Bootloader
run: |
make bootloader
sleep 10
- name: Copy Firmware
run: |
picotool load ./zephyr.uf2
picotool reboot
- name: Run Integration Tests
run: |
make test-integration
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Components {
@ Used to trigger bootloader mode to install board firmware for integration testing. (DO NOT USE IN SPACE VERY BAD!!!!)
passive component BootloaderTrigger {

@ Restarts board and puts it in bootloader mode. (Only should be used for integration testing)
@ Restarts board and puts it in bootloader mode. (Only should be used for integration tests)
sync command TRIGGER_BOOTLOADER(
)

Expand Down
33 changes: 33 additions & 0 deletions FprimeZephyrReference/test/bootloader_trigger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import os
import subprocess
import time

import pytest
from fprime_gds.common.testing_fw.api import IntegrationTestAPI


@pytest.fixture(scope="session", autouse=True)
def start_gds(fprime_test_api_session: IntegrationTestAPI):
process = subprocess.Popen(["make", "gds-integration"], cwd=os.getcwd())

gds_working = False
timeout_time = time.time() + 30
while time.time() < timeout_time:
try:
fprime_test_api_session.send_and_assert_command(
command="CdhCore.cmdDisp.CMD_NO_OP"
)
gds_working = True
break
except Exception:
time.sleep(1)
assert gds_working

yield
process.kill()


def test_bootloader(fprime_test_api: IntegrationTestAPI):
fprime_test_api.send_command(
"ReferenceDeployment.bootloaderTrigger.TRIGGER_BOOTLOADER"
)
33 changes: 33 additions & 0 deletions FprimeZephyrReference/test/int/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import os
import signal
import subprocess
import time

import pytest
from fprime_gds.common.testing_fw.api import IntegrationTestAPI


@pytest.fixture(scope="session")
def start_gds(fprime_test_api_session: IntegrationTestAPI):
pro = subprocess.Popen(
["make", "gds-integration"],
cwd=os.getcwd(),
stdout=subprocess.PIPE,
preexec_fn=os.setsid,
)

gds_working = False
timeout_time = time.time() + 30
while time.time() < timeout_time:
try:
fprime_test_api_session.send_and_assert_command(
command="CdhCore.cmdDisp.CMD_NO_OP"
)
gds_working = True
break
except Exception:
time.sleep(1)
assert gds_working

yield
os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
8 changes: 4 additions & 4 deletions FprimeZephyrReference/test/int/imu_manager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def send_packet(fprime_test_api: IntegrationTestAPI):
)


def test_01_acceleration_telemetry(fprime_test_api: IntegrationTestAPI):
def test_01_acceleration_telemetry(fprime_test_api: IntegrationTestAPI, start_gds):
"""Test that we can get Acceleration telemetry"""
result: ChData = fprime_test_api.assert_telemetry(
"ReferenceDeployment.lsm6dsoManager.Acceleration", start="NOW", timeout=3
Expand All @@ -30,7 +30,7 @@ def test_01_acceleration_telemetry(fprime_test_api: IntegrationTestAPI):
)


def test_02_angular_velocity_telemetry(fprime_test_api: IntegrationTestAPI):
def test_02_angular_velocity_telemetry(fprime_test_api: IntegrationTestAPI, start_gds):
"""Test that we can get AngularVelocity telemetry"""
result: ChData = fprime_test_api.assert_telemetry(
"ReferenceDeployment.lsm6dsoManager.AngularVelocity", start="NOW", timeout=3
Expand All @@ -42,7 +42,7 @@ def test_02_angular_velocity_telemetry(fprime_test_api: IntegrationTestAPI):
)


def test_03_temperature_telemetry(fprime_test_api: IntegrationTestAPI):
def test_03_temperature_telemetry(fprime_test_api: IntegrationTestAPI, start_gds):
"""Test that we can get Temperature telemetry"""
result: ChData = fprime_test_api.assert_telemetry(
"ReferenceDeployment.lsm6dsoManager.Temperature", start="NOW", timeout=3
Expand All @@ -52,7 +52,7 @@ def test_03_temperature_telemetry(fprime_test_api: IntegrationTestAPI):
assert reading != 0, "Temperature reading should be non-zero"


def test_04_magnetic_field_telemetry(fprime_test_api: IntegrationTestAPI):
def test_04_magnetic_field_telemetry(fprime_test_api: IntegrationTestAPI, start_gds):
"""Test that we can get MagneticField telemetry"""
result: ChData = fprime_test_api.assert_telemetry(
"ReferenceDeployment.lis2mdlManager.MagneticField", start="NOW", timeout=3
Expand Down
6 changes: 3 additions & 3 deletions FprimeZephyrReference/test/int/rtc_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def set_time(fprime_test_api: IntegrationTestAPI, dt: datetime = None):
fprime_test_api.assert_event("ReferenceDeployment.rtcManager.TimeSet", timeout=2)


def test_01_time_set(fprime_test_api: IntegrationTestAPI):
def test_01_time_set(fprime_test_api: IntegrationTestAPI, start_gds):
"""Test that we can set the time"""

# Set time to Curiosity landing on Mars (7 minutes of terror! https://youtu.be/Ki_Af_o9Q9s)
Expand Down Expand Up @@ -91,7 +91,7 @@ def test_01_time_set(fprime_test_api: IntegrationTestAPI):
pytest.approx(event_time, abs=30) == datetime.now(timezone.utc)


def test_02_time_incrementing(fprime_test_api: IntegrationTestAPI):
def test_02_time_incrementing(fprime_test_api: IntegrationTestAPI, start_gds):
"""Test that time increments over time"""

# Fetch initial time
Expand Down Expand Up @@ -122,7 +122,7 @@ def test_02_time_incrementing(fprime_test_api: IntegrationTestAPI):
)


def test_03_time_not_set_event(fprime_test_api: IntegrationTestAPI):
def test_03_time_not_set_event(fprime_test_api: IntegrationTestAPI, start_gds):
"""Test that a TimeNotSet event is emitted when setting time with invalid data"""

# Clear histories
Expand Down
6 changes: 3 additions & 3 deletions FprimeZephyrReference/test/int/watchdog_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ def get_watchdog_transitions(fprime_test_api: IntegrationTestAPI) -> int:
return result.get_val()


def test_01_watchdog_telemetry_basic(fprime_test_api: IntegrationTestAPI):
def test_01_watchdog_telemetry_basic(fprime_test_api: IntegrationTestAPI, start_gds):
"""Test that we can read WatchdogTransitions telemetry"""
value = get_watchdog_transitions(fprime_test_api)
assert value >= 0, f"WatchdogTransitions should be >= 0, got {value}"


def test_02_watchdog_increments(fprime_test_api: IntegrationTestAPI):
def test_02_watchdog_increments(fprime_test_api: IntegrationTestAPI, start_gds):
"""Test that WatchdogTransitions increments over time"""

initial_value = get_watchdog_transitions(fprime_test_api)
Expand All @@ -59,7 +59,7 @@ def test_02_watchdog_increments(fprime_test_api: IntegrationTestAPI):
)


def test_03_stop_watchdog_command(fprime_test_api: IntegrationTestAPI):
def test_03_stop_watchdog_command(fprime_test_api: IntegrationTestAPI, start_gds):
"""
Test STOP_WATCHDOG command sends and emits WatchdogStop
event and WatchdogTransitions stops incrementing
Expand Down
16 changes: 13 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,13 @@ build-ci:
@$(UV) run fprime-util build

.PHONY: test-integration
test-integration:
test-integration: uv
@$(UV) run pytest FprimeZephyrReference/test/int --deployment build-artifacts/zephyr/fprime-zephyr-deployment

.PHONY: bootloader
bootloader: uv
@$(UV) run pytest FprimeZephyrReference/test/bootloader_trigger.py --deployment build-artifacts/zephyr/fprime-zephyr-deployment

.PHONY: clean
clean: ## Remove all gitignored files
git clean -dfX
Expand All @@ -84,11 +88,17 @@ clean-zephyr-sdk: ## Remove Zephyr SDK (reinstall with 'make zephyr-setup')

##@ Operations

.PHONY: gds
GDS_COMMAND ?= $(UV) run fprime-gds -n --dictionary $(ARTIFACT_DIR)/zephyr/fprime-zephyr-deployment/dict/ReferenceDeploymentTopologyDictionary.json --communication-selection uart --uart-baud 115200 --output-unframed-data
ARTIFACT_DIR ?= $(shell pwd)/build-artifacts

.PHONY: gds
gds: ## Run FPrime GDS
@echo "Running FPrime GDS..."
@$(UV) run fprime-gds -n --dictionary $(ARTIFACT_DIR)/zephyr/fprime-zephyr-deployment/dict/ReferenceDeploymentTopologyDictionary.json --communication-selection uart --uart-baud 115200 --output-unframed-data
@$(GDS_COMMAND)

.PHONY: gds-integration
gds-integration:
@$(GDS_COMMAND) --gui=none

##@ Build Tools

Expand Down
Loading
Loading