3
3
//! # Example
4
4
//!
5
5
//! ```
6
- //! // Plug in the allocator
6
+ //! // Plug in the allocator crate
7
7
//! extern crate alloc_cortex_m;
8
8
//! extern crate collections;
9
9
//!
10
- //! use alloc_cortex_m::HEAP;
11
10
//! use collections::Vec;
12
11
//!
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
+ //!
13
18
//! #[no_mangle]
14
19
//! pub fn main() -> ! {
15
20
//! // 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 ) }
17
22
//!
18
23
//! let mut xs = Vec::new();
19
24
//! xs.push(1);
20
25
//! // ...
21
26
//! }
22
27
//! ```
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
+ //! ```
23
39
24
40
#![ allocator]
25
41
#![ feature( allocator) ]
29
45
extern crate cortex_m;
30
46
extern crate linked_list_allocator;
31
47
32
- use core:: { ptr , cmp } ;
48
+ use core:: { cmp , ptr } ;
33
49
50
+ use linked_list_allocator:: Heap ;
34
51
use cortex_m:: interrupt:: Mutex ;
35
52
36
53
/// A global UNINITIALIZED heap allocator
37
54
///
38
55
/// You must initialize this heap using the
39
56
/// [`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 ( ) ) ;
52
58
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) ) ;
67
88
}
68
89
69
90
// Rust allocator interface
@@ -73,15 +94,15 @@ impl Heap {
73
94
/// Rust allocation function (c.f. malloc)
74
95
pub extern "C" fn __rust_allocate ( size : usize , align : usize ) -> * mut u8 {
75
96
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" )
77
98
} )
78
99
}
79
100
80
101
/// Rust de-allocation function (c.f. free)
81
102
#[ doc( hidden) ]
82
103
#[ no_mangle]
83
104
pub 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) } ) ;
85
106
}
86
107
87
108
/// Rust re-allocation function (c.f. realloc)
0 commit comments