8000 Add Zephyr port · jepler/circuitpython@7f0cc9e · GitHub
[go: up one dir, main page]

Skip to content

Commit 7f0cc9e

Browse files
committed
Add Zephyr port
This port is meant to grow to encompass all existing boards. For now, it is a port while we transition over. It is named `zephyr-cp` to differentiate it from the MicroPython `zephyr` port. They are separate implementations.
1 parent 11711fd commit 7f0cc9e

File tree

140 files changed

+10322
-294
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

140 files changed

+10322
-294
lines changed

.github/actions/deps/external/action.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ runs:
2222
if: >-
2323
inputs.port != 'none' &&
2424
inputs.port != 'litex' &&
25-
inputs.port != 'espressif'
25+
inputs.port != 'espressif' &&
26+
inputs.port != 'zephyr-cp'
2627
uses: carlosperate/arm-none-eabi-gcc-action@v1
2728
with:
2829
# When changing this update what Windows grabs too!
@@ -51,7 +52,7 @@ runs:
5152

5253
# common
5354
- name: Cache python dependencies
54-
if: inputs.port != 'espressif'
55+
if: inputs.port != 'espressif' && inputs.port != 'zephyr-cp'
5556
uses: ./.github/actions/deps/python
5657
with:
5758
action: ${{ inputs.action }}

.github/actions/deps/ports/action.yml

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,29 @@ inputs:
44
board:
55
required: true
66
type: string
7-
8-
outputs:
97
port:
10-
value: ${{ steps.board-to-port.outputs.port }}
8+
required: true
9+
type: string
1110

