esp_wifi/compat/
malloc.rs1#[unsafe(no_mangle)]
2pub unsafe extern "C" fn malloc(size: usize) -> *mut u8 {
3 trace!("alloc {}", size);
4
5 unsafe extern "C" {
6 fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8;
7 }
8
9 let ptr = unsafe { esp_wifi_allocate_from_internal_ram(size) };
10
11 if ptr.is_null() {
12 warn!("Unable to allocate {} bytes", size);
13 }
14
15 ptr
16}
17
18#[unsafe(no_mangle)]
19pub unsafe extern "C" fn free(ptr: *mut u8) {
20 trace!("free {:?}", ptr);
21
22 if ptr.is_null() {
23 warn!("Attempt to free null pointer");
24 return;
25 }
26
27 unsafe extern "C" {
28 fn esp_wifi_deallocate_internal_ram(ptr: *mut u8);
29 }
30
31 unsafe {
32 esp_wifi_deallocate_internal_ram(ptr);
33 }
34}
35
36#[unsafe(no_mangle)]
37pub unsafe extern "C" fn calloc(number: u32, size: usize) -> *mut u8 {
38 trace!("calloc {} {}", number, size);
39
40 let total_size = number as usize * size;
41 unsafe {
42 let ptr = malloc(total_size);
43
44 if !ptr.is_null() {
45 for i in 0..total_size as isize {
46 ptr.offset(i).write_volatile(0);
47 }
48 }
49
50 ptr
51 }
52}
53
54#[unsafe(no_mangle)]
55unsafe extern "C" fn realloc(ptr: *mut u8, new_size: usize) -> *mut u8 {
56 trace!("realloc {:?} {}", ptr, new_size);
57
58 unsafe extern "C" {
59 fn memcpy(d: *mut u8, s: *const u8, l: usize);
60 }
61
62 unsafe {
63 let p = malloc(new_size);
64 if !p.is_null() && !ptr.is_null() {
65 let len = usize::min(
66 (ptr as *const u32).sub(1).read_volatile() as usize,
67 new_size,
68 );
69 memcpy(p, ptr, len);
70 free(ptr);
71 }
72 p
73 }
74}
75
76#[cfg(feature = "esp-alloc")]
77#[doc(hidden)]
78#[unsafe(no_mangle)]
79pub extern "C" fn esp_wifi_free_internal_heap() -> usize {
80 esp_alloc::HEAP.free_caps(esp_alloc::MemoryCapability::Internal.into())
81}
82
83#[cfg(feature = "esp-alloc")]
84#[doc(hidden)]
85#[unsafe(no_mangle)]
86pub extern "C" fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8 {
87 let total_size = size + 4;
88 unsafe {
89 let ptr = esp_alloc::HEAP.alloc_caps(
90 esp_alloc::MemoryCapability::Internal.into(),
91 core::alloc::Layout::from_size_align_unchecked(total_size, 4),
92 );
93
94 if ptr.is_null() {
95 return ptr;
96 }
97
98 *(ptr as *mut usize) = total_size;
99 ptr.offset(4)
100 }
101}
102
103#[cfg(feature = "esp-alloc")]
104#[doc(hidden)]
105#[unsafe(no_mangle)]
106pub extern "C" fn esp_wifi_deallocate_internal_ram(ptr: *mut u8) {
107 use core::alloc::GlobalAlloc;
108
109 unsafe {
110 let ptr = ptr.offset(-4);
111 let total_size = *(ptr as *const usize);
112
113 esp_alloc::HEAP.dealloc(
114 ptr,
115 core::alloc::Layout::from_size_align_unchecked(total_size, 4),
116 )
117 }
118}
119
120#[cfg(not(feature = "esp-alloc"))]
122mod esp_alloc {
123 use core::{alloc::Layout, ptr::NonNull};
124
125 use allocator_api2::alloc::{AllocError, Allocator};
126
127 pub struct InternalMemory;
129
130 unsafe impl Allocator for InternalMemory {
131 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
132 unsafe extern "C" {
133 fn esp_wifi_allocate_from_internal_ram(size: usize) -> *mut u8;
134 }
135 let raw_ptr = unsafe { esp_wifi_allocate_from_internal_ram(layout.size()) };
136 let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
137 Ok(NonNull::slice_from_raw_parts(ptr, layout.size()))
138 }
139
140 unsafe fn deallocate(&self, ptr: NonNull<u8>, _layout: Layout) {
141 unsafe extern "C" {
142 fn esp_wifi_deallocate_internal_ram(ptr: *mut u8);
143 }
144 unsafe {
145 esp_wifi_deallocate_internal_ram(ptr.as_ptr());
146 }
147 }
148 }
149}
150
151pub(crate) use esp_alloc::InternalMemory;