use core::ffi::c_void;
use core::ptr;
use crate::kernel::tasks::{xTaskGetCurrentTaskHandle, xTaskCreateStatic, StaticTask_t};
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
use crate::kernel::tasks::xTaskCreate;
#[cfg(feature = "task-delete")]
use crate::kernel::tasks::vTaskDelete;
#[cfg(feature = "task-suspend")]
use crate::kernel::tasks::{vTaskResume, vTaskSuspend};
use crate::types::*;
#[derive(Clone, Copy)]
pub struct TaskHandle {
handle: TaskHandle_t,
}
unsafe impl Sync for TaskHandle {}
unsafe impl Send for TaskHandle {}
pub type TaskFn = extern "C" fn(*mut c_void);
impl TaskHandle {
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
pub fn spawn(
name: &[u8],
stack_size: usize,
priority: UBaseType_t,
task_fn: TaskFn,
) -> Option<Self> {
Self::spawn_with_param(name, stack_size, priority, task_fn, ptr::null_mut())
}
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
pub fn spawn_with_param(
name: &[u8],
stack_size: usize,
priority: UBaseType_t,
task_fn: TaskFn,
param: *mut c_void,
) -> Option<Self> {
let mut handle: TaskHandle_t = ptr::null_mut();
let result = unsafe {
xTaskCreate(
task_fn,
name.as_ptr(),
stack_size,
param,
priority,
&mut handle,
)
};
if result == pdPASS && !handle.is_null() {
Some(Self { handle })
} else {
None
}
}
pub fn spawn_static(
name: &[u8],
stack: &'static mut [StackType_t],
tcb: &'static mut StaticTask_t,
priority: UBaseType_t,
task_fn: TaskFn,
) -> Option<Self> {
Self::spawn_static_with_param(name, stack, tcb, priority, task_fn, ptr::null_mut())
}
pub fn spawn_static_with_param(
name: &[u8],
stack: &'static mut [StackType_t],
tcb: &'static mut StaticTask_t,
priority: UBaseType_t,
task_fn: TaskFn,
param: *mut c_void,
) -> Option<Self> {
let handle = unsafe {
xTaskCreateStatic(
task_fn,
name.as_ptr(),
stack.len(),
param,
priority,
stack.as_mut_ptr(),
tcb as *mut StaticTask_t,
)
};
if handle.is_null() {
None
} else {
Some(Self { handle })
}
}
#[cfg(feature = "task-suspend")]
pub fn suspend(&self) {
vTaskSuspend(self.handle);
}
#[cfg(feature = "task-suspend")]
pub fn resume(&self) {
vTaskResume(self.handle);
}
#[cfg(feature = "task-delete")]
pub fn delete(self) {
vTaskDelete(self.handle);
}
#[cfg(feature = "task-priority-set")]
pub fn priority(&self) -> UBaseType_t {
unsafe { crate::kernel::tasks::uxTaskPriorityGet(self.handle) }
}
#[cfg(feature = "task-priority-set")]
pub fn set_priority(&self, new_priority: UBaseType_t) {
unsafe { crate::kernel::tasks::vTaskPrioritySet(self.handle, new_priority) }
}
pub fn current() -> Self {
Self {
handle: xTaskGetCurrentTaskHandle(),
}
}
pub unsafe fn raw_handle(&self) -> TaskHandle_t {
self.handle
}
pub unsafe fn from_raw(handle: TaskHandle_t) -> Self {
Self { handle }
}
}
#[cfg(feature = "task-suspend")]
pub fn suspend_self() {
vTaskSuspend(ptr::null_mut());
}
#[cfg(feature = "task-delete")]
pub fn delete_self() -> ! {
vTaskDelete(ptr::null_mut());
unreachable!()
}