1211
runs:
1312
using: composite
1413
steps:
15-
- name: Board to port
16-
id: board-to-port
17-
run: |
18-
PORT=$(find ports/*/boards/ -type d -name ${{ inputs.board }} | sed 's/^ports\///g;s/\/boards.*//g')
19-
if [ -z $PORT ]; then (exit 1); else echo >> $GITHUB_OUTPUT "port=$PORT"; fi
20-
shell: bash
21-
2214
- name: Set up broadcom
23-
if: steps.board-to-port.outputs.port == 'broadcom'
15+
if: inputs.port == 'broadcom'
2416
uses: ./.github/actions/deps/ports/broadcom
2517

2618
- name: Set up espressif
27-
if: steps.board-to-port.outputs.port == 'espressif'
19+
if: inputs.port == 'espressif'
2820
uses: ./.github/actions/deps/ports/espressif
2921

3022
- name: Set up litex
31-
if: steps.board-to-port.outputs.port == 'litex'
23+
if: inputs.port == 'litex'
3224
uses: ./.github/actions/deps/ports/litex
3325

3426
- name: Set up nordic
35-
if: steps.board-to-port.outputs.port == 'nordic'
27+
if: inputs.port == 'nordic'
3628
uses: ./.github/actions/deps/ports/nordic
29+
30+
- name: Set up Zephyr
31+
if: inputs.port == 'zephyr-cp'
32+
uses: ./.github/actions/deps/ports/zephyr-cp
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Fetch Zephyr port deps
2+
3+
runs:
4+
using: composite
5+
steps:
6+
- name: Setup Zephyr project
7+
uses: zephyrproject-rtos/action-zephyr-setup@v1
8+
with:
9+
app-path: zephyr-config
10+
base-path: ports/zephyr-cp
11+
toolchains: arm-zephyr-eabi
12+
- name: Export cmake info
13+
run: west zephyr-export
14+
shell: bash
15+
working-directory: ports/zephyr-cp

.github/actions/deps/submodules/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ runs:
8080
git fetch --no-recurse-submodules --shallow-since="2021-07-01" origin $GITHUB_SHA
8181
git repack -d
8282
echo "::endgroup::"
83-
CP_VERSION=$(tools/describe)
83+
CP_VERSION=$(python py/version.py)
8484
echo "$CP_VERSION"
8585
echo "CP_VERSION=$CP_VERSION" >> $GITHUB_ENV
8686
echo "cp-version=$CP_VERSION" >> $GITHUB_OUTPUT

.github/workflows/build-board-custom.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ jobs:
9797
download: false
9898
- name: Versions
9999
run: |
100-
tools/describe
100+
python py/version.py
101101
gcc --version
102102
python3 --version
103103
cmake --version || true

.github/workflows/build-boards.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ on:
99
cp-version:
1010
required: true
1111
type: string
12+
port:
13+
required: true
14+
type: string
1215
secrets:
1316
AWS_ACCESS_KEY_ID:
1417
required: false
@@ -43,6 +46,7 @@ jobs:
4346
uses: ./.github/actions/deps/ports
4447
with:
4548
board: ${{ matrix.board }}
49+
port: ${{ inputs.port }}
4650

4751
- name: Set up submodules
4852
id: set-up-submodules
@@ -51,7 +55,7 @@ jobs:
5155
- name: Set up external
5256
uses: ./.github/actions/deps/external
5357
with:
54-
port: ${{ steps.set-up-port.outputs.port }}
58+
port: ${{ inputs.port }}
5559
- name: Set up mpy-cross
5660
if: steps.set-up-submodules.outputs.frozen == 'True'
5761
uses: ./.github/actions/mpy_cross

.github/workflows/build.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,35 @@ jobs:
299299
# ERROR: Platform MINGW64_NT-10.0-17763-x86_64 appears to be unsupported
300300
# https://github.com/espressif/esp-idf/issues/7062
301301

302+
windows-zephyr:
303+
strategy:
304+
matrix:
305+
os: [windows-2022, windows-2025]
306+
runs-on: ${{ matrix.os }}
307+
needs: scheduler
308+
if: needs.scheduler.outputs.windows == 'True'
309+
env:
310+
CP_VERSION: ${{ needs.scheduler.outputs.cp-version }}
311+
steps:
312+
- name: Set up repository
313+
uses: actions/checkout@v4
314+
with:
315+
submodules: false
316+
show-progress: false
317+
fetch-depth: 1
318+
persist-credentials: false
319+
- uses: actions/setup-python@v5
320+
with:
321+
python-version: '3.13'
322+
- name: Set up Zephyr
323+
uses: ./.github/actions/deps/ports/zephyr-cp
324+
- name: Set up submodules
325+
uses: ./.github/actions/deps/submodules
326+
- name: build mpy-cross
327+
run: make -j4 -C mpy-cross
328+
- name: build ek_ra8d1
329+
run: make -j4 -C ports/zephyr-cp BOARD=renesas_ek_ra8d1
330+
302331
ports:
303332
needs: [scheduler, mpy-cross, tests]
304333
if: needs.scheduler.outputs.ports != '{}'
@@ -311,3 +340,4 @@ jobs:
311340
with:
312341
boards: ${{ toJSON(fromJSON(needs.scheduler.outputs.ports)[matrix.port]) }}
313342
cp-version: ${{ needs.scheduler.outputs.cp-version }}
343+
port: ${{ matrix.port }}

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ repos:
2525
tests/unicode/data/utf-8_invalid.txt|
2626
tests/extmod/data/qr.pgm|
2727
tests/basics/bytearray_byte_operations.py|
28-
ports/raspberrypi/sdk
28+
ports/raspberrypi/sdk|
29+
ports/zephyr-cp/cptools/compat2driver.py
2930
)
3031
- repo: local
3132
hooks:

conf.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
from sphinx import addnodes
3333
from sphinx.ext import intersphinx
3434

35-
tools_describe = str(pathlib.Path(__file__).parent / "tools/describe")
36-
3735
# If extensions (or modules to document with autodoc) are in another directory,
3836
# add these directories to sys.path here. If the directory is relative to the
3937
# documentation root, use os.path.abspath to make it absolute, like shown here.
@@ -145,7 +143,7 @@ def autoapi_prepare_jinja_env(jinja_env):
145143

146144
final_version = ""
147145
git_describe = subprocess.run(
148-
[tools_describe],
146+
["python", "py/version.py"],
149147
stdout=subprocess.PIPE,
150148
stderr=subprocess.STDOUT,
151149
encoding="utf-8"

docs/shared_bindings_matrix.py

Lines changed: 68 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import pathlib
2727
import re
2828
import subprocess
29-
29+
import tomllib
3030

3131
from concurrent.futures import ThreadPoolExecutor
3232

@@ -43,6 +43,7 @@
4343
"renode",
4444
"silabs",
4545
"stm",
46+
"zephyr-cp",
4647
]
4748

