simulate-circuitpython-nativesim 1.0.2__tar.gz → 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/PKG-INFO +53 -4
- simulate_circuitpython_nativesim-2.0.0/README.md +69 -0
- simulate_circuitpython_nativesim-2.0.0/VERSION +1 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0/build-firmware}/action.yml +27 -56
- simulate_circuitpython_nativesim-2.0.0/circuitpy_sim.py +119 -0
- simulate_circuitpython_nativesim-2.0.0/prepare-flash/action.yml +37 -0
- simulate_circuitpython_nativesim-2.0.0/prepare-system/action.yml +20 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/pyproject.toml +2 -1
- simulate_circuitpython_nativesim-2.0.0/simulate/action.yml +41 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/simulate_circuitpython_nativesim.egg-info/PKG-INFO +53 -4
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/simulate_circuitpython_nativesim.egg-info/SOURCES.txt +4 -3
- simulate_circuitpython_nativesim-2.0.0/simulate_circuitpython_nativesim.egg-info/entry_points.txt +3 -0
- simulate_circuitpython_nativesim-1.0.2/README.md +0 -20
- simulate_circuitpython_nativesim-1.0.2/VERSION +0 -1
- simulate_circuitpython_nativesim-1.0.2/circuitpy_sim.py +0 -70
- simulate_circuitpython_nativesim-1.0.2/scripts/prepare.py +0 -32
- simulate_circuitpython_nativesim-1.0.2/scripts/simulate.py +0 -8
- simulate_circuitpython_nativesim-1.0.2/simulate_circuitpython_nativesim.egg-info/entry_points.txt +0 -2
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/.github/workflows/publish.yml +0 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/.pre-commit-config.yaml +0 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/LICENSE +0 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/LICENSES/MIT.txt +0 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/LICENSES/Unlicense.txt +0 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/README.md.license +0 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/VERSION.license +0 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/setup.cfg +0 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/simulate_circuitpython_nativesim.egg-info/dependency_links.txt +0 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/simulate_circuitpython_nativesim.egg-info/requires.txt +0 -0
- {simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/simulate_circuitpython_nativesim.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simulate-circuitpython-nativesim
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Simulate CircuitPython using Zephyr simulator
|
|
5
5
|
Author-email: Alec Delaney <tekktrik@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -18,17 +18,66 @@ Requires-Dist: pre-commit~=4.5; extra == "dev"
|
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
20
20
|
# simulate-circuitpython-nativesim
|
|
21
|
+
|
|
21
22
|
Simulate CircuitPython using Zephyr simulator
|
|
22
23
|
|
|
23
|
-
##
|
|
24
|
+
## prepare-system
|
|
25
|
+
|
|
26
|
+
Prepare the runner for the simulator (and possible build process)
|
|
27
|
+
|
|
28
|
+
### Inputs
|
|
29
|
+
|
|
30
|
+
None
|
|
31
|
+
|
|
32
|
+
### Outputs
|
|
33
|
+
|
|
34
|
+
None
|
|
35
|
+
|
|
36
|
+
## build-firmware
|
|
37
|
+
|
|
38
|
+
Build the nativesim firmware (or use a cached version if available)
|
|
39
|
+
|
|
40
|
+
### Inputs
|
|
24
41
|
|
|
25
42
|
| Argument Name | Description | Default | Notes |
|
|
26
43
|
| --- | --- | --- | --- |
|
|
27
44
|
| ``version`` | Version of CircuitPython to simulate | ``main`` | Must be a version that supports the Zephyr OS native sim |
|
|
28
|
-
| ``circuitpy`` | Filepath to file or folder of files to add to the simualted CIRCUITPY | "" | If an empty string (default), this action merely sets up the environment for the simulator |
|
|
29
45
|
| ``circuitpython-folder`` | Folder name to use for the CircuitPython checkout | ``cpysim`` | Change this if it conflicts with another file/folder |
|
|
46
|
+
| ``firmware-filepath`` | Filepath for the built firmware | ``./firmware.exe`` | |
|
|
47
|
+
|
|
48
|
+
### Outputs
|
|
49
|
+
|
|
50
|
+
| Argument Name | Description | Notes |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| ``restored`` | Whether the firmware was restored from cache | |
|
|
53
|
+
|
|
54
|
+
## prepare-flash
|
|
55
|
+
|
|
56
|
+
Prepare the flash space for the simulator
|
|
57
|
+
|
|
58
|
+
### Inputs
|
|
59
|
+
|
|
60
|
+
| Argument Name | Description | Default | Notes |
|
|
61
|
+
| --- | --- | --- | --- |
|
|
62
|
+
| ``flash-filepath`` | Filepath for the desired flash binary file | ``./flash.bin`` | |
|
|
63
|
+
| ``circuitpy`` | Filepath to file or folder of files to add to the simualted CIRCUITPY | N/A (required) | |
|
|
64
|
+
|
|
65
|
+
### Outputs
|
|
66
|
+
|
|
67
|
+
None
|
|
68
|
+
|
|
69
|
+
## simulate
|
|
70
|
+
|
|
71
|
+
Run the simulator
|
|
72
|
+
|
|
73
|
+
### Inputs
|
|
74
|
+
|
|
75
|
+
| Argument Name | Description | Default | Notes |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| ``firmware-filepath`` | Filepath for the built firmware | ``./firmware.exe`` | |
|
|
78
|
+
| ``flash-filepath`` | Filepath for the desired flash binary file | ``./flash.bin`` | |
|
|
30
79
|
|
|
31
|
-
|
|
80
|
+
### Outputs
|
|
32
81
|
|
|
33
82
|
| Argument Name | Description | Notes |
|
|
34
83
|
| --- | --- | --- |
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# simulate-circuitpython-nativesim
|
|
2
|
+
|
|
3
|
+
Simulate CircuitPython using Zephyr simulator
|
|
4
|
+
|
|
5
|
+
## prepare-system
|
|
6
|
+
|
|
7
|
+
Prepare the runner for the simulator (and possible build process)
|
|
8
|
+
|
|
9
|
+
### Inputs
|
|
10
|
+
|
|
11
|
+
None
|
|
12
|
+
|
|
13
|
+
### Outputs
|
|
14
|
+
|
|
15
|
+
None
|
|
16
|
+
|
|
17
|
+
## build-firmware
|
|
18
|
+
|
|
19
|
+
Build the nativesim firmware (or use a cached version if available)
|
|
20
|
+
|
|
21
|
+
### Inputs
|
|
22
|
+
|
|
23
|
+
| Argument Name | Description | Default | Notes |
|
|
24
|
+
| --- | --- | --- | --- |
|
|
25
|
+
| ``version`` | Version of CircuitPython to simulate | ``main`` | Must be a version that supports the Zephyr OS native sim |
|
|
26
|
+
| ``circuitpython-folder`` | Folder name to use for the CircuitPython checkout | ``cpysim`` | Change this if it conflicts with another file/folder |
|
|
27
|
+
| ``firmware-filepath`` | Filepath for the built firmware | ``./firmware.exe`` | |
|
|
28
|
+
|
|
29
|
+
### Outputs
|
|
30
|
+
|
|
31
|
+
| Argument Name | Description | Notes |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| ``restored`` | Whether the firmware was restored from cache | |
|
|
34
|
+
|
|
35
|
+
## prepare-flash
|
|
36
|
+
|
|
37
|
+
Prepare the flash space for the simulator
|
|
38
|
+
|
|
39
|
+
### Inputs
|
|
40
|
+
|
|
41
|
+
| Argument Name | Description | Default | Notes |
|
|
42
|
+
| --- | --- | --- | --- |
|
|
43
|
+
| ``flash-filepath`` | Filepath for the desired flash binary file | ``./flash.bin`` | |
|
|
44
|
+
| ``circuitpy`` | Filepath to file or folder of files to add to the simualted CIRCUITPY | N/A (required) | |
|
|
45
|
+
|
|
46
|
+
### Outputs
|
|
47
|
+
|
|
48
|
+
None
|
|
49
|
+
|
|
50
|
+
## simulate
|
|
51
|
+
|
|
52
|
+
Run the simulator
|
|
53
|
+
|
|
54
|
+
### Inputs
|
|
55
|
+
|
|
56
|
+
| Argument Name | Description | Default | Notes |
|
|
57
|
+
| --- | --- | --- | --- |
|
|
58
|
+
| ``firmware-filepath`` | Filepath for the built firmware | ``./firmware.exe`` | |
|
|
59
|
+
| ``flash-filepath`` | Filepath for the desired flash binary file | ``./flash.bin`` | |
|
|
60
|
+
|
|
61
|
+
### Outputs
|
|
62
|
+
|
|
63
|
+
| Argument Name | Description | Notes |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| ``output-text`` | The text output from the simulator | |
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
This library is available under an MIT license.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
v2.0.0
|
|
@@ -1,32 +1,29 @@
|
|
|
1
1
|
# SPDX-FileCopyrightText: 2026 Alec Delaney
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
-
name: '
|
|
5
|
-
description: '
|
|
4
|
+
name: 'Build CircuitPython simulator'
|
|
5
|
+
description: 'Build the Zephyr simulator firmware'
|
|
6
6
|
inputs:
|
|
7
7
|
version:
|
|
8
8
|
description: 'Version of CircuitPython to simulate'
|
|
9
9
|
required: true
|
|
10
|
+
# TODO: Should default to latest
|
|
10
11
|
default: main
|
|
11
|
-
circuitpy:
|
|
12
|
-
description: 'Filepath to file or folder of files to add to the simualted CIRCUITPY'
|
|
13
|
-
required: true
|
|
14
|
-
default: ''
|
|
15
12
|
circuitpython-folder:
|
|
16
|
-
description: 'Folder name to use for the CircuitPython checkout'
|
|
13
|
+
description: 'Folder name to use for the CircuitPython checkout, if needed'
|
|
17
14
|
required: true
|
|
18
15
|
default: 'cpysim'
|
|
16
|
+
firmware-filepath:
|
|
17
|
+
description: 'Filepath for the built firmware'
|
|
18
|
+
required: true
|
|
19
|
+
default: './firmware.exe'
|
|
19
20
|
outputs:
|
|
20
|
-
|
|
21
|
-
description: '
|
|
22
|
-
value: ${{ steps.
|
|
21
|
+
restored:
|
|
22
|
+
description: 'Whether the firmware was restored from cache'
|
|
23
|
+
value: ${{ steps.cache-hit.outputs.cached }}
|
|
23
24
|
runs:
|
|
24
25
|
using: "composite"
|
|
25
26
|
steps:
|
|
26
|
-
- name: Setup Python 3.12
|
|
27
|
-
uses: actions/setup-python@v6
|
|
28
|
-
with:
|
|
29
|
-
python-version: 3.12
|
|
30
27
|
- name: Checkout CircuitPython repository
|
|
31
28
|
uses: actions/checkout@v6
|
|
32
29
|
with:
|
|
@@ -45,25 +42,18 @@ runs:
|
|
|
45
42
|
else
|
|
46
43
|
CACHE_KEY="${{ inputs.version }}-zephyr-cache"
|
|
47
44
|
fi
|
|
48
|
-
echo "
|
|
49
|
-
- name: Install system dependencies
|
|
50
|
-
shell: bash
|
|
51
|
-
run: |
|
|
52
|
-
sudo apt-get update
|
|
53
|
-
sudo apt-get install -y \
|
|
54
|
-
libusb-1.0-0-dev \
|
|
55
|
-
libudev-dev \
|
|
56
|
-
mtools \
|
|
57
|
-
protobuf-compiler \
|
|
58
|
-
dosfstools \
|
|
59
|
-
gcc-multilib \
|
|
60
|
-
g++-multilib
|
|
45
|
+
echo "cache-key=$CACHE_KEY" >> "$GITHUB_OUTPUT"
|
|
61
46
|
- name: Cache firmware build
|
|
62
47
|
id: cache-firmware
|
|
63
48
|
uses: actions/cache@v5
|
|
64
49
|
with:
|
|
65
|
-
path: ${{ inputs.
|
|
66
|
-
key: ${{ steps.cache-key.outputs.
|
|
50
|
+
path: ${{ inputs.firmware-filepath }}
|
|
51
|
+
key: ${{ steps.cache-key.outputs.cache-key }}
|
|
52
|
+
- name: Setup Python 3.12
|
|
53
|
+
uses: actions/setup-python@v6
|
|
54
|
+
if: steps.cache-firmware.outputs.cache-hit != 'true'
|
|
55
|
+
with:
|
|
56
|
+
python-version: 3.12
|
|
67
57
|
- name: Fetch submodules
|
|
68
58
|
shell: bash
|
|
69
59
|
working-directory: ${{ inputs.circuitpython-folder }}/ports/zephyr-cp
|
|
@@ -111,32 +101,13 @@ runs:
|
|
|
111
101
|
working-directory: ${{ inputs.circuitpython-folder }}/ports/zephyr-cp
|
|
112
102
|
if: steps.cache-firmware.outputs.cache-hit != 'true'
|
|
113
103
|
run: make BOARD=native_native_sim BUILD=build-native_native_sim build-native_native_sim/firmware.exe
|
|
114
|
-
- name:
|
|
115
|
-
shell: bash
|
|
116
|
-
working-directory: ${{ inputs.circuitpython-folder }}/ports/zephyr-cp
|
|
117
|
-
run: |
|
|
118
|
-
truncate -s 2M build-native_native_sim/flash.bin
|
|
119
|
-
mformat -i build-native_native_sim/flash.bin ::
|
|
120
|
-
- name: Create CIRCUITPY folder
|
|
121
|
-
shell: bash
|
|
122
|
-
run: |
|
|
123
|
-
python ${{ github.action_path }}/scripts/prepare.py ${{ inputs.circuitpy }} ${{ inputs.circuitpython-folder }}/ports/zephyr-cp
|
|
124
|
-
- name: Add files to flash
|
|
104
|
+
- name: Move firmware executable
|
|
125
105
|
shell: bash
|
|
126
|
-
|
|
127
|
-
run:
|
|
128
|
-
- name:
|
|
129
|
-
|
|
130
|
-
run: pipx install ${{ github.action_path }}
|
|
131
|
-
- name: Run simulator script
|
|
132
|
-
id: run-sim
|
|
106
|
+
if: steps.cache-firmware.outputs.cache-hit != 'true'
|
|
107
|
+
run: mv ${{ inputs.circuitpython-folder }}/ports/zephyr-cp/build-native_native_sim/firmware.exe ${{ inputs.firmware-filepath }}
|
|
108
|
+
- name: Mark firmware as restored from cache
|
|
109
|
+
id: cache-hit
|
|
133
110
|
shell: bash
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
SIM_OUTPUT=$(simulate-circuitpython)
|
|
138
|
-
{
|
|
139
|
-
echo "simout<<EOF"
|
|
140
|
-
echo "$SIM_OUTPUT"
|
|
141
|
-
echo "EOF"
|
|
142
|
-
} >> "$GITHUB_OUTPUT"
|
|
111
|
+
run: echo "cached=${{ steps.cache-firmware.outputs.cache-hit }}" >> "$GITHUB_OUTPUT"
|
|
112
|
+
|
|
113
|
+
# TODO: Upload firmware as an artifact
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries
|
|
2
|
+
# SPDX-FileCopyrightText: Copyright (c) 2026 Alec Delaney
|
|
3
|
+
#
|
|
4
|
+
# SPDX-License-Identifier: MIT
|
|
5
|
+
|
|
6
|
+
"""Slim and simple version of the CircuitPython Zephyr test infrastructure."""
|
|
7
|
+
|
|
8
|
+
import pathlib
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def simulate(firmware_filepath: str, flash_filepath: str, timeout: int = 5) -> str:
|
|
14
|
+
"""Simulate using the native sim firmware."""
|
|
15
|
+
firmware_path = pathlib.Path(firmware_filepath).absolute()
|
|
16
|
+
flash_path = pathlib.Path(flash_filepath).absolute()
|
|
17
|
+
|
|
18
|
+
cmd = [
|
|
19
|
+
str(firmware_path),
|
|
20
|
+
f"--flash={str(flash_path)}",
|
|
21
|
+
"-rt",
|
|
22
|
+
"-uart_stdinout",
|
|
23
|
+
f"-stop_at={timeout}",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
simproc = subprocess.Popen(
|
|
27
|
+
cmd,
|
|
28
|
+
stdin=subprocess.PIPE,
|
|
29
|
+
stdout=subprocess.PIPE,
|
|
30
|
+
stderr=None,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
if simproc.stdout is None:
|
|
34
|
+
raise RuntimeError("Failed to capture simulator output")
|
|
35
|
+
|
|
36
|
+
recording: bool | None = None
|
|
37
|
+
recorded = ""
|
|
38
|
+
|
|
39
|
+
while simproc.poll() is None:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
output: str = simproc.stdout.read().decode()
|
|
43
|
+
for line in output.split("\n"):
|
|
44
|
+
encoded = line.encode()
|
|
45
|
+
if not line:
|
|
46
|
+
continue
|
|
47
|
+
if encoded.strip() == b"\x1b[2K\x1b[0Gcode.py output:" and recording is None:
|
|
48
|
+
recording = True
|
|
49
|
+
elif line.strip() == "Code done running." and recording:
|
|
50
|
+
recording = False
|
|
51
|
+
break
|
|
52
|
+
elif recording:
|
|
53
|
+
recorded += line + "\n"
|
|
54
|
+
|
|
55
|
+
return recorded.strip()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def prepare_flash(flash_filepath: str, circuitpy_filepath: str) -> None:
|
|
59
|
+
"""Prepare the native sim flash."""
|
|
60
|
+
flash_path = str(pathlib.Path(flash_filepath).absolute())
|
|
61
|
+
circuitpy_abspath = pathlib.Path(circuitpy_filepath).absolute()
|
|
62
|
+
|
|
63
|
+
subprocess.run(
|
|
64
|
+
[
|
|
65
|
+
"truncate",
|
|
66
|
+
"-s",
|
|
67
|
+
"2M",
|
|
68
|
+
f"{flash_path}",
|
|
69
|
+
],
|
|
70
|
+
timeout=5,
|
|
71
|
+
check=True,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
subprocess.run(
|
|
75
|
+
[
|
|
76
|
+
"mformat",
|
|
77
|
+
"-i",
|
|
78
|
+
f"{flash_path}",
|
|
79
|
+
"::",
|
|
80
|
+
],
|
|
81
|
+
timeout=5,
|
|
82
|
+
check=True,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
mcopy_cmd = [
|
|
86
|
+
"mcopy",
|
|
87
|
+
"-s",
|
|
88
|
+
"-i",
|
|
89
|
+
f"{flash_path}",
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
files = [str(path) for path in circuitpy_abspath.glob("*")]
|
|
93
|
+
mcopy_cmd.extend(files)
|
|
94
|
+
mcopy_cmd.append("::")
|
|
95
|
+
|
|
96
|
+
subprocess.run(
|
|
97
|
+
mcopy_cmd,
|
|
98
|
+
timeout=5,
|
|
99
|
+
check=True,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def simulate_circuitpython_cmdline() -> None:
|
|
104
|
+
"""Simulate CircuitPython using a simulator."""
|
|
105
|
+
firmware_filepath = sys.argv[1]
|
|
106
|
+
flash_filepath = sys.argv[2]
|
|
107
|
+
result = simulate(firmware_filepath, flash_filepath)
|
|
108
|
+
print(result)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def prepare_flash_cmdline() -> None:
|
|
112
|
+
"""Prepare flash for the simulator."""
|
|
113
|
+
flash_filepath = sys.argv[1]
|
|
114
|
+
circuitpy_filepath = sys.argv[2]
|
|
115
|
+
prepare_flash(flash_filepath, circuitpy_filepath)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
if __name__ == "__main__":
|
|
119
|
+
simulate_circuitpython_cmdline()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Alec Delaney
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
name: 'Simulate CircuitPython'
|
|
5
|
+
description: 'Simulate CircuitPython using Zephyr simulator'
|
|
6
|
+
inputs:
|
|
7
|
+
flash-filepath:
|
|
8
|
+
description: 'Filepath for the desired flash binary file'
|
|
9
|
+
required: true
|
|
10
|
+
default: './flash.bin'
|
|
11
|
+
circuitpy:
|
|
12
|
+
description: 'Filepath to file or folder of files to add to the simualted CIRCUITPY'
|
|
13
|
+
required: true
|
|
14
|
+
runs:
|
|
15
|
+
using: "composite"
|
|
16
|
+
steps:
|
|
17
|
+
- name: Install system dependencies
|
|
18
|
+
shell: bash
|
|
19
|
+
run: |
|
|
20
|
+
sudo apt-get update
|
|
21
|
+
sudo apt-get install -y \
|
|
22
|
+
libusb-1.0-0-dev \
|
|
23
|
+
libudev-dev \
|
|
24
|
+
mtools \
|
|
25
|
+
protobuf-compiler \
|
|
26
|
+
dosfstools \
|
|
27
|
+
gcc-multilib \
|
|
28
|
+
g++-multilib
|
|
29
|
+
- name: Install flash preparation command
|
|
30
|
+
shell: bash
|
|
31
|
+
run: pipx install ${{ github.action_path }}/..
|
|
32
|
+
- name: Create flash space
|
|
33
|
+
shell: bash
|
|
34
|
+
run: prepare-flash ${{ inputs.flash-filepath }} ${{ inputs.circuitpy }}
|
|
35
|
+
- name: Uninstall flash preparation command
|
|
36
|
+
shell: bash
|
|
37
|
+
run: pipx uninstall simulate-circuitpython-nativesim
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Alec Delaney
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
name: 'Prepare system'
|
|
5
|
+
description: 'Prepare the system for building/running the simulator'
|
|
6
|
+
runs:
|
|
7
|
+
using: "composite"
|
|
8
|
+
steps:
|
|
9
|
+
- name: Install system dependencies
|
|
10
|
+
shell: bash
|
|
11
|
+
run: |
|
|
12
|
+
sudo apt-get update
|
|
13
|
+
sudo apt-get install -y \
|
|
14
|
+
libusb-1.0-0-dev \
|
|
15
|
+
libudev-dev \
|
|
16
|
+
mtools \
|
|
17
|
+
protobuf-compiler \
|
|
18
|
+
dosfstools \
|
|
19
|
+
gcc-multilib \
|
|
20
|
+
g++-multilib
|
{simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/pyproject.toml
RENAMED
|
@@ -41,7 +41,8 @@ dev = [
|
|
|
41
41
|
]
|
|
42
42
|
|
|
43
43
|
[project.scripts]
|
|
44
|
-
simulate-circuitpython = "circuitpy_sim:
|
|
44
|
+
simulate-circuitpython = "circuitpy_sim:simulate_circuitpython_cmdline"
|
|
45
|
+
prepare-flash = "circuitpy_sim:prepare_flash_cmdline"
|
|
45
46
|
|
|
46
47
|
[tool.setuptools]
|
|
47
48
|
py-modules = ["circuitpy_sim"]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Alec Delaney
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
name: 'Simulate CircuitPython'
|
|
5
|
+
description: 'Simulate CircuitPython using Zephyr simulator'
|
|
6
|
+
inputs:
|
|
7
|
+
firmware-filepath:
|
|
8
|
+
description: 'Filepath to firmware executable file'
|
|
9
|
+
required: true
|
|
10
|
+
default: './firmware.exe'
|
|
11
|
+
flash-filepath:
|
|
12
|
+
description: 'Filepath to flash binary file'
|
|
13
|
+
required: true
|
|
14
|
+
default: './flash.bin'
|
|
15
|
+
outputs:
|
|
16
|
+
output-text:
|
|
17
|
+
description: 'The text output from the simulator'
|
|
18
|
+
value: ${{ steps.run-sim.outputs.simout }}
|
|
19
|
+
runs:
|
|
20
|
+
using: "composite"
|
|
21
|
+
steps:
|
|
22
|
+
- name: Setup Python 3.12
|
|
23
|
+
uses: actions/setup-python@v6
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.12"
|
|
26
|
+
- name: Install simulator command
|
|
27
|
+
shell: bash
|
|
28
|
+
run: pipx install ${{ github.action_path }}/..
|
|
29
|
+
- name: Run simulator script
|
|
30
|
+
id: run-sim
|
|
31
|
+
shell: bash
|
|
32
|
+
run: |
|
|
33
|
+
SIM_OUTPUT=$(simulate-circuitpython ${{ inputs.firmware-filepath }} ${{ inputs.flash-filepath }})
|
|
34
|
+
{
|
|
35
|
+
echo "simout<<EOF"
|
|
36
|
+
echo "$SIM_OUTPUT"
|
|
37
|
+
echo "EOF"
|
|
38
|
+
} >> "$GITHUB_OUTPUT"
|
|
39
|
+
- name: Uninstall simulator script
|
|
40
|
+
shell: bash
|
|
41
|
+
run: pipx uninstall simulate-circuitpython-nativesim
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simulate-circuitpython-nativesim
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Simulate CircuitPython using Zephyr simulator
|
|
5
5
|
Author-email: Alec Delaney <tekktrik@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -18,17 +18,66 @@ Requires-Dist: pre-commit~=4.5; extra == "dev"
|
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
20
20
|
# simulate-circuitpython-nativesim
|
|
21
|
+
|
|
21
22
|
Simulate CircuitPython using Zephyr simulator
|
|
22
23
|
|
|
23
|
-
##
|
|
24
|
+
## prepare-system
|
|
25
|
+
|
|
26
|
+
Prepare the runner for the simulator (and possible build process)
|
|
27
|
+
|
|
28
|
+
### Inputs
|
|
29
|
+
|
|
30
|
+
None
|
|
31
|
+
|
|
32
|
+
### Outputs
|
|
33
|
+
|
|
34
|
+
None
|
|
35
|
+
|
|
36
|
+
## build-firmware
|
|
37
|
+
|
|
38
|
+
Build the nativesim firmware (or use a cached version if available)
|
|
39
|
+
|
|
40
|
+
### Inputs
|
|
24
41
|
|
|
25
42
|
| Argument Name | Description | Default | Notes |
|
|
26
43
|
| --- | --- | --- | --- |
|
|
27
44
|
| ``version`` | Version of CircuitPython to simulate | ``main`` | Must be a version that supports the Zephyr OS native sim |
|
|
28
|
-
| ``circuitpy`` | Filepath to file or folder of files to add to the simualted CIRCUITPY | "" | If an empty string (default), this action merely sets up the environment for the simulator |
|
|
29
45
|
| ``circuitpython-folder`` | Folder name to use for the CircuitPython checkout | ``cpysim`` | Change this if it conflicts with another file/folder |
|
|
46
|
+
| ``firmware-filepath`` | Filepath for the built firmware | ``./firmware.exe`` | |
|
|
47
|
+
|
|
48
|
+
### Outputs
|
|
49
|
+
|
|
50
|
+
| Argument Name | Description | Notes |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| ``restored`` | Whether the firmware was restored from cache | |
|
|
53
|
+
|
|
54
|
+
## prepare-flash
|
|
55
|
+
|
|
56
|
+
Prepare the flash space for the simulator
|
|
57
|
+
|
|
58
|
+
### Inputs
|
|
59
|
+
|
|
60
|
+
| Argument Name | Description | Default | Notes |
|
|
61
|
+
| --- | --- | --- | --- |
|
|
62
|
+
| ``flash-filepath`` | Filepath for the desired flash binary file | ``./flash.bin`` | |
|
|
63
|
+
| ``circuitpy`` | Filepath to file or folder of files to add to the simualted CIRCUITPY | N/A (required) | |
|
|
64
|
+
|
|
65
|
+
### Outputs
|
|
66
|
+
|
|
67
|
+
None
|
|
68
|
+
|
|
69
|
+
## simulate
|
|
70
|
+
|
|
71
|
+
Run the simulator
|
|
72
|
+
|
|
73
|
+
### Inputs
|
|
74
|
+
|
|
75
|
+
| Argument Name | Description | Default | Notes |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| ``firmware-filepath`` | Filepath for the built firmware | ``./firmware.exe`` | |
|
|
78
|
+
| ``flash-filepath`` | Filepath for the desired flash binary file | ``./flash.bin`` | |
|
|
30
79
|
|
|
31
|
-
|
|
80
|
+
### Outputs
|
|
32
81
|
|
|
33
82
|
| Argument Name | Description | Notes |
|
|
34
83
|
| --- | --- | --- |
|
|
@@ -4,14 +4,15 @@ README.md
|
|
|
4
4
|
README.md.license
|
|
5
5
|
VERSION
|
|
6
6
|
VERSION.license
|
|
7
|
-
action.yml
|
|
8
7
|
circuitpy_sim.py
|
|
9
8
|
pyproject.toml
|
|
10
9
|
.github/workflows/publish.yml
|
|
11
10
|
LICENSES/MIT.txt
|
|
12
11
|
LICENSES/Unlicense.txt
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
build-firmware/action.yml
|
|
13
|
+
prepare-flash/action.yml
|
|
14
|
+
prepare-system/action.yml
|
|
15
|
+
simulate/action.yml
|
|
15
16
|
simulate_circuitpython_nativesim.egg-info/PKG-INFO
|
|
16
17
|
simulate_circuitpython_nativesim.egg-info/SOURCES.txt
|
|
17
18
|
simulate_circuitpython_nativesim.egg-info/dependency_links.txt
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# simulate-circuitpython-nativesim
|
|
2
|
-
Simulate CircuitPython using Zephyr simulator
|
|
3
|
-
|
|
4
|
-
## Inputs
|
|
5
|
-
|
|
6
|
-
| Argument Name | Description | Default | Notes |
|
|
7
|
-
| --- | --- | --- | --- |
|
|
8
|
-
| ``version`` | Version of CircuitPython to simulate | ``main`` | Must be a version that supports the Zephyr OS native sim |
|
|
9
|
-
| ``circuitpy`` | Filepath to file or folder of files to add to the simualted CIRCUITPY | "" | If an empty string (default), this action merely sets up the environment for the simulator |
|
|
10
|
-
| ``circuitpython-folder`` | Folder name to use for the CircuitPython checkout | ``cpysim`` | Change this if it conflicts with another file/folder |
|
|
11
|
-
|
|
12
|
-
## Outputs
|
|
13
|
-
|
|
14
|
-
| Argument Name | Description | Notes |
|
|
15
|
-
| --- | --- | --- |
|
|
16
|
-
| ``output-text`` | The text output from the simulator | |
|
|
17
|
-
|
|
18
|
-
## License
|
|
19
|
-
|
|
20
|
-
This library is available under an MIT license.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
v1.0.2
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries
|
|
2
|
-
# SPDX-FileCopyrightText: Copyright (c) 2026 Alec Delaney
|
|
3
|
-
#
|
|
4
|
-
# SPDX-License-Identifier: MIT
|
|
5
|
-
|
|
6
|
-
"""Slim and simple version of the CircuitPython Zephyr test infrastructure."""
|
|
7
|
-
|
|
8
|
-
import subprocess
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class Simualtor:
|
|
12
|
-
"""Zephyr OS native sim wrapper."""
|
|
13
|
-
|
|
14
|
-
def __init__(self, timeout: int = 5) -> None:
|
|
15
|
-
"""Intialize the simulator."""
|
|
16
|
-
self.simproc: subprocess.Popen | None = None
|
|
17
|
-
self.cmd = [
|
|
18
|
-
"build-native_native_sim/firmware.exe",
|
|
19
|
-
"--flash=build-native_native_sim/flash.bin",
|
|
20
|
-
"-rt",
|
|
21
|
-
"-uart_stdinout",
|
|
22
|
-
f"-stop_at={timeout}",
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
def simulate(self) -> str:
|
|
26
|
-
"""Simulate using the native sim firmware."""
|
|
27
|
-
self.simproc = subprocess.Popen(
|
|
28
|
-
self.cmd,
|
|
29
|
-
stdin=subprocess.PIPE,
|
|
30
|
-
stdout=subprocess.PIPE,
|
|
31
|
-
stderr=None,
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
if self.simproc.stdout is None:
|
|
35
|
-
raise RuntimeError("Failed to capture simulator output")
|
|
36
|
-
|
|
37
|
-
recording: bool | None = None
|
|
38
|
-
recorded = ""
|
|
39
|
-
|
|
40
|
-
while self.simproc.poll() is None:
|
|
41
|
-
pass
|
|
42
|
-
|
|
43
|
-
output: str = self.simproc.stdout.read().decode()
|
|
44
|
-
for line in output.split("\n"):
|
|
45
|
-
encoded = line.encode()
|
|
46
|
-
if not line:
|
|
47
|
-
continue
|
|
48
|
-
if (
|
|
49
|
-
encoded.strip() == b"\x1b[2K\x1b[0Gcode.py output:"
|
|
50
|
-
and recording is None
|
|
51
|
-
):
|
|
52
|
-
recording = True
|
|
53
|
-
elif line.strip() == "Code done running." and recording:
|
|
54
|
-
recording = False
|
|
55
|
-
break
|
|
56
|
-
elif recording:
|
|
57
|
-
recorded += line + "\n"
|
|
58
|
-
|
|
59
|
-
return recorded.strip()
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def simulate_circuitpython() -> None:
|
|
63
|
-
"""Simulate CircuitPython using a simulator."""
|
|
64
|
-
simulator = Simualtor()
|
|
65
|
-
result = simulator.simulate()
|
|
66
|
-
print(result)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if __name__ == "__main__":
|
|
70
|
-
simulate_circuitpython()
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2026 Alec Delaney
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
|
|
4
|
-
"""Prepare the CIRCUITPY drive."""
|
|
5
|
-
|
|
6
|
-
import pathlib
|
|
7
|
-
import shutil
|
|
8
|
-
import sys
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def prepare():
|
|
12
|
-
"""Prepare the CIRCUITPY drive folder."""
|
|
13
|
-
src = pathlib.Path(sys.argv[1])
|
|
14
|
-
dst = pathlib.Path(sys.argv[2])
|
|
15
|
-
|
|
16
|
-
if not src.exists():
|
|
17
|
-
print(f"Filepath {src.absolute()} does not exist")
|
|
18
|
-
sys.exit(1)
|
|
19
|
-
|
|
20
|
-
circuitpy = dst / "CIRCUITPY"
|
|
21
|
-
circuitpy.mkdir()
|
|
22
|
-
|
|
23
|
-
if src.is_file():
|
|
24
|
-
print(f"Copying file {src} to {circuitpy}")
|
|
25
|
-
shutil.copy(src, circuitpy)
|
|
26
|
-
else:
|
|
27
|
-
print(f"Copying folder {src} to {circuitpy}")
|
|
28
|
-
shutil.copytree(src, circuitpy, dirs_exist_ok=True)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if __name__ == "__main__":
|
|
32
|
-
prepare()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/LICENSES/MIT.txt
RENAMED
|
File without changes
|
|
File without changes
|
{simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/README.md.license
RENAMED
|
File without changes
|
{simulate_circuitpython_nativesim-1.0.2 → simulate_circuitpython_nativesim-2.0.0}/VERSION.license
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|