aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bors[bot] <bors[bot]@users.noreply.github.com> 2019-06-19 07:18:52 +0000
committerGravatar bors[bot] <bors[bot]@users.noreply.github.com> 2019-06-19 07:18:52 +0000
commit5678f48fb3d4badf521b9720381c1f1a80994ddc (patch)
tree0751b8519f469d5c8b158f3de5974ca352963e93
parent8a6e9f1ddcc57010dfa1f247aacb2cf67e110211 (diff)
parent94fbbe01189f97aefa8d6a97cc7cd73e5c6f6ec9 (diff)
downloadcortex-m-5678f48fb3d4badf521b9720381c1f1a80994ddc.tar.gz
cortex-m-5678f48fb3d4badf521b9720381c1f1a80994ddc.tar.zst
cortex-m-5678f48fb3d4badf521b9720381c1f1a80994ddc.zip
Merge #192
192: add a .uninit section r=therealprof a=japaric that contains static variables that will not be initialized by the runtime this implements only the linker section described in RFC #116 so that downstream libraries / framework can leverage it without (a) forking this crate or (b) requiring the end user to pass additional linker scripts to the linker when building their crate. This commit doesn't add the user interface described in RFC #116; instead it documents how to use this linker section in the advanced section of the crate level documentation Co-authored-by: Jorge Aparicio <jorge@japaric.io>
-rw-r--r--cortex-m-rt/link.x.in11
-rw-r--r--cortex-m-rt/src/lib.rs30
2 files changed, 33 insertions, 8 deletions
diff --git a/cortex-m-rt/link.x.in b/cortex-m-rt/link.x.in
index 7a31928..3382d26 100644
--- a/cortex-m-rt/link.x.in
+++ b/cortex-m-rt/link.x.in
@@ -112,7 +112,6 @@ SECTIONS
__edata = .;
} > RAM AT > FLASH
-
/* LMA of .data */
__sidata = LOADADDR(.data);
@@ -126,7 +125,15 @@ SECTIONS
__ebss = .;
} > RAM
- /* Place the heap right after `.bss` */
+ /* ### .uninit */
+ .uninit (NOLOAD) : ALIGN(4)
+ {
+ . = ALIGN(4);
+ *(.uninit .uninit.*);
+ . = ALIGN(4);
+ } > RAM
+
+ /* Place the heap right after `.uninit` */
. = ALIGN(4);
__sheap = .;
diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs
index f7ecb91..d89df2a 100644
--- a/cortex-m-rt/src/lib.rs
+++ b/cortex-m-rt/src/lib.rs
@@ -360,13 +360,31 @@
//! }
//! ```
//!
-//! ## `pre_init!`
+//! ## Uninitialized static variables
//!
-//! A user-defined function can be run at the start of the reset handler, before RAM is
-//! initialized. The macro `pre_init!` can be called to set the function to be run. The function is
-//! intended to perform actions that cannot wait the time it takes for RAM to be initialized, such
-//! as disabling a watchdog. As the function is called before RAM is initialized, any access of
-//! static variables will result in undefined behavior.
+//! The `.uninit` linker section can be used to leave `static mut` variables uninitialized. One use
+//! case of unitialized static variables is to avoid zeroing large statically allocated buffers (say
+//! to be used as thread stacks) -- this can considerably reduce initialization time on devices that
+//! operate at low frequencies.
+//!
+//! The only correct way to use this section is by placing `static mut` variables with type
+//! [`MaybeUninit`] in it.
+//!
+//! [`MaybeUninit`]: https://doc.rust-lang.org/core/mem/union.MaybeUninit.html
+//!
+//! ``` ignore
+//! use core::mem::MaybeUninit;
+//!
+//! const STACK_SIZE: usize = 8 * 1024;
+//! const NTHREADS: usize = 4;
+//!
+//! #[link_section = ".uninit.STACKS"]
+//! static mut STACKS: MaybeUninit<[[u8; STACK_SIZE]; NTHREADS]> = MaybeUninit::uninit();
+//! ```
+//!
+//! Be very careful with the `link_section` attribute because it's easy to misuse in ways that cause
+//! undefined behavior. At some point in the future we may add an attribute to safely place static
+//! variables in this section.
// # Developer notes
//