linuxcnc_hal/hal_pin/
hal_pin.rs1use crate::error::{PinRegisterError, StorageError};
2use linuxcnc_hal_sys::hal_malloc;
3use std::{convert::TryInto, mem};
4
5fn is_aligned_to<T: ?Sized>(ptr: *const T, align: usize) -> bool {
6 assert!(align.is_power_of_two());
7 let ptr = ptr as *const u8 as usize;
8 let mask = align.wrapping_sub(1);
9 (ptr & mask) == 0
10}
11
12pub trait HalPin: Sized {
16 type Storage: std::fmt::Debug;
20
21 fn allocate_storage() -> Result<*mut *mut Self::Storage, StorageError> {
32 let storage_ptr = unsafe {
33 let size = mem::size_of::<Self::Storage>();
34
35 let ptr_size = mem::size_of::<*mut Self::Storage>().try_into().unwrap();
36
37 debug!("Allocating {} bytes (ptr size {})", size, ptr_size);
38
39 let ptr = hal_malloc(ptr_size) as *mut *mut Self::Storage;
40
41 if ptr.is_null() {
42 return Err(StorageError::Null);
43 }
44
45 if !is_aligned_to(ptr, size) {
46 return Err(StorageError::Alignment);
47 }
48
49 debug!("Allocated value {:?} at {:?}", *ptr, ptr);
50
51 ptr
52 };
53
54 Ok(storage_ptr)
55 }
56
57 fn name(&self) -> &str;
59
60 fn storage_mut(&self) -> Result<&mut Self::Storage, StorageError>;
62
63 fn storage(&self) -> Result<&Self::Storage, StorageError>;
65
66 fn register(full_pin_name: &str, component_id: i32) -> Result<Self, PinRegisterError>;
70}