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
// When compiling a binary Rust crate in STD (e.g. in Cargo-first builds) and NOT doing
// any tricks like using #[no_main] or #[start], the Rust compiler will autogenerate
// a C function with the signature as below which will be proxying
// the real Rust main function of your binary crate
//
// So to bridge this function with the real C "app_main()" entrypoint
// that ESP-IDF expects it is enough to implement app_main() and call in it
// the "main" C function autogenerated by the Rust compiler
//
// See https://github.com/rust-lang/rust/issues/29633 for more information
extern "C"
// When compiling a static Rust library crate (e.g. by using a PIO->Cargo or a CMake->Cargo) build,
// there is no main function that the Rust compiler expects, nor autogeneration of a callable
// wrapper around it.
//
// In that case (and if the "libstart" feature is enabled), it is _us_ (not the Rust compiler)
// expecting the user to define a rust #[no_mangle] "main" function and it is our code below which is explicitly
// calling it from app_main(). If the user does not define a main() runction in Rust, there will
// be a linkage error instead of the nice Rust syntax error for binary crates.
//
// Another restriction of the "libstart" feature is that the Rust main function will always have one
// fixed signature: "fn main() -> ()" - as opposed to the flexibility of main() in binary crates
// where it can have quite a few different returning types
//
// When compiling a binary Rust crate in no_std, we end up in identical situation:
// - There is no Rust "lang = start" item defined
// - As such, there is no magic C "main" function defined for, which would proxy our binary crate main
extern "Rust"
pub extern "C"
// TODO: Move to `esp-idf-hal`. We should start precisely in the state ESP IDF was configured to be. The below should become a utility method,
// ideally as part of `esp_idf_hal::uart` and possibly with support from future ESP IDF VFS safe APIs
// #[cfg(all(feature = "uart0_driver_init", esp_idf_comp_driver_enabled, esp_idf_comp_vfs_enabled))]
// mod uart_init {
// use crate::{esp_vfs_dev_uart_use_driver, uart_driver_install};
// use core::{ffi::c_int, ptr::null_mut};
// const UART_BUFFER_SIZE: c_int = 512;
// const UART_QUEUE_SIZE: c_int = 10;
// pub(super) fn init_uart0() {
// // Enable UART0 driver so stdin can be read.
// unsafe {
// crate::esp!(uart_driver_install(
// 0,
// UART_BUFFER_SIZE,
// UART_BUFFER_SIZE,
// UART_QUEUE_SIZE,
// null_mut(),
// 0
// ))
// .expect("unable to initialize UART0 driver");
// esp_vfs_dev_uart_use_driver(0);
// }
// }
// }