Skip to content

Commit 708282c

Browse files
authored
Merge pull request #99 from mbrossard/soc-support
Add new section 'Supporting a new SoC'
2 parents 66c663e + 7f9be5c commit 708282c

File tree

2 files changed

+240
-0
lines changed

2 files changed

+240
-0
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
---
1313
[A note on compiler support](./compiler-support.md)
1414
[Creating a custom target](./custom-target.md)
15+
[Supporting a new SoC](./soc-support.md)

src/soc-support.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# Guide for silicon vendors to enable Rust support for their SoCs
2+
3+
## Introduction
4+
5+
Rust has emerged as a powerful and safety-focused programming language, gaining
6+
traction among embedded developers. Silicon vendors who wish to enable Rust
7+
support for their System-on-Chip (SoC) products can benefit from this trend by
8+
attracting a growing community of Rust developers.
9+
10+
This guide aims to help silicon vendors enable Rust support, either
11+
independently or by empowering third-party developers. It outlines the
12+
essential resources, tasks, and priorities required to foster a robust Rust
13+
ecosystem around their System-on-Chip (SoC).
14+
15+
**Note:** For assistance with strategy in engaging with the community, we
16+
recommend reaching out to the Rust Embedded Working Group (REWG) leads. They
17+
can provide valuable insights and support to help you navigate the process
18+
effectively.
19+
20+
## Essential resources
21+
22+
### Documentation
23+
24+
Detailed documentation is essential for effective development and debugging. It
25+
enables developers to comprehend the System-on-Chip (SoC), including its memory
26+
map, peripherals, interrupt handling, low-power modes, etc. Ensure that the
27+
documentation covers all hardware aspects comprehensively, from register-level
28+
details to system-level interactions. The documentation should be publicly
29+
available; in cases where public availability is not feasible, any
30+
non-disclosure agreement (NDA) must permit the publication of open-source code
31+
derived from it.
32+
33+
### Register description files
34+
35+
Register description files are used to generate Peripheral Access Crates
36+
(PACs). The most common format for these files is SVD
37+
([System View Description](https://open-cmsis-pack.github.io/svd-spec)). Rust
38+
developers have often encountered issues with SVD files, so it is crucial to
39+
provide clear contact information for reporting any discrepancies or problems.
40+
Up-to-date SVD files ensure that the community can collaborate effectively to
41+
resolve issues and improve the quality of the PACs.
42+
43+
### Flash Algorithms
44+
45+
[Flash Algorithms](https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/flashAlgorithm.html)
46+
are integrated with debugging tools like [probe-rs](https://probe.rs). They
47+
facilitate and speed up firmware programming and debugging, streamlining
48+
development workflows. Providing well-supported FlashAlgos will enhance the
49+
integration with these tools and improve the overall developer experience.
50+
Flash Algorithms can be authored in Rust (see
51+
[flash-algorithm-template](https://github.com/probe-rs/flash-algorithm-template)
52+
for an template to write one).
53+
54+
### Vendor tooling
55+
56+
Some System-on-Chip (SoC) devices require custom tools for generating images or
57+
flashing them onto the device. It is beneficial to provide these tools in an
58+
open-source manner, fostering community contributions and accelerating
59+
ecosystem growth. Open-sourcing vendor tooling enables third-party developers
60+
to extend and enhance the toolchain, ensuring improved compatibility with the
61+
broader Embedded Rust ecosystem.
62+
63+
### Contact information
64+
65+
Providing contact information is vital for addressing maintainer queries and
66+
issues related to register description files or other resources. The use of a
67+
public issue tracking system (like GitHub Issues) for reporting and tracking
68+
problems might help. Actively engage with the community through forums,
69+
discussions, and updates to build trust and collaboration.
70+
71+
## Maintaining PAC and HAL crates
72+
73+
Peripheral Access Crates (PACs) and Hardware Abstraction Layer (HAL) crates are
74+
at the core of enabling Rust support.
75+
76+
### Generate and maintain PACs
77+
78+
Multiple tools such as [svd2rust](https://crates.io/crates/svd2rust),
79+
[chiptool](https://github.com/embassy-rs/chiptool),
80+
[raltool](https://github.com/imxrt-rs/imxrt-ral/tree/master/raltool), and
81+
[svd2pac](https://github.com/Infineon/svd2pac) automate the generation of PACs
82+
from register description files. Each tool has its strengths, and selecting the
83+
right one depends on the requirements and the complexity of the hardware.
84+
85+
### Develop and maintain HAL crates
86+
87+
Implement [embedded-hal](https://crates.io/crates/embedded-hal),
88+
[embedded-hal-async](https://crates.io/crates/embedded-hal-async), and
89+
[embedded-io](https://crates.io/crates/embedded-io) traits in your HAL crates.
90+
Adhering to these traits ensures compatibility across the Embedded Rust
91+
ecosystem, enhancing interoperability. It is an essential goal that HALs use
92+
Rust code rather than wrapping existing C code. An incremental porting
93+
strategy, where all core functionality is implemented in Rust, but C with Rust
94+
bindings is used for complex drivers, is acceptable, allowing for gradual
95+
adoption and community contributions.
96+
97+
Start with essential peripherals (clock, timer, GPIO) and expand progressively
98+
(I2C, SPI, UART, etc.) based on community feedback. Release early and often to
99+
engage the community and gather valuable insights for further development.
100+
101+
### Common recommendations
102+
103+
- Ensure that crates are compatible with `no_std` environments, which are
104+
common in embedded systems without an operating system. Functionality that
105+
needs `alloc` or `std` can be included when gated with Cargo
106+
[features](https://doc.rust-lang.org/cargo/reference/features.html).
107+
- Make your crates available on [crates.io](https://crates.io) to maximize
108+
visibility and ease of use for developers.
109+
- Use [semantic versioning](https://semver.org) to maintain consistency and
110+
predictability in your releases.
111+
- Prefer licenses like Apache 2.0 and MIT for their permissive nature, which
112+
encourages broader adoption and collaboration.
113+
114+
### Issue tracking
115+
116+
Effective issue tracking is crucial for maintaining a healthy and collaborative
117+
ecosystem. Discuss triaging, labeling, and community involvement in issue
118+
resolution. Implement transparent processes for:
119+
120+
- Triage and prioritize issues based on severity and impact.
121+
- Use labels to categorize issues (e.g., bugs, feature requests).
122+
- Encourage community members to contribute to resolving issues by providing
123+
feedback or submitting pull requests (PRs).
124+
125+
### Facilitate debugging and testing
126+
127+
The Embedded Rust ecosystem offers various tools used for debugging
128+
and testing, with [probe-rs](https://probe.rs) being one of the most widely
129+
used. [probe-rs](https://probe.rs) supports a wide range
130+
of target architectures, debug interfaces, and debug probe protocols.
131+
Combined with debug-based facilities like
132+
[defmt-rtt](https://crates.io/crates/defmt-rtt), which provide logging
133+
capabilities for embedded systems, these tools form a robust foundation for
134+
development.
135+
136+
Thorough testing ensures hardware-software reliability, and leveraging these
137+
tools can significantly enhance development workflows.
138+
139+
## Nice-to-have features for enhanced ecosystem support
140+
141+
### Examples
142+
143+
Including some basic examples as part of the HAL is essential for helping
144+
developers get started. These examples should demonstrate key functionalities,
145+
such as initializing peripherals or handling interrupts. They serve as
146+
practical starting points and learning aids.
147+
148+
### BSP (Board Support Package) crates
149+
150+
BSP crates are relevant when you need to provide board-specific configurations
151+
and initializations. Unlike HALs, which focus on hardware abstraction, BSPs
152+
handle the integration of multiple components for a specific board. Separation
153+
in BSP and HAL crates offers a layered approach, making it easier for developers
154+
to build applications targeting a particular hardware board.
155+
156+
### Project templates
157+
158+
Project templates are boilerplate code structures that provide a starting point
159+
for new projects. They include prevalent configurations, dependencies, and
160+
setup steps, saving developers time and reducing the learning curve. Examples
161+
of project templates include bare-metal (using the HAL without any framework),
162+
Embassy, RTIC, and others.
163+
164+
### Integration with popular IDEs and tools
165+
166+
Offer guides on setting up development environments for Embedded Rust projects
167+
with popular tools such as:
168+
169+
- [rust-analyzer](https://rust-analyzer.github.io): for Rust syntax
170+
highlighting and error checking.
171+
- [probe-rs](https://probe.rs): for flashing and debugging firmware.
172+
- [defmt](https://crates.io/crates/defmt): a logging framework optimized for
173+
embedded systems, including a test harness called
174+
[defmt-test](https://crates.io/crates/defmt-test).
175+
176+
Providing setup instructions for these tools will help developers integrate
177+
them into their workflows, enhancing productivity and collaboration.
178+
179+
## Suggested flow for adding SoC Support
180+
181+
- A preliminary requirement of this flow is that the Rust toolchain includes
182+
a [target](https://doc.rust-lang.org/rustc/platform-support.html) that
183+
matches the System-on-Chip (SoC). If this not the case the solution can be as
184+
simple as adding a
185+
[custom target](https://doc.rust-lang.org/rustc/targets/custom.html) or as
186+
difficult as adding support for the underlying architecture to
187+
[LLVM](https://llvm.org).
188+
- Before starting from scratch, check if any existing community efforts for
189+
already exist (e.g. checking on
190+
[awesome-embedded-rust](https://github.com/rust-embedded/awesome-embedded-rust)
191+
or joining the
192+
[Rust Embedded Matrix room](https://matrix.to/#/#rust-embedded:matrix.org)).
193+
This could save significant development time.
194+
- Ensure that your target is supported by [probe-rs](https://probe.rs). The
195+
ability to debug using SWD or JTAG is highly beneficial. Support for flashing
196+
programming can be added with a Flash Algorithm (e.g. from a CMSIS-Pack or
197+
[writing one in Rust](https://github.com/probe-rs/flash-algorithm-template)).
198+
- Generate Peripheral Access Crates (PACs) from register description files,
199+
with SVD (System View Description) being the most common and preferred
200+
format. Alternatives include extracting the register descriptions from PDF
201+
datasheets or C header files, but this can be much more labor-intensive.
202+
- Create a minimal project containing the PAC and/or an empty Hardware
203+
Abstraction Layer (HAL). The goal is to get a minimal working binary that
204+
either blinks an LED or sends messages through
205+
[defmt-rtt](https://crates.io/crates/defmt-rtt) using only the PAC crate or
206+
with a minimal HAL. This will require a linker script and exercise the
207+
availability to flash and debug programs. Additional crates for core
208+
registers and peripheral, or startup code and interrupt handling will also be
209+
required (see [Cortex-M](https://github.com/rust-embedded/cortex-m) or
210+
[RISC-V](https://github.com/rust-embedded/riscv)).
211+
- Add core functionality in HAL: clocks, timers, interrupts. Verify the
212+
accuracy of timers and interrupts with external tools like a logic analyzer
213+
or an oscilloscope.
214+
- Progressively add drivers for other peripherals (GPIO, I2C, SPI, UART, etc.)
215+
implementing standard Rust Embedded traits
216+
([embedded-hal](https://crates.io/crates/embedded-hal),
217+
[embedded-hal-async](https://crates.io/crates/embedded-hal-async),
218+
[embedded-io](https://crates.io/crates/embedded-io)).
219+
- Release early and often in the beginning, engage with the community to get
220+
feedback.
221+
222+
## Conclusion
223+
224+
Enabling Rust support for your SoC opens the door to a vibrant community of
225+
developers who value safety, performance, and reliability. By providing
226+
essential resources, maintaining high-quality PACs and HAL crates, and
227+
fostering a supportive ecosystem, you empower both internal teams and
228+
third-party developers to unlock the full potential of your hardware.
229+
230+
As the Rust embedded ecosystem continues to grow, embracing these practices
231+
positions your company at the forefront of this movement, attracting developers
232+
passionate about building robust and innovative systems. Encourage ongoing
233+
engagement with the Rust community to stay updated on best practices and tools,
234+
ensuring your System-on-Chip (SoC) remains a preferred choice for Rust
235+
developers.
236+
237+
By following this guide, you can create a comprehensive and supportive
238+
environment that not only enables Rust support but also nurtures a thriving
239+
developer ecosystem around your products.

0 commit comments

Comments
 (0)