|
| 1 | +.. _language_rust: |
| 2 | + |
| 3 | +Rust Language Support |
| 4 | +##################### |
| 5 | + |
| 6 | +Rust is a systems programming language focused on safety, speed, and |
| 7 | +concurrency. Designed to prevent common programming errors such as |
| 8 | +null pointer dereferencing and buffer overflows, Rust emphasizes |
| 9 | +memory safety without sacrificing performance. Its powerful type |
| 10 | +system and ownership model ensure thread-safe programming, making it |
| 11 | +an ideal choice for developing reliable and efficient low-level code. |
| 12 | +Rust's expressive syntax and modern features make it a robust |
| 13 | +alternative for developers working on embedded systems, operating |
| 14 | +systems, and other performance-critical applications. |
| 15 | + |
| 16 | +Enabling Rust Support |
| 17 | +********************* |
| 18 | + |
| 19 | +Currently, Zephyr supports applications written in Rust and C. The |
| 20 | +enable Rust support, you must select the :kconfig:option:`CONFIG_RUST` |
| 21 | +in the application configuration file. |
| 22 | + |
| 23 | +The rust toolchain is separate from the rest of the Zephyr SDK. It |
| 24 | +is recommended to use the `rustup`_ tool to install the rust |
| 25 | +toolchain. In addition to the base compiler, you will need to install |
| 26 | +core libraries for the target(s) you wish to compile on. It is |
| 27 | +easiest to determine what needs to be installed by trying a build. |
| 28 | +The diagnostics from the rust compilation will indicate the rust |
| 29 | +command needed to install the appropriate target support: |
| 30 | + |
| 31 | +.. _rustup: https://rustup.rs/ |
| 32 | + |
| 33 | +.. code-block:: |
| 34 | +
|
| 35 | + $ west build ... |
| 36 | + ... |
| 37 | + error[E0463]: can't find crate for `core` |
| 38 | + | |
| 39 | + = note: the `thumbv7m-none-eabi` target may not be installed |
| 40 | + = help: consider downloading the target with `rustup target add thumb7m-none-eabi` |
| 41 | +
|
| 42 | +In this case, the given ``rustup`` command will install the needed |
| 43 | +target support. The target needed will depend on both the board |
| 44 | +selected, as well as certain configuration choices (such as whether |
| 45 | +floating point is enabled). |
| 46 | + |
| 47 | +Writing a Rust Application |
| 48 | +************************** |
| 49 | + |
| 50 | +See :zephyr_file:`samples/rust` for examples of an application. |
| 51 | + |
| 52 | +CMake files |
| 53 | +----------- |
| 54 | + |
| 55 | +The application should contain a :file:`CMakeFiles.txt`, similar to |
| 56 | +the following: |
| 57 | + |
| 58 | +.. code-block:: cmake |
| 59 | +
|
| 60 | + cmake_minimum_required(VERSION 3.20.0) |
| 61 | +
|
| 62 | + find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) |
| 63 | + project(hello_world) |
| 64 | +
|
| 65 | + rust_cargo_application() |
| 66 | +
|
| 67 | +Cargo files |
| 68 | +----------- |
| 69 | + |
| 70 | +Rust applications are built with Cargo. The Zephyr build system will |
| 71 | +configure and invoke cargo in your application directory, with options |
| 72 | +set so that it can find the Zephyr support libraries, and that the |
| 73 | +output will be contained within the Zephyr build directory. |
| 74 | + |
| 75 | +The :file:`Cargo.toml` will need to have a ``[lib]`` section that sets |
| 76 | +``crate-type = ["staticlib"]``, and will need to include ``zephyr = |
| 77 | +"0.1.0"`` as a dependency. You can use crates.io and the Crate |
| 78 | +ecosystem to include any other dependencies you need. Just make sure |
| 79 | +that you use crates that support building with no-std. |
| 80 | + |
| 81 | +Application |
| 82 | +----------- |
| 83 | + |
| 84 | +The application source itself should live in file:`src/lib.rs`. A few |
| 85 | +things are needed. A minimal file would be: |
| 86 | + |
| 87 | +.. code-block:: rust |
| 88 | +
|
| 89 | + #![no_std] |
| 90 | +
|
| 91 | + extern crate zephyr; |
| 92 | +
|
| 93 | + #[no_mangle] |
| 94 | + extern "C" fn rust_main() { |
| 95 | + } |
| 96 | +
|
| 97 | +The ``no_std`` declaration is needed to prevent the code from |
| 98 | +referencing the ``std`` library. The extern reference will cause the |
| 99 | +zephyr crate to be brought in, even if nothing from it is used. |
| 100 | +Practically, any meaningful Rust application on Zephyr will use |
| 101 | +something from this crate, and this line is not necessary. Lastly, |
| 102 | +the main declaration exports the main symbol so that it can be called |
| 103 | +by C code. The build ``rust_cargo_application()`` cmake function will |
| 104 | +include a small C file that will call into this from the C main |
| 105 | +function. |
| 106 | + |
| 107 | +Zephyr Functionality |
| 108 | +******************** |
| 109 | + |
| 110 | +The bindings to Zephyr for Rust are under development, and are |
| 111 | +currently rather minimalistic. |
| 112 | + |
| 113 | +Bool Kconfig settings |
| 114 | +--------------------- |
| 115 | + |
| 116 | +Boolean Kconfig settings can be used from within Rust code. Due to |
| 117 | +design constraints by the Rust language, settings that affect |
| 118 | +compilation must be determined before the build is made. In order to |
| 119 | +use this in your application, you will need to use the |
| 120 | +``zephyr-build`` crate, provided, to make these symbols available. |
| 121 | + |
| 122 | +To your ``Cargo.toml`` file, add the following: |
| 123 | + |
| 124 | +.. code-block:: toml |
| 125 | +
|
| 126 | + [build-dependencies] |
| 127 | + zephyr-build = "0.1.0" |
| 128 | +
|
| 129 | +Then, you will need a ``build.rs`` file to call the support function. |
| 130 | +The following will work: |
| 131 | + |
| 132 | +.. code-block:: rust |
| 133 | +
|
| 134 | + fn main() { |
| 135 | + zephyr_build::export_bool_kconfig(); |
| 136 | + } |
| 137 | +
|
| 138 | +At this point, it will be possible to use the ``cfg`` directive in |
| 139 | +Rust on boolean Kconfig values. For example: |
| 140 | + |
| 141 | +.. code-block:: rust |
| 142 | +
|
| 143 | + #[cfg(CONFIG_SCHED_DUMB)] |
| 144 | + one_declaration; |
| 145 | +
|
| 146 | + #[cfg(not(CONFIG_SCHED_DUMB)] |
| 147 | + other_declaration; |
| 148 | +
|
| 149 | +Other Kconfig settings |
| 150 | +---------------------- |
| 151 | + |
| 152 | +All bool, numeric and string Kconfig settings are accessible from the |
| 153 | +``zephyr::kconfig`` module. For example: |
| 154 | + |
| 155 | +.. code-block:: rust |
| 156 | +
|
| 157 | + let ceiling = zephyr::kconfig::CONFIG_PRIORITY_CEILING - 1; |
| 158 | +
|
| 159 | +Other functionality |
| 160 | +------------------- |
| 161 | + |
| 162 | +Access to other functionality within zephyr is a work-in-progress, and |
| 163 | +this document will be updated as that is done. |
0 commit comments