#[repr(C)]
pub struct HeapStats_t {
pub xAvailableHeapSpaceInBytes: usize,
pub xSizeOfLargestFreeBlockInBytes: usize,
pub xSizeOfSmallestFreeBlockInBytes: usize,
pub xNumberOfFreeBlocks: usize,
pub xMinimumEverFreeBytesRemaining: usize,
pub xNumberOfSuccessfulAllocations: usize,
pub xNumberOfSuccessfulFrees: usize,
}
#[repr(C)]
pub struct HeapRegion_t {
pub pucStartAddress: *mut u8,
pub xSizeInBytes: usize,
}
#[cfg(feature = "heap-4")]
mod heap_4;
#[cfg(feature = "heap-4")]
pub use heap_4::*;
#[cfg(feature = "heap-4")]
pub use heap_4::FreeRtosAllocator;
#[cfg(all(feature = "heap-5", not(feature = "heap-4")))]
mod heap_5;
#[cfg(all(feature = "heap-5", not(feature = "heap-4")))]
pub use heap_5::*;
#[cfg(all(feature = "heap-5", not(feature = "heap-4")))]
pub use heap_5::FreeRtosAllocator;
#[cfg(all(feature = "heap-5", not(feature = "heap-4")))]
pub use heap_5::HeapRegion;
#[cfg(all(feature = "alloc", not(any(feature = "heap-4", feature = "heap-5"))))]
mod alloc_impl {
use alloc::alloc::{alloc, dealloc, Layout};
use core::ffi::c_void;
use core::ptr;
use core::sync::atomic::{AtomicUsize, Ordering};
static ALLOCATED_BYTES: AtomicUsize = AtomicUsize::new(0);
pub unsafe fn pvPortMalloc(xWantedSize: usize) -> *mut c_void {
if xWantedSize == 0 {
return ptr::null_mut();
}
let total_size = xWantedSize + core::mem::size_of::<usize>();
let layout = match Layout::from_size_align(total_size, crate::port::portBYTE_ALIGNMENT) {
Ok(l) => l,
Err(_) => return ptr::null_mut(),
};
let ptr = alloc(layout);
if ptr.is_null() {
return ptr::null_mut();
}
*(ptr as *mut usize) = total_size;
ALLOCATED_BYTES.fetch_add(total_size, Ordering::Relaxed);
ptr.add(core::mem::size_of::<usize>()) as *mut c_void
}
pub unsafe fn vPortFree(pv: *mut c_void) {
if pv.is_null() {
return;
}
let size_ptr = (pv as *mut u8).sub(core::mem::size_of::<usize>()) as *mut usize;
let total_size = *size_ptr;
let layout = Layout::from_size_align_unchecked(total_size, crate::port::portBYTE_ALIGNMENT);
ALLOCATED_BYTES.fetch_sub(total_size, Ordering::Relaxed);
dealloc(size_ptr as *mut u8, layout);
}
pub fn xPortGetFreeHeapSize() -> usize {
usize::MAX - ALLOCATED_BYTES.load(Ordering::Relaxed)
}
pub fn xPortGetMinimumEverFreeHeapSize() -> usize {
xPortGetFreeHeapSize()
}
pub unsafe fn pvPortCalloc(xNum: usize, xSize: usize) -> *mut c_void {
let total = match xNum.checked_mul(xSize) {
Some(t) => t,
None => return ptr::null_mut(),
};
let ptr = pvPortMalloc(total);
if !ptr.is_null() {
ptr::write_bytes(ptr as *mut u8, 0, total);
}
ptr
}
pub fn vPortInitialiseBlocks() {}
pub fn vPortHeapResetState() {}
pub fn xPortResetHeapMinimumEverFreeHeapSize() {}
pub fn vPortGetHeapStats(pxHeapStats: *mut super::HeapStats_t) {
unsafe {
(*pxHeapStats).xAvailableHeapSpaceInBytes = xPortGetFreeHeapSize();
(*pxHeapStats).xSizeOfLargestFreeBlockInBytes = xPortGetFreeHeapSize();
(*pxHeapStats).xSizeOfSmallestFreeBlockInBytes = 0;
(*pxHeapStats).xNumberOfFreeBlocks = 1;
(*pxHeapStats).xMinimumEverFreeBytesRemaining = xPortGetMinimumEverFreeHeapSize();
(*pxHeapStats).xNumberOfSuccessfulAllocations = 0;
(*pxHeapStats).xNumberOfSuccessfulFrees = 0;
}
}
}
#[cfg(all(feature = "alloc", not(any(feature = "heap-4", feature = "heap-5"))))]
pub use alloc_impl::*;
#[cfg(not(any(feature = "heap-4", feature = "heap-5", feature = "alloc")))]
mod stub_impl {
use core::ffi::c_void;
use core::ptr;
pub unsafe fn pvPortMalloc(_xWantedSize: usize) -> *mut c_void {
panic!("pvPortMalloc called but no heap feature is enabled (use `heap-4` or `alloc`)");
}
pub unsafe fn vPortFree(_pv: *mut c_void) {
panic!("vPortFree called but no heap feature is enabled");
}
pub fn xPortGetFreeHeapSize() -> usize {
0
}
pub fn xPortGetMinimumEverFreeHeapSize() -> usize {
0
}
pub unsafe fn pvPortCalloc(_xNum: usize, _xSize: usize) -> *mut c_void {
panic!("pvPortCalloc called but no heap feature is enabled");
}
pub fn vPortInitialiseBlocks() {}
pub fn vPortHeapResetState() {}
pub fn xPortResetHeapMinimumEverFreeHeapSize() {}
pub fn vPortGetHeapStats(pxHeapStats: *mut super::HeapStats_t) {
unsafe {
(*pxHeapStats).xAvailableHeapSpaceInBytes = 0;
(*pxHeapStats).xSizeOfLargestFreeBlockInBytes = 0;
(*pxHeapStats).xSizeOfSmallestFreeBlockInBytes = 0;
(*pxHeapStats).xNumberOfFreeBlocks = 0;
(*pxHeapStats).xMinimumEverFreeBytesRemaining = 0;
(*pxHeapStats).xNumberOfSuccessfulAllocations = 0;
(*pxHeapStats).xNumberOfSuccessfulFrees = 0;
}
}
}
#[cfg(not(any(feature = "heap-4", feature = "heap-5", feature = "alloc")))]
pub use stub_impl::*;