doc: boards: catalog: add shields to board catalog
Populate board catalog with shields as well and have them show up in the boards/index page. Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
This commit is contained in:
parent
3c4b6417b3
commit
11fea40a40
9 changed files with 140 additions and 39 deletions
|
@ -3,26 +3,28 @@
|
||||||
Supported Boards and Shields
|
Supported Boards and Shields
|
||||||
############################
|
############################
|
||||||
|
|
||||||
|
This page lists all the boards and shields that are currently supported in Zephyr.
|
||||||
|
|
||||||
If you are looking to add Zephyr support for a new board, please start with the
|
If you are looking to add Zephyr support for a new board, please start with the
|
||||||
:ref:`board_porting_guide`.
|
:ref:`board_porting_guide`. When adding support documentation for a board, remember to use the
|
||||||
|
template available under :zephyr_file:`doc/templates/board.tmpl`.
|
||||||
|
|
||||||
When adding support documentation for a board, remember to use the template
|
Shields are hardware add-ons that can be stacked on top of a board to add extra functionality.
|
||||||
available under :zephyr_file:`doc/templates/board.tmpl`.
|
Refer to the :ref:`shield_porting_guide` for more information on how to port a shield.
|
||||||
|
|
||||||
Shields are hardware add-ons that can be stacked on top of a board to add extra
|
|
||||||
functionality. They are listed separately from boards, towards :ref:`the end of
|
|
||||||
this page <boards-shields>`.
|
|
||||||
|
|
||||||
.. admonition:: Search Tips
|
.. admonition:: Search Tips
|
||||||
:class: dropdown
|
:class: dropdown
|
||||||
|
|
||||||
* Use the form below to filter the list of supported boards. If a field is left empty, it will
|
* Use the form below to filter the list of supported boards and shields. If a field is left
|
||||||
not be used in the filtering process.
|
empty, it will not be used in the filtering process.
|
||||||
|
|
||||||
* A board must meet **all** criteria selected across different fields. For example, if you select
|
* Filtering by name and vendor is available for both boards and shields. The rest of the fields
|
||||||
both a vendor and an architecture, only boards that match both will be displayed. Within a
|
apply only to boards.
|
||||||
single field, selecting multiple options (such as two architectures) will show boards matching
|
|
||||||
**either** option.
|
* A board/shield must meet **all** criteria selected across different fields. For example, if you
|
||||||
|
select both a vendor and an architecture, only boards that match both will be displayed. Within
|
||||||
|
a single field, selecting multiple options (such as two architectures) will show boards
|
||||||
|
matching **either** option.
|
||||||
|
|
||||||
* The list of supported hardware features for each board is automatically generated using
|
* The list of supported hardware features for each board is automatically generated using
|
||||||
information from the Devicetree. It may not be reflecting the full list of supported features
|
information from the Devicetree. It may not be reflecting the full list of supported features
|
||||||
|
@ -40,14 +42,3 @@ this page <boards-shields>`.
|
||||||
*/index
|
*/index
|
||||||
|
|
||||||
.. zephyr:board-catalog::
|
.. zephyr:board-catalog::
|
||||||
|
|
||||||
.. _boards-shields:
|
|
||||||
|
|
||||||
Shields
|
|
||||||
#######
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
:glob:
|
|
||||||
|
|
||||||
shields/**/*
|
|
||||||
|
|
8
boards/shields/index.rst
Normal file
8
boards/shields/index.rst
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Shields
|
||||||
|
#######
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
:glob:
|
||||||
|
|
||||||
|
**/*
|
|
@ -757,6 +757,7 @@ class BoardCatalogDirective(SphinxDirective):
|
||||||
"board-catalog.html",
|
"board-catalog.html",
|
||||||
{
|
{
|
||||||
"boards": domain_data["boards"],
|
"boards": domain_data["boards"],
|
||||||
|
"shields": domain_data["shields"],
|
||||||
"vendors": domain_data["vendors"],
|
"vendors": domain_data["vendors"],
|
||||||
"socs": domain_data["socs"],
|
"socs": domain_data["socs"],
|
||||||
"hw_features_present": self.env.app.config.zephyr_generate_hw_features,
|
"hw_features_present": self.env.app.config.zephyr_generate_hw_features,
|
||||||
|
@ -1381,6 +1382,7 @@ def load_board_catalog_into_domain(app: Sphinx) -> None:
|
||||||
hw_features_vendor_filter=app.config.zephyr_hw_features_vendor_filter,
|
hw_features_vendor_filter=app.config.zephyr_hw_features_vendor_filter,
|
||||||
)
|
)
|
||||||
app.env.domaindata["zephyr"]["boards"] = board_catalog["boards"]
|
app.env.domaindata["zephyr"]["boards"] = board_catalog["boards"]
|
||||||
|
app.env.domaindata["zephyr"]["shields"] = board_catalog["shields"]
|
||||||
app.env.domaindata["zephyr"]["vendors"] = board_catalog["vendors"]
|
app.env.domaindata["zephyr"]["vendors"] = board_catalog["vendors"]
|
||||||
app.env.domaindata["zephyr"]["socs"] = board_catalog["socs"]
|
app.env.domaindata["zephyr"]["socs"] = board_catalog["socs"]
|
||||||
app.env.domaindata["zephyr"]["runners"] = board_catalog["runners"]
|
app.env.domaindata["zephyr"]["runners"] = board_catalog["runners"]
|
||||||
|
|
|
@ -146,6 +146,7 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.board-card:hover,
|
.board-card:hover,
|
||||||
|
@ -155,6 +156,34 @@
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.board-card.shield::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 48px 48px 0;
|
||||||
|
border-color: transparent var(--admonition-note-title-background-color) transparent transparent;
|
||||||
|
border-radius: 0 8px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.board-card.shield::after {
|
||||||
|
rotate: 45deg;
|
||||||
|
content: "SHIELD";
|
||||||
|
position: absolute;
|
||||||
|
top: 7px;
|
||||||
|
right: 6px;
|
||||||
|
color: var(--admonition-note-title-color);
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
z-index: 1;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.board-card .picture {
|
.board-card .picture {
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
@ -247,6 +276,23 @@
|
||||||
max-width: none;
|
max-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#catalog.compact .board-card.shield::before {
|
||||||
|
display: none; /* Remove the S prefix */
|
||||||
|
}
|
||||||
|
|
||||||
|
#catalog.compact .board-card.shield::after {
|
||||||
|
content: "Shield";
|
||||||
|
color: var(--admonition-note-color);
|
||||||
|
background-color: var(--admonition-note-background-color);
|
||||||
|
padding: 2px 10px 2px 10px;
|
||||||
|
border-radius: 30px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#catalog.compact .board-card.shield {
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
#catalog.compact .board-card .vendor,
|
#catalog.compact .board-card .vendor,
|
||||||
#catalog.compact .board-card .picture {
|
#catalog.compact .board-card .picture {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -119,7 +119,7 @@ function setupHWCapabilitiesField() {
|
||||||
const datalist = document.getElementById('tag-list');
|
const datalist = document.getElementById('tag-list');
|
||||||
|
|
||||||
const tagCounts = Array.from(document.querySelectorAll('.board-card')).reduce((acc, board) => {
|
const tagCounts = Array.from(document.querySelectorAll('.board-card')).reduce((acc, board) => {
|
||||||
board.getAttribute('data-supported-features').split(' ').forEach(tag => {
|
(board.getAttribute('data-supported-features') || '').split(' ').forEach(tag => {
|
||||||
acc[tag] = (acc[tag] || 0) + 1;
|
acc[tag] = (acc[tag] || 0) + 1;
|
||||||
});
|
});
|
||||||
return acc;
|
return acc;
|
||||||
|
@ -254,12 +254,14 @@ function resetForm() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateBoardCount() {
|
function updateBoardCount() {
|
||||||
const boards = document.getElementsByClassName("board-card");
|
const boards = Array.from(document.getElementsByClassName("board-card"));
|
||||||
const visibleBoards = Array.from(boards).filter(
|
const visible = boards.filter(board => !board.classList.contains("hidden"));
|
||||||
(board) => !board.classList.contains("hidden")
|
const shields = boards.filter(board => board.classList.contains("shield"));
|
||||||
).length;
|
const visibleShields = visible.filter(board => board.classList.contains("shield"));
|
||||||
const totalBoards = boards.length;
|
|
||||||
document.getElementById("nb-matches").textContent = `Showing ${visibleBoards} of ${totalBoards}`;
|
document.getElementById("nb-matches").textContent =
|
||||||
|
`Showing ${visible.length - visibleShields.length} of ${boards.length - shields.length} boards,`
|
||||||
|
+ ` ${visibleShields.length} of ${shields.length} shields`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterBoards() {
|
function filterBoards() {
|
||||||
|
@ -281,10 +283,10 @@ function filterBoards() {
|
||||||
|
|
||||||
Array.from(boards).forEach(function (board) {
|
Array.from(boards).forEach(function (board) {
|
||||||
const boardName = board.getAttribute("data-name").toLowerCase();
|
const boardName = board.getAttribute("data-name").toLowerCase();
|
||||||
const boardArchs = board.getAttribute("data-arch").split(" ");
|
const boardArchs = (board.getAttribute("data-arch") || "").split(" ").filter(Boolean);
|
||||||
const boardVendor = board.getAttribute("data-vendor");
|
const boardVendor = board.getAttribute("data-vendor") || "";
|
||||||
const boardSocs = board.getAttribute("data-socs").split(" ");
|
const boardSocs = (board.getAttribute("data-socs") || "").split(" ").filter(Boolean);
|
||||||
const boardSupportedFeatures = board.getAttribute("data-supported-features").split(" ");
|
const boardSupportedFeatures = (board.getAttribute("data-supported-features") || "").split(" ").filter(Boolean);
|
||||||
|
|
||||||
let matches = true;
|
let matches = true;
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
#}
|
#}
|
||||||
|
|
||||||
<form class="filter-form" aria-label="Filter boards by name, architecture, and vendor">
|
<form class="filter-form" aria-label="Filter boards & shields by name, architecture, and vendor">
|
||||||
|
|
||||||
<div class="form-group" style="flex-basis: 100%">
|
<div class="form-group" style="flex-basis: 100%">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<input type="text" id="name"
|
<input type="text" id="name"
|
||||||
placeholder='Name (or partial name) of the board, e.g. "reel board", "nucleo", …'
|
placeholder='Name (or partial name) of the board/shield, e.g. "reel board", "nucleo", …'
|
||||||
oninput="filterBoards()" />
|
oninput="filterBoards()" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -35,9 +35,11 @@
|
||||||
<div class="select-container">
|
<div class="select-container">
|
||||||
<select id="vendor">
|
<select id="vendor">
|
||||||
<option value="" disabled selected>Select a vendor</option>
|
<option value="" disabled selected>Select a vendor</option>
|
||||||
{# Only show those vendors that have actual boards in the catalog.
|
{# Only show those vendors that have actual boards or shields in the catalog.
|
||||||
Note: as sorting per vendor name is not feasible in Jinja, the option list is sorted in the JavaScript code later #}
|
Note: as sorting per vendor name is not feasible in Jinja, the option list is sorted in the JavaScript code later #}
|
||||||
{% for vendor in (boards | items | map(attribute='1.vendor') | unique ) -%}
|
{% set board_vendors = boards | items | map(attribute='1.vendor') | unique | list %}
|
||||||
|
{% set shield_vendors = shields | items | map(attribute='1.vendor') | unique | list %}
|
||||||
|
{% for vendor in (board_vendors + shield_vendors) | unique -%}
|
||||||
<option value="{{ vendor }}">{{ vendors[vendor] }}</option>
|
<option value="{{ vendor }}">{{ vendors[vendor] }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
@ -98,6 +100,10 @@
|
||||||
{% for board_name, board in boards | items | sort(attribute='1.full_name') -%}
|
{% for board_name, board in boards | items | sort(attribute='1.full_name') -%}
|
||||||
{% include "board-card.html" %}
|
{% include "board-card.html" %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for shield_name, shield in shields | items | sort(attribute='1.full_name') -%}
|
||||||
|
{% include "shield-card.html" %}
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
25
doc/_extensions/zephyr/domain/templates/shield-card.html
Normal file
25
doc/_extensions/zephyr/domain/templates/shield-card.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{#
|
||||||
|
Copyright (c) 2024-2025, The Linux Foundation.
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
#}
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="board-card shield"
|
||||||
|
{% if shield.doc_page -%}
|
||||||
|
href="../{{ shield.doc_page | replace(".rst", ".html") }}"
|
||||||
|
{% else -%}
|
||||||
|
href="#"
|
||||||
|
{% endif -%}
|
||||||
|
aria-label="Open the documentation page for {{ shield.full_name }}"
|
||||||
|
data-name="{{ shield.full_name}}"
|
||||||
|
data-vendor="{{ shield.vendor }}"
|
||||||
|
tabindex="0">
|
||||||
|
<div class="vendor">{{ vendors[shield.vendor] }}</div>
|
||||||
|
{% if shield.image -%}
|
||||||
|
<img alt="A picture of the {{ shield.full_name }} shield"
|
||||||
|
src="../_images/{{ shield.image.split('/')[-1] }}" class="picture" />
|
||||||
|
{% else -%}
|
||||||
|
<div class="no-picture fa fa-microchip picture"></div>
|
||||||
|
{% endif -%}
|
||||||
|
<div class="board-name">{{ shield.full_name }}</div>
|
||||||
|
</a>
|
|
@ -12,6 +12,7 @@ from pathlib import Path
|
||||||
|
|
||||||
import list_boards
|
import list_boards
|
||||||
import list_hardware
|
import list_hardware
|
||||||
|
import list_shields
|
||||||
import yaml
|
import yaml
|
||||||
import zephyr_module
|
import zephyr_module
|
||||||
from gen_devicetree_rest import VndLookup
|
from gen_devicetree_rest import VndLookup
|
||||||
|
@ -256,8 +257,10 @@ def get_catalog(generate_hw_features=False, hw_features_vendor_filter=None):
|
||||||
)
|
)
|
||||||
|
|
||||||
boards = list_boards.find_v2_boards(args_find_boards)
|
boards = list_boards.find_v2_boards(args_find_boards)
|
||||||
|
shields = list_shields.find_shields(args_find_boards)
|
||||||
systems = list_hardware.find_v2_systems(args_find_boards)
|
systems = list_hardware.find_v2_systems(args_find_boards)
|
||||||
board_catalog = {}
|
board_catalog = {}
|
||||||
|
shield_catalog = {}
|
||||||
board_devicetrees = {}
|
board_devicetrees = {}
|
||||||
board_runners = {}
|
board_runners = {}
|
||||||
|
|
||||||
|
@ -400,8 +403,24 @@ def get_catalog(generate_hw_features=False, hw_features_vendor_filter=None):
|
||||||
"commands": runner.capabilities().commands,
|
"commands": runner.capabilities().commands,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for shield in shields:
|
||||||
|
doc_page = guess_doc_page(shield)
|
||||||
|
if doc_page and doc_page.is_relative_to(ZEPHYR_BASE):
|
||||||
|
doc_page_path = doc_page.relative_to(ZEPHYR_BASE).as_posix()
|
||||||
|
else:
|
||||||
|
doc_page_path = None
|
||||||
|
|
||||||
|
shield_catalog[shield.name] = {
|
||||||
|
"name": shield.name,
|
||||||
|
"full_name": shield.full_name or shield.name,
|
||||||
|
"vendor": shield.vendor or "others",
|
||||||
|
"doc_page": doc_page_path,
|
||||||
|
"image": guess_image(shield),
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"boards": board_catalog,
|
"boards": board_catalog,
|
||||||
|
"shields": shield_catalog,
|
||||||
"vendors": {**vnd_lookup.vnd2vendor, "others": "Other/Unknown"},
|
"vendors": {**vnd_lookup.vnd2vendor, "others": "Other/Unknown"},
|
||||||
"socs": socs_hierarchy,
|
"socs": socs_hierarchy,
|
||||||
"runners": available_runners,
|
"runners": available_runners,
|
||||||
|
|
|
@ -8,6 +8,8 @@ to extend its features and services for easier and modularized prototyping.
|
||||||
In Zephyr, the shield feature provides Zephyr-formatted shield
|
In Zephyr, the shield feature provides Zephyr-formatted shield
|
||||||
descriptions for easier compatibility with applications.
|
descriptions for easier compatibility with applications.
|
||||||
|
|
||||||
|
.. _shield_porting_guide:
|
||||||
|
|
||||||
Shield porting and configuration
|
Shield porting and configuration
|
||||||
********************************
|
********************************
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue