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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
//! ## Overview
//!
//! Procedural macros for use with the `esp-hal` family of HAL packages. In
//! general, you should not need to depend on this package directly, as the
//! relevant procmacros are re-exported by the various HAL packages.
//!
//! Provides macros for:
//!
//! - Placing statics and functions into RAM
//! - Marking interrupt handlers
//! - Blocking and Async `#[main]` macros
//!
//! These macros offer developers a convenient way to control memory placement
//! and define interrupt handlers in their embedded applications, allowing for
//! optimized memory usage and precise handling of hardware interrupts.
//!
//! Key Components:
//! - [`handler`](macro@handler) - Attribute macro for marking interrupt handlers. Interrupt
//! handlers are used to handle specific hardware interrupts generated by peripherals.
//!
//! - [`ram`](macro@ram) - Attribute macro for placing statics and functions into specific memory
//! sections, such as SRAM or RTC RAM (slow or fast) with different initialization options. See
//! its documentation for details.
//!
//! - [`esp_rtos::main`](macro@rtos_main) - Creates a new instance of `esp_rtos::embassy::Executor`
//! and declares an application entry point spawning the corresponding function body as an async
//! task.
//!
//! ## Examples
//!
//! #### `main` macro
//!
//! Requires the `embassy` feature to be enabled.
//!
//! ```rust,ignore
//! #[main]
//! async fn main(spawner: Spawner) {
//! // Your application's entry point
//! }
//! ```
//!
//! ## Feature Flags
use TokenStream;
/// Sets which segment of RAM to use for a function or static and how it should
/// be initialized.
///
/// # Options
///
/// - `rtc_fast`: Use RTC fast RAM.
/// - `rtc_slow`: Use RTC slow RAM. **Note**: not available on all targets.
/// - `persistent`: Persist the contents of the `static` across resets. See [the section
/// below](#persistent) for details.
/// - `zeroed`: Initialize the memory of the `static` to zero. The initializer expression will be
/// discarded. Types used must implement [`bytemuck::Zeroable`].
/// - `reclaimed`: Memory reclaimed from the esp-idf bootloader.
///
/// Using both `rtc_fast` and `rtc_slow` or `persistent` and `zeroed` together
/// is an error.
///
/// ## `persistent`
///
/// Initialize the memory to zero after the initial boot. Thereafter,
/// initialization is skipped to allow communication across `software_reset()`,
/// deep sleep, watchdog timeouts, etc.
///
/// Types used must implement [`bytemuck::AnyBitPattern`].
///
/// ### Warnings
///
/// - A system-level or lesser reset occurring before the ram has been zeroed *could* skip
/// initialization and start the application with the static filled with random bytes.
/// - There is no way to keep some kinds of resets from happening while updating a persistent
/// static—not even a critical section.
///
/// If these are issues for your application, consider adding a checksum
/// alongside the data.
///
/// # Examples
///
/// ```rust, ignore
/// #[ram(unstable(rtc_fast))]
/// static mut SOME_INITED_DATA: [u8; 2] = [0xaa, 0xbb];
///
/// #[ram(unstable(rtc_fast, persistent))]
/// static mut SOME_PERSISTENT_DATA: [u8; 2] = [0; 2];
///
/// #[ram(unstable(rtc_fast, zeroed))]
/// static mut SOME_ZEROED_DATA: [u8; 8] = [0; 8];
/// ```
///
/// See the `ram` example in the qa-test folder of the esp-hal repository for a full usage example.
///
/// [`bytemuck::AnyBitPattern`]: https://docs.rs/bytemuck/1.9.0/bytemuck/trait.AnyBitPattern.html
/// [`bytemuck::Zeroable`]: https://docs.rs/bytemuck/1.9.0/bytemuck/trait.Zeroable.html
/// Replaces placeholders in rustdoc doc comments.
///
/// The purpose of this macro is to enable us to extract boilerplate, while at
/// the same time let rustfmt format code blocks. This macro rewrites the whole
/// documentation of the annotated item.
///
/// Replacements can be placed in the documentation as `# {placeholder}`. Each
/// replacement must be its own line. The `before_snippet` and `after_snippet` placeholders are
/// expanded to the `esp_hal::before_snippet!()` and `esp_hal::after_snippet!()` macros, and are
/// expected to be used in example code blocks.
///
/// In-line replacements can be placed in the middle of a line as `__placeholder__`. Currently,
/// only literal strings can be substituted into in-line placeholders, and only one placeholder
/// can be used per line.
///
/// You can also define custom replacements in the attribute. A replacement can be
/// an unconditional literal (i.e. a string that is always substituted into the doc comment),
/// or a conditional.
///
/// ## Examples
///
/// ```rust, ignore
/// #[doc_replace(
/// "literal_placeholder" => "literal value",
/// "conditional_placeholder" => {
/// cfg(condition1) => "value 1",
/// cfg(condition2) => "value 2",
/// _ => "neither value 1 nor value 2",
/// }
/// )]
/// /// Here comes the documentation.
/// ///
/// /// The replacements are interpreted outside of code blocks, too:
/// /// # {literal_placeholder}
/// ///
/// /// ```rust, no run
/// /// // here is some code
/// /// # {literal_placeholder}
/// /// // here is some more code
/// /// # {conditional_placeholder}
/// ///
/// /// The macro even supports __conditional_placeholder__ replacements in-line.
/// /// ```
/// fn my_function() {}
/// ```
/// Mark a function as an interrupt handler.
///
/// Optionally a priority can be specified, e.g. `#[handler(priority =
/// esp_hal::interrupt::Priority::Priority2)]`.
///
/// If no priority is given, `Priority::min()` is assumed
/// Load code to be run on the LP/ULP core.
///
/// ## Example
/// ```rust, ignore
/// let lp_core_code = load_lp_code!("path.elf");
/// lp_core_code.run(&mut lp_core, lp_core::LpCoreWakeupSource::HpCpu, lp_pin);
/// ````
/// Marks the entry function of a LP core / ULP program.
/// Creates a new instance of `esp_rtos::embassy::Executor` and declares an application entry point
/// spawning the corresponding function body as an async task.
///
/// The following restrictions apply:
///
/// * The function must accept exactly 1 parameter, an `embassy_executor::Spawner` handle that it
/// can use to spawn additional tasks.
/// * The function must be declared `async`.
/// * The function must not use generics.
/// * Only a single `main` task may be declared.
///
/// ## Examples
/// Spawning a task:
///
/// ```rust,ignore
/// #[esp_rtos::main]
/// async fn main(_s: embassy_executor::Spawner) {
/// // Function body
/// }
/// ```
/// Attribute to declare the entry point of the program
///
/// The specified function will be called by the reset handler *after* RAM has
/// been initialized. If present, the FPU will also be enabled before the
/// function is called.
///
/// The type of the specified function must be `[unsafe] fn() -> !` (never
/// ending function)
///
/// # Properties
///
/// The entry point will be called by the reset handler. The program can't
/// reference to the entry point, much less invoke it.
///
/// # Examples
///
/// - Simple entry point
///
/// ```ignore
/// #[main]
/// fn main() -> ! {
/// loop { /* .. */ }
/// }
/// ```
/// Automatically implement the [Builder Lite] pattern for a struct.
///
/// This will create an `impl` which contains methods for each field of a
/// struct, allowing users to easily set the values. The generated methods will
/// be the field name prefixed with `with_`, and calls to these methods can be
/// chained as needed.
///
/// ## Example
///
/// ```rust, ignore
/// #[derive(Default)]
/// enum MyEnum {
/// #[default]
/// A,
/// B,
/// }
///
/// #[derive(Default, BuilderLite)]
/// #[non_exhaustive]
/// struct MyStruct {
/// enum_field: MyEnum,
/// bool_field: bool,
/// option_field: Option<i32>,
/// }
///
/// MyStruct::default()
/// .with_enum_field(MyEnum::B)
/// .with_bool_field(true)
/// .with_option_field(-5);
/// ```
///
/// [Builder Lite]: https://matklad.github.io/2022/05/29/builder-lite.html
/// Print a build error and terminate the process.
///
/// It should be noted that the error will be printed BEFORE the main function
/// is called, and as such this should NOT be thought analogous to `println!` or
/// similar utilities.
///
/// ## Example
///
/// ```rust, ignore
/// esp_hal_procmacros::error! {"
/// ERROR: something really bad has happened!
/// "}
/// // Process exits with exit code 1
/// ```
/// Print a build warning.
///
/// It should be noted that the warning will be printed BEFORE the main function
/// is called, and as such this should NOT be thought analogous to `println!` or
/// similar utilities.
///
/// ## Example
///
/// ```rust,no_run
/// esp_hal_procmacros::warning! {"
/// WARNING: something unpleasant has happened!
/// "};
/// ```
pub use unwrap_or_compile_error;