working on queues

This commit is contained in:
Ulrich Mohr 2023-11-15 15:15:37 +01:00
parent 15478854f5
commit 1c3ba9e20f
2 changed files with 89 additions and 11 deletions

View File

@ -2,27 +2,40 @@
#include "semphr.h" #include "semphr.h"
#include "task.h" #include "task.h"
#define NUMBER_OF_TASKS 1 /**
* Task descriptors
*/
#define NUMBER_OF_TASKS 100
SemaphoreHandle_t taskMutex = NULL; SemaphoreHandle_t taskMutex = NULL;
StaticSemaphore_t taskMutexDescriptor; StaticSemaphore_t taskMutexDescriptor;
size_t nextFreeTaskDescriptor = 0; size_t nextFreeTaskDescriptor = 0;
StaticTask_t taskDescriptors[NUMBER_OF_TASKS]; 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 // TODO check and return
void initFreeRTOSHelper() { void initFreeRTOSHelper() {
taskMutex = xSemaphoreCreateRecursiveMutexStatic(&taskMutexDescriptor); taskMutex = xSemaphoreCreateRecursiveMutexStatic(&taskMutexDescriptor);
queueMutex = xSemaphoreCreateRecursiveMutexStatic(&queueMutexDescriptor);
} }
const char * getTaskName() { const char * get_task_name() {
return pcTaskGetName( NULL ); return pcTaskGetName( NULL );
} }
void stopIt() { void stop_it() {
taskENTER_CRITICAL(); taskENTER_CRITICAL();
} }
// TODO return some error code? // 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) { size_t buffersize) {
if (xSemaphoreTakeRecursive(taskMutex, portMAX_DELAY) != pdTRUE) { if (xSemaphoreTakeRecursive(taskMutex, portMAX_DELAY) != pdTRUE) {
return NULL; return NULL;
@ -45,4 +58,19 @@ void *createTask(TaskFunction_t taskFunction, void *parameter, void *buffer,
void task_delay(uint32_t milliseconds) { void task_delay(uint32_t milliseconds) {
vTaskDelay(pdMS_TO_TICKS(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;
} }

View File

@ -1,5 +1,7 @@
#![no_std] #![no_std]
//TODO look into using core::ffi (some types do not seem to work)
#[macro_export] #[macro_export]
macro_rules! sifln { macro_rules! sifln {
($(,)?) => ( ($(,)?) => (
@ -25,12 +27,12 @@ use core::panic::PanicInfo;
#[panic_handler] #[panic_handler]
fn panic(panic: &PanicInfo<'_>) -> ! { fn panic(panic: &PanicInfo<'_>) -> ! {
unsafe { unsafe {
stopIt(); stop_it();
} }
// TODO: Make this unicode-safe // TODO: Make this unicode-safe
sif!("In Task \""); sif!("In Task \"");
unsafe { unsafe {
let task_name = getTaskName(); let task_name = get_task_name();
let mut offset = 0; let mut offset = 0;
while *task_name.offset(offset) != 0 { while *task_name.offset(offset) != 0 {
sif!("{}", *task_name.offset(offset) as char); sif!("{}", *task_name.offset(offset) as char);
@ -48,24 +50,32 @@ type TaskFunction = unsafe extern "C" fn(*mut cty::c_void);
extern "C" { extern "C" {
fn outbyte(c: cty::c_char); fn outbyte(c: cty::c_char);
fn createTask( fn create_task(
taskFunction: TaskFunction, taskFunction: TaskFunction,
parameter: *mut cty::c_void, parameter: *mut cty::c_void,
buffer: *mut cty::c_void, buffer: *mut cty::c_void,
buffersize: cty::size_t, buffersize: cty::size_t,
) -> *const cty::c_void; ) -> *const cty::c_void;
fn getTaskName() -> *const cty::c_char; fn get_task_name() -> *const core::ffi::c_uchar;
fn stopIt();
fn stop_it();
//TODO wrap os agnostic
fn vTaskDelete(handle: *const cty::c_void); fn vTaskDelete(handle: *const cty::c_void);
fn task_delay(milliseconds: cty::uint32_t); 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] #[no_mangle]
extern "C" fn rust_main() { extern "C" fn rust_main() {
sifln!("Rust startup"); sifln!("Rust startup 🚀");
mission(); mission();
sifln!("Mission done"); 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 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; let stack_pointer: *mut cty::c_void = &mut instance.stack as *mut _ as *mut cty::c_void;
unsafe { 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 { if instance.task == 0 as *mut cty::c_void {
panic!("could not create Task"); panic!("could not create Task");
} }
@ -146,6 +157,45 @@ impl ExecutableObjectIF for Handler {
} }
} }
struct MessageQueue<T, const LENGTH: usize> {
queueId: *const cty::c_void,
buffer: [T; LENGTH],
}
struct MessageQueueSender<T> {
queueId: *const cty::c_void,
}
impl<T: Copy, const LENGTH: usize> MessageQueue<T, LENGTH> {
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::<T>(), buffer_pointer);
if instance.queueId == 0 as *mut cty::c_void {
panic!("could not create Queue");
}
instance
}
}
fn getSender(self) -> MessageQueueSender<T> {
let instance:MessageQueueSender<T> = MessageQueueSender::<T>{queueId: self.queueId};
instance
}
}
impl<T> MessageQueueSender<T> {
fn send(message: T) {
}
}
struct Outbytes {} struct Outbytes {}
use core::fmt::{Error, Write}; use core::fmt::{Error, Write};