1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//! # Bindings for RIOT system calls
//!
//! This crate contains dynamically generated Rust FFI bindings to the [RIOT
//! Operating System](https://riot-os.org/).
//!
//! Those bindings are inherently unsafe; it is recommended that their safe
//! abstractions in the [riot-wrappers] crate are used in most applications.
//!
//! For a newcomer's starting point, see [RIOT's documentation on using it with Rust].
//! This also contains installation instructions / depenendencies.
//!
//! [riot-wrappers]: https://crates.io/crates/riot-wrappers
//! [RIOT's documentation on using it with Rust]: https://doc.riot-os.org/using-rust.html
//!
//! ## RIOT integration
//!
//! Which functions and structs are present in this crate, and sometimes their
//! details, inherently depends on the RIOT configuration this will be used with.
//! For example, RIOT's `thread_t` only has a member `name` if `DEVHELP` is
//! set for a build, and its `flags` member is only present if the `thread_flags`
//! module is in use.
//!
//! All the relevant information -- including the location of the actually used
//! RIOT header files and flags influencing the ABI -- is conveyed to `riot-sys` by passing on the
//! compiler and the CFLAGS. This can either be done by passing in th epath to a "compile commads"
//! file through the `RIOT_COMPILE_COMMANDS` environment variable (accompanied by a
//! `RIOT_USEMODULES`, as that part of `CFLAGS` is missing from the compile commands), or
//! alternatively by passing in the C compiler as `RIOT_CC` and the CFLAGS (both their
//! `CFLAGS_WITH_MACROS` and the `INCLUDES` part from RIOT's build system) in. When called from
//! within RIOT's build system, care must be taken to clear `CC` and `CFLAGS`, as these would be
//! interpreted by Cargo (Rust's build system) to refer to the host compiler and flags.
//! The flags will be interpreted by libclang based tools; care must be taken to pass in flags
//! suitable for clang and not for GCC.
//!
//! These steps are automated in RIOT's build system.
//!
//!
//! The `RIOT_CC` and `RIOT_CFLAGS` are made available to dependent crates through
//! Cargo (as `DEP_RIOT_SYS_CC` etc); see [riot-wrappers]'s build.sh for an example. Similarly,
//! custom markers are made available based on the presence of certain defines or features in RIOT
//! as downstream crates require that information (typically to allow a crate to work across a
//! wider range of RIOT versions); see the comments in `build.rs` for details.
//!
//!
//! ## Extension
//!
//! Currently, only a subset of all the RIOT headers is processed; all the relevant
//! header files are included in this crate's `riot-headers.h` header file. If you
//! need access to more RIOT APIs, more includes can be added there.
//!
//!
//! ## Versioning
//!
//! `riot-sys` is versioned using SemVer,
//! and efforts are made to not make breaking changes even while in the 0.x phase.
//! Note that as it passes on RIOT internals,
//! any of the SemVer guarantees only hold when built on the *same* RIOT --
//! once the underlying C code is changed, all bets are off.
//! Users of `riot-rs` can introspect its markers (see `build.rs`)
//! to influence which symbols to use.
//!
//! ### Markers
//!
//! Some decisions of downstream crates need to depend on whether some feature is around in
//! RIOT. For many things that's best checked on module level, but some minor items have no
//! module to mark the feature, and checking for versions by numers is not fine-grained enough,
//! so it's easiest to check for concrete strings in the bindgen output.
//!
//! The `build.rs` of this crate contains a list of marker conditions. These lead to `MARKER_foo=1`
//! items emitted that are usable as `DEP_RIOT_SYS_MARKER_foo=1` by crates that explicitly `links =
//! "riot-sys"`. They are stable in that they'll only go away in a breaking riot-sys version;
//! downstream users likely stop using them earlier because they sooner or later stop supporting
//! old RIOT versions.
//!
//! For example, in [PR #17957](https://github.com/RIOT-OS/RIOT/pull/17957), an argument to a
//! particular handler function changed fundamentally; no amount of `.into()` would allow writing
//! sensible abstractions. The marker `coap_request_ctx_t` was introduced, and is present
//! automatically on all RIOT versions that have that particular pull request merged. Code in
//! `riot-wrappers` uses conditions like `#[cfg(marker_coap_request_ctx_t)] ` to decide whether to
//! use the old or the new conventions.
//!
//! These markers are currently checked against bindgen's output, but could query any property
//! that riot-sys has access to. The markers are defined in terms of some change having happened
//! in RIOT; the way they are tested for can change. (In particular, when riot-sys stops
//! supporting an older RIOT version, it can just always emit that marker).
//!
//! Crates building on this should preferably not alter their own APIs depending on these,
//! because that would add extra (and hard-to-track) dimensions to them. If they can, they
//! should provide a unified view and degrade gracefully. (For example, riot-wrappers has the
//! unit `T` of the `phydat_unit_t` in its enum, but converts it to the generic unspecified unit
//! on RIOT versions that don't have the T type yet -- at least for as long as it supports
//! 2022.01).
//!
//! ---
//!
//! The types and constants of RIOT are translated in two forms:
//! through bindgen (to be linked together), and through C2Rust (transpiled, to be inlined).
//! This is necessary because neither can express the full set of useful RIOT APIs.
//!
//! All bindgen types are reexported in the main module and exclusively public through there. The
//! C2Rust types largely reside in the [inline] module, with some pub used into the root module as
//! necessary or convenient.
#![no_std]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![cfg_attr(feature = "keep-extern-types", feature(extern_types))]

pub mod libc;

mod intrinsics_replacements;

mod bindgen;
pub mod inline;

include!(concat!(env!("OUT_DIR"), "/toplevel_from_inline.rs"));
pub use bindgen::*;

// re-export RIOT-rs core (used by riot-wrappers)
#[cfg(feature = "riot-rs")]
pub use riot_rs_core;