4849
ALIASES_BY_BOARD = {
@@ -130,21 +131,29 @@ def get_board_mapping():
130131
boards = {}
131132
for port in SUPPORTED_PORTS:
132133
board_path = root_dir / "ports" / port / "boards"
133-
for board_path in os.scandir(board_path):
134+
# Zephyr port has vendor specific subdirectories to match zephyr (and
135+
# clean up the boards folder.)
136+
g = "*/*" if port == "zephyr-cp" else "*"
137+
for board_path in board_path.glob(g):
134138
if board_path.is_dir():
135139
board_id = board_path.name
140+
if port == "zephyr-cp":
141+
vendor = board_path.parent.name
142+
board_id = f"{vendor}_{board_id}"
136143
aliases = ALIASES_BY_BOARD.get(board_path.name, [])
137144
boards[board_id] = {
138145
"port": port,
139146
"download_count": 0,
140147
"aliases": aliases,
148+
"directory": board_path,
141149
}
142150
for alias in aliases:
143151
boards[alias] = {
144152
"port": port,
145153
"download_count": 0,
146154
"alias": True,
147155
"aliases": [],
156+
"directory": board_path,
148157
}
149158
return boards
150159

@@ -295,15 +304,6 @@ def lookup_setting(settings, key, default=""):
295304
return value
296305

297306

298-
def all_ports_all_boards(ports=SUPPORTED_PORTS):
299-
for port in ports:
300-
port_dir = get_circuitpython_root_dir() / "ports" / port
301-
for entry in (port_dir / "boards").iterdir():
302-
if not entry.is_dir():
303-
continue
304-
yield (port, entry)
305-
306-
307307
def support_matrix_by_board(use_branded_name=True, withurl=True,
308308
add_port=False, add_chips=False,
309309
add_pins=False, add_branded_name=False):
@@ -313,29 +313,44 @@ def support_matrix_by_board(use_branded_name=True, withurl=True,
313313
base = build_module_map()
314314

315315
def support_matrix(arg):
316-
port, entry = arg
317-
port_dir = get_circuitpython_root_dir() / "ports" / port
318-
settings = get_settings_from_makefile(str(port_dir), entry.name)
316+
board_id, board_info = arg
317+
port = board_info["port"]
318+
board_directory = board_info["directory"]
319+
port_dir = board_directory.parent.parent
320+
if port != "zephyr-cp":
321+
settings = get_settings_from_makefile(str(port_dir), board_directory.name)
322+
autogen_board_info = None
323+
else:
324+
circuitpython_toml_fn = board_directory / "circuitpython.toml"
325+
with circuitpython_toml_fn.open("rb") as f:
326+
settings = tomllib.load(f)
327+
328+
autogen_board_info_fn = board_directory / "autogen_board_info.toml"
329+
with autogen_board_info_fn.open("rb") as f:
330+
autogen_board_info = tomllib.load(f)
319331

320332
if use_branded_name or add_branded_name:
321-
with open(entry / "mpconfigboard.h") as get_name:
322-
board_contents = get_name.read()
323-
board_name_re = re.search(
324-
r"(?<=MICROPY_HW_BOARD_NAME)\s+(.+)", board_contents
325-
)
326-
if board_name_re:
327-
branded_name = board_name_re.group(1).strip('"')
328-
if '"' in branded_name: # sometimes the closing " is not at line end
329-
branded_name = branded_name[:branded_name.index('"')]
330-
board_name = branded_name
333+
if autogen_board_info:
334+
branded_name = autogen_board_info["name"]
335+
else:
336+
with open(board_directory / "mpconfigboard.h") as get_name:
337+
board_contents = get_name.read()
338+
board_name_re = re.search(
339+
r"(?<=MICROPY_HW_BOARD_NAME)\s+(.+)", board_contents
340+
)
341+
if board_name_re:
342+
branded_name = board_name_re.group(1).strip('"')
343+
if '"' in branded_name: # sometimes the closing " is not at line end
344+
branded_name = branded_name[:branded_name.index('"')]
345+
board_name = branded_name
331346

332347
if use_branded_name:
333348
board_name = branded_name
334349
else:
335-
board_name = entry.name
350+
board_name = board_directory.name
336351

337352
if add_chips:
338-
with open(entry / "mpconfigboard.h") as get_name:
353+
with open(board_directory / "mpconfigboard.h") as get_name:
339354
board_contents = get_name.read()
340355
mcu_re = re.search(
341356
r'(?<=MICROPY_HW_MCU_NAME)\s+(.+)', board_contents
@@ -346,7 +361,7 @@ def support_matrix(arg):
346361
mcu = mcu[:mcu.index('"')]
347362
else:
348363
mcu = ""
349-
with open(entry / "mpconfigboard.mk") as get_name:
364+
with open(board_directory / "mpconfigboard.mk") as get_name:
350365
board_contents = get_name.read()
351366
flash_re = re.search(
352367
r'(?<=EXTERNAL_FLASH_DEVICES)\s+=\s+(.+)', board_contents
@@ -363,7 +378,7 @@ def support_matrix(arg):
363378
if add_pins:
364379
pins = []
365380
try:
366-
with open(entry / "pins.c") as get_name:
381+
with open(board_directory / "pins.c") as get_name:
367382
pin_lines = get_name.readlines()
368383
except FileNotFoundError: # silabs boards have no pins.c
369384
pass
@@ -376,17 +391,25 @@ def support_matrix(arg):
376391
pins.append((board_pin, chip_pin))
377392

378393
board_modules = []
379-
for module in base:
380-
key = base[module]["key"]
381-
if int(lookup_setting(settings, key, "0")):
382-
board_modules.append(base[module]["name"])
394+
if autogen_board_info:
395+
autogen_modules = autogen_board_info["modules"]
396+
for k in autogen_modules:
397+
if autogen_modules[k]:
398+
board_modules.append(k)
399+
else:
400+
for module in base:
401+
key = base[module]["key"]
402+
if int(lookup_setting(settings, key, "0")):
403+
board_modules.append(base[module]["name"])
383404
board_modules.sort()
384405

385406
if "CIRCUITPY_BUILD_EXTENSIONS" in settings:
386-
board_extensions = [
387-
extension.strip()
388-
for extension in settings["CIRCUITPY_BUILD_EXTENSIONS"].split(",")
389-
]
407+
board_extensions = settings["CIRCUITPY_BUILD_EXTENSIONS"]
408+
if isinstance(board_extensions, str):
409+
board_extensions = [
410+
extension.strip()
411+
for extension in board_extensions.split(",")
412+
]
390413
else:
391414
raise OSError(f"Board extensions undefined: {board_name}.")
392415

@@ -420,8 +443,8 @@ def support_matrix(arg):
420443
board_info
421444
)
422445
]
423-
if entry.name in ALIASES_BY_BOARD:
424-
for alias in ALIASES_BY_BOARD[entry.name]:
446+
if board_id in ALIASES_BY_BOARD:
447+
for alias in ALIASES_BY_BOARD[board_id]:
425448
if use_branded_name:
426449
if alias in ALIASES_BRAND_NAMES:
427450
alias = ALIASES_BRAND_NAMES[alias]
@@ -450,8 +473,14 @@ def support_matrix(arg):
450473

451474
return board_matrix # this is now a list of (board,modules)
452475

476+
477+
board_mapping = get_board_mapping()
478+
real_boards = []
479+
for board in board_mapping:
480+
if not board_mapping[board].get("alias", False):
481+
real_boards.append((board, board_mapping[board]))
453482
executor = ThreadPoolExecutor(max_workers=os.cpu_count())
454-
mapped_exec = executor.map(support_matrix, all_ports_all_boards())
483+
mapped_exec = executor.map(support_matrix, real_boards)
455484
# flatmap with comprehensions
456485
boards = dict(
457486
sorted(

0 commit comments

Comments
 (0)
0