diff --git a/mission/freeRTOS_rust_helper.c b/mission/freeRTOS_rust_helper.c index 3cf2049..744c81a 100644 --- a/mission/freeRTOS_rust_helper.c +++ b/mission/freeRTOS_rust_helper.c @@ -2,27 +2,40 @@ #include "semphr.h" #include "task.h" -#define NUMBER_OF_TASKS 1 +/** + * Task descriptors +*/ +#define NUMBER_OF_TASKS 100 SemaphoreHandle_t taskMutex = NULL; StaticSemaphore_t taskMutexDescriptor; size_t nextFreeTaskDescriptor = 0; StaticTask_t taskDescriptors[NUMBER_OF_TASKS]; +/** + * Queue descriptors +*/ +#define NUMBER_OF_QUEUES 300 +SemaphoreHandle_t queueMutex = NULL; +StaticSemaphore_t queueMutexDescriptor; +size_t nextFreeQueueDescriptor = 0; +StaticQueue_t queueDescriptors[NUMBER_OF_QUEUES]; + // TODO check and return void initFreeRTOSHelper() { taskMutex = xSemaphoreCreateRecursiveMutexStatic(&taskMutexDescriptor); + queueMutex = xSemaphoreCreateRecursiveMutexStatic(&queueMutexDescriptor); } -const char * getTaskName() { +const char * get_task_name() { return pcTaskGetName( NULL ); } -void stopIt() { +void stop_it() { taskENTER_CRITICAL(); } // TODO return some error code? -void *createTask(TaskFunction_t taskFunction, void *parameter, void *buffer, +void *create_task(TaskFunction_t taskFunction, void *parameter, void *buffer, size_t buffersize) { if (xSemaphoreTakeRecursive(taskMutex, portMAX_DELAY) != pdTRUE) { return NULL; @@ -45,4 +58,19 @@ void *createTask(TaskFunction_t taskFunction, void *parameter, void *buffer, void task_delay(uint32_t milliseconds) { vTaskDelay(pdMS_TO_TICKS(milliseconds)); +} + +void * create_queue(size_t length, size_t element_size, uint8_t * buffer) { + if (xSemaphoreTakeRecursive(queueMutex, portMAX_DELAY) != pdTRUE) { + return NULL; + } + // we hold the queue mutex and are now allowed to access the taskDescriptors + if (nextFreeQueueDescriptor >= + sizeof(queueDescriptors) / sizeof(*queueDescriptors)) { + return NULL; + } +QueueHandle_t newQueue = xQueueCreateStatic(length, element_size, buffer, queueDescriptors + nextFreeQueueDescriptor); +nextFreeQueueDescriptor++; +xSemaphoreGiveRecursive(queueMutex); + return newQueue; } \ No newline at end of file diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index 25d1cbe..d29ad01 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -1,5 +1,7 @@ #![no_std] +//TODO look into using core::ffi (some types do not seem to work) + #[macro_export] macro_rules! sifln { ($(,)?) => ( @@ -25,12 +27,12 @@ use core::panic::PanicInfo; #[panic_handler] fn panic(panic: &PanicInfo<'_>) -> ! { unsafe { - stopIt(); + stop_it(); } // TODO: Make this unicode-safe sif!("In Task \""); unsafe { - let task_name = getTaskName(); + let task_name = get_task_name(); let mut offset = 0; while *task_name.offset(offset) != 0 { sif!("{}", *task_name.offset(offset) as char); @@ -48,24 +50,32 @@ type TaskFunction = unsafe extern "C" fn(*mut cty::c_void); extern "C" { fn outbyte(c: cty::c_char); - fn createTask( + fn create_task( taskFunction: TaskFunction, parameter: *mut cty::c_void, buffer: *mut cty::c_void, buffersize: cty::size_t, ) -> *const cty::c_void; - fn getTaskName() -> *const cty::c_char; - fn stopIt(); + fn get_task_name() -> *const core::ffi::c_uchar; + fn stop_it(); + + //TODO wrap os agnostic fn vTaskDelete(handle: *const cty::c_void); fn task_delay(milliseconds: cty::uint32_t); + + fn create_queue( + length: cty::size_t, + element_size: cty::size_t, + buffer: *mut cty::c_void, + ) -> *const cty::c_void; } #[no_mangle] extern "C" fn rust_main() { - sifln!("Rust startup"); + sifln!("Rust startup 🚀"); mission(); sifln!("Mission done"); @@ -119,8 +129,9 @@ impl<'a, const STACKSIZE: usize> PeriodicTask<'a, STACKSIZE> { let runner_pointer: *mut cty::c_void = &mut instance.runner as *mut _ as *mut cty::c_void; let stack_pointer: *mut cty::c_void = &mut instance.stack as *mut _ as *mut cty::c_void; unsafe { - instance.task = createTask(task_entry, runner_pointer, stack_pointer, STACKSIZE); + instance.task = create_task(task_entry, runner_pointer, stack_pointer, STACKSIZE); } + let a: core::ffi::c_char; if instance.task == 0 as *mut cty::c_void { panic!("could not create Task"); } @@ -146,6 +157,45 @@ impl ExecutableObjectIF for Handler { } } +struct MessageQueue { + queueId: *const cty::c_void, + buffer: [T; LENGTH], +} + +struct MessageQueueSender { + queueId: *const cty::c_void, +} + +impl MessageQueue { + fn new() -> Self { + unsafe { + let mut instance = Self { + queueId: 0 as *const cty::c_void, + buffer: [core::mem::MaybeUninit::zeroed().assume_init();LENGTH] + }; + let buffer_pointer: *mut cty::c_void = + &mut instance.buffer as *mut _ as *mut cty::c_void; + instance.queueId = create_queue(LENGTH, core::mem::size_of::(), buffer_pointer); + + if instance.queueId == 0 as *mut cty::c_void { + panic!("could not create Queue"); + } + instance + } + } + + fn getSender(self) -> MessageQueueSender { + let instance:MessageQueueSender = MessageQueueSender::{queueId: self.queueId}; + instance + } +} + +impl MessageQueueSender { + fn send(message: T) { + + } +} + struct Outbytes {} use core::fmt::{Error, Write};