33//! # Example
44//!
55//! ```
6- //! // Plug in the allocator
6+ //! // Plug in the allocator crate
77//! extern crate alloc_cortex_m;
88//! extern crate collections;
99//!
10- //! use alloc_cortex_m::HEAP;
1110//! use collections::Vec;
1211//!
12+ //! // These symbols come from a linker script
13+ //! extern "C" {
14+ //! static mut _heap_start: usize;
15+ //! static mut _heap_end: usize;
16+ //! }
17+ //!
1318//! #[no_mangle]
1419//! pub fn main() -> ! {
1520//! // Initialize the heap BEFORE you use the allocator
16- //! unsafe { HEAP. init(0x2000_0000, 1024 ) }
21+ //! unsafe { alloc_cortex_m:: init(&mut _heap_start, &mut _heap_end ) }
1722//!
1823//! let mut xs = Vec::new();
1924//! xs.push(1);
2025//! // ...
2126//! }
2227//! ```
28+ //!
29+ //! And in your linker script, you might have something like:
30+ //!
31+ //! ``` text
32+ //! /* space reserved for the stack */
33+ //! _stack_size = 0x1000;
34+ //!
35+ //! /* `.` is right after the .bss and .data sections */
36+ //! _heap_start = .;
37+ //! _heap_end = ORIGIN(SRAM) + LENGTH(SRAM) - _stack_size;
38+ //! ```
2339
2440#![ allocator]
2541#![ feature( allocator) ]
2945extern crate cortex_m;
3046extern crate linked_list_allocator;
3147
32- use core:: { ptr , cmp } ;
48+ use core:: { cmp , ptr } ;
3349
50+ use linked_list_allocator:: Heap ;
3451use cortex_m:: interrupt:: Mutex ;
3552
3653/// A global UNINITIALIZED heap allocator
3754///
3855/// You must initialize this heap using the
3956/// [`init`](struct.Heap.html#method.init) method before using the allocator.
40- pub static HEAP : Mutex < Heap > = Mutex :: new ( Heap :: empty ( ) ) ;
41-
42- /// A heap allocator
43- // NOTE newtype to hide all the other Heap methods
44- pub struct Heap {
45- inner : linked_list_allocator:: Heap ,
46- }
47-
48- impl Heap {
49- const fn empty ( ) -> Self {
50- Heap { inner : linked_list_allocator:: Heap :: empty ( ) }
51- }
57+ static HEAP : Mutex < Heap > = Mutex :: new ( Heap :: empty ( ) ) ;
5258
53- /// Initializes the heap
54- ///
55- /// This method must be called before you run any code that makes use of the
56- /// allocator.
57- ///
58- /// This method must be called exactly ONCE.
59- ///
60- /// `heap_bottom` is the address where the heap will be located. Note that
61- /// heap grows "upwards", towards larger addresses.
62- ///
63- /// `heap_size` is the size of the heap in bytes
64- pub unsafe fn init ( & mut self , heap_bottom : usize , heap_size : usize ) {
65- self . inner . init ( heap_bottom, heap_size) ;
66- }
59+ /// Initializes the heap
60+ ///
61+ /// This function must be called BEFORE you run any code that makes use of the
62+ /// allocator.
63+ ///
64+ /// `start_addr` is the address where the heap will be located.
65+ ///
66+ /// `end_addr` points to the end of the heap.
67+ ///
68+ /// Note that:
69+ ///
70+ /// - The heap grows "upwards", towards larger addresses. Thus `end_addr` must
71+ /// be larger than `start_addr`
72+ ///
73+ /// - The size of the heap will actually be
74+ /// `(end_addr as usize) - (start_addr as usize) + 1` because the allocator
75+ /// won't use the byte at `end_addr`.
76+ ///
77+ /// # Unsafety
78+ ///
79+ /// Obey these or Bad Stuff will happen.
80+ ///
81+ /// - This function must be called exactly ONCE.
82+ /// - `end_addr` > `start_addr`
83+ pub unsafe fn init ( start_addr : * mut usize , end_addr : * mut usize ) {
84+ let start = start_addr as usize ;
85+ let end = end_addr as usize ;
86+ let size = ( end - start) - 1 ;
87+ HEAP . lock ( |heap| heap. init ( start, size) ) ;
6788}
6889
6990// Rust allocator interface
@@ -73,15 +94,15 @@ impl Heap {
7394/// Rust allocation function (c.f. malloc)
7495pub extern "C" fn __rust_allocate ( size : usize , align : usize ) -> * mut u8 {
7596 HEAP . lock ( |heap| {
76- heap. inner . allocate_first_fit ( size, align) . expect ( "out of memory" )
97+ heap. allocate_first_fit ( size, align) . expect ( "out of memory" )
7798 } )
7899}
79100
80101/// Rust de-allocation function (c.f. free)
81102#[ doc( hidden) ]
82103#[ no_mangle]
83104pub extern "C" fn __rust_deallocate ( ptr : * mut u8 , size : usize , align : usize ) {
84- HEAP . lock ( |heap| unsafe { heap. inner . deallocate ( ptr, size, align) } ) ;
105+ HEAP . lock ( |heap| unsafe { heap. deallocate ( ptr, size, align) } ) ;
85106}
86107
87108/// Rust re-allocation function (c.f. realloc)
0 commit comments