diff options
author | 2019-06-19 07:18:52 +0000 | |
---|---|---|
committer | 2019-06-19 07:18:52 +0000 | |
commit | 5678f48fb3d4badf521b9720381c1f1a80994ddc (patch) | |
tree | 0751b8519f469d5c8b158f3de5974ca352963e93 | |
parent | 8a6e9f1ddcc57010dfa1f247aacb2cf67e110211 (diff) | |
parent | 94fbbe01189f97aefa8d6a97cc7cd73e5c6f6ec9 (diff) | |
download | cortex-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.in | 11 | ||||
-rw-r--r-- | cortex-m-rt/src/lib.rs | 30 |
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 // |