From 89fa2f9466097101c9f7dfd071f150bff8d92ec0 Mon Sep 17 00:00:00 2001 From: Anthony Rabine Date: Fri, 21 Jul 2023 18:26:53 +0200 Subject: [PATCH] External stack for QoRTOS --- software/system/main.c | 61 +++++++++++++++++------------------------- software/system/qor.c | 19 +++++++------ software/system/qor.h | 17 +++--------- 3 files changed, 37 insertions(+), 60 deletions(-) diff --git a/software/system/main.c b/software/system/main.c index 3663c4c..cf87541 100644 --- a/software/system/main.c +++ b/software/system/main.c @@ -86,8 +86,6 @@ ost_event_t ev_queue[10]; qor_tcb_t tcb1; qor_tcb_t tcb2; -qor_tcb_t tcb3; -qor_tcb_t idle; void UserTask_1(void *args) { @@ -146,10 +144,15 @@ void UserTask_2(void *args) } } -void UserTask_3(void *args) +// =========================================================================================================== +// SD CARD TASK +// =========================================================================================================== +static qor_tcb_t AudioTcb; +static uint32_t AudioStack[1024]; +void AudioTask(void *args) { - int cpt = 0; - + picture_show("example.bmp"); + // ost_audio_play("out2.wav"); while (1) { @@ -157,16 +160,15 @@ void UserTask_3(void *args) qor_sleep(500); ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 1); qor_sleep(500); - - // if (++cpt >= 10) - // { - // cpt = 0; - // debug_printf("SU: %d, SO: %d\r\n", tcb3.stack_usage, tcb3.so); - // } } } -void IdleTaskFunction(void *args) +// =========================================================================================================== +// IDLE TASK +// =========================================================================================================== +static qor_tcb_t IdleTcb; +static uint32_t IdleStack[1024]; +void IdleTask(void *args) { while (1) { @@ -175,41 +177,28 @@ void IdleTaskFunction(void *args) } } +// =========================================================================================================== +// MAIN ENTRY POINT +// =========================================================================================================== int main() { - // timer_hw->inte = 0; - // timer_hw->alarm[3] = 0; - // timer_hw->dbgpause = 1; - + // 1. Call the platform initialization ost_system_initialize(); - // 1. Test the printf output + // 2. Test the printf output debug_printf("\r\n [OST] Starting OpenStoryTeller tests: V%d.%d\r\n", 1, 0); - /* - filesystem_mount(); - picture_show("example.bmp"); - */ - // ost_audio_play("out2.wav"); + // 3. Filesystem / SDCard initialization + filesystem_mount(); - qor_init(THREADFREQ); + // 4. Initialize OS and threads + qor_init(125000000UL); // qor_create_thread(&tcb1, UserTask_1, 2, "UserTask_1"); // qor_create_thread(&tcb2, UserTask_2, 1, "UserTask_2"); - qor_create_thread(&tcb3, UserTask_3, 3, "UserTask_3"); + qor_create_thread(&AudioTcb, AudioTask, AudioStack, 1024, 3, "AudioTask"); ///< High priority for audio + qor_start(&IdleTcb, IdleTask, IdleStack, 1024); - qor_start(&idle, IdleTaskFunction); - - for (;;) - { - - // ost_hal_audio_loop(); - - // ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 1); - // ost_system_delay_ms(1000); - // ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 0); - // ost_system_delay_ms(1000); - } return 0; } #endif diff --git a/software/system/qor.c b/software/system/qor.c index 0c65623..7e71227 100644 --- a/software/system/qor.c +++ b/software/system/qor.c @@ -149,9 +149,6 @@ static void timer_init() // =========================================================================================================== // GLOBAL AND STATIC VARIABLES // =========================================================================================================== - -static uint32_t Stacks[MAXNUMTHREADS][STACKSIZE]; - /* Pointer to the currently running thread */ qor_tcb_t *RunPt = NULL; static qor_tcb_t *TcbHead = NULL; @@ -210,14 +207,15 @@ uint32_t *qor_initialize_stack(uint32_t *top_of_stack, thread_func_t task, void return top_of_stack; } -void qor_create_thread(qor_tcb_t *tcb, thread_func_t task, uint8_t priority, const char *name) +void qor_create_thread(qor_tcb_t *tcb, thread_func_t task, uint32_t *stack, uint32_t stack_size, uint8_t priority, const char *name) { - assert_or_panic(ActiveTCBsCount >= 0 && ActiveTCBsCount < MAXNUMTHREADS); + // assert_or_panic(ActiveTCBsCount >= 0 && ActiveTCBsCount < MAXNUMTHREADS); disable_irq(); - memset(&Stacks[ActiveTCBsCount][0], 0xAAAAAAAA, sizeof(Stacks[ActiveTCBsCount][0]) * STACKSIZE); + memset(&stack[0], 0xAAAAAAAA, sizeof(stack[0]) * stack_size); - tcb->stack_bottom = &Stacks[ActiveTCBsCount][0]; + tcb->stack_bottom = &stack[0]; + tcb->stack_size = stack_size; tcb->stack_usage = 0; tcb->so = false; @@ -229,7 +227,8 @@ void qor_create_thread(qor_tcb_t *tcb, thread_func_t task, uint8_t priority, con tcb->next = NULL; tcb->mbox = NULL; tcb->wait_next = NULL; - tcb->sp = qor_initialize_stack(&Stacks[ActiveTCBsCount][STACKSIZE], task, (void *)name); + // The ARM architecture is full-descending task, so we indicate the last occupied entry (not a free cell) + tcb->sp = qor_initialize_stack(&stack[stack_size], task, (void *)name); if (TcbHead == NULL) { @@ -251,7 +250,7 @@ void qor_create_thread(qor_tcb_t *tcb, thread_func_t task, uint8_t priority, con enable_irq(); } -bool __attribute__((naked)) qor_start(qor_tcb_t *idle_tcb, thread_func_t idle_task) +bool __attribute__((naked)) qor_start(qor_tcb_t *idle_tcb, thread_func_t idle_task, uint32_t *idle_stack, uint32_t idle_stack_size) { assert_or_panic(ActiveTCBsCount > 0); @@ -260,7 +259,7 @@ bool __attribute__((naked)) qor_start(qor_tcb_t *idle_tcb, thread_func_t idle_ta return false; } - qor_create_thread(idle_tcb, idle_task, 0, "IdleTask"); + qor_create_thread(idle_tcb, idle_task, idle_stack, idle_stack_size, 0, "IdleTask"); // FIXME: use the scheduler to find the best first thread to start IdleTcb = idle_tcb; diff --git a/software/system/qor.h b/software/system/qor.h index 335cdcc..e622505 100644 --- a/software/system/qor.h +++ b/software/system/qor.h @@ -11,18 +11,6 @@ extern void ost_hal_panic(); */ #define assert_or_panic(expr) ((expr) ? (void)0U : ost_hal_panic()) -/** - * The module os encapsulates the core functionality of the operating system and - * exposes the functions for interacting with it. - */ - -#define MAXNUMTHREADS 4 /* Maximum number of threads, allocated at compile time */ -#define STACKSIZE 100 /* Number of 32-bit words in each TCB's stack */ -#define THREADFREQ 1 /* Maximum time-slice, in Hz, before the scheduler is run */ - -#define OS_SCHEDL_PRIO_MIN 1 /* Lowest priority that can be assigned to a thread */ -#define OS_SCHEDL_PRIO_MAX UINT8_MAX /* Highest priority that can be assigned to a thread */ - typedef void (*thread_func_t)(void *args); // =========================================================================================================== @@ -52,6 +40,7 @@ typedef struct TCB uint32_t *sp; //!< Stack pointer, valid for threads not running struct TCB *next; //!< Pointer to circular-linked-list of TCBs struct TCB *wait_next; //!< Next TCB in waiting list + uint32_t stack_size; qor_tcb_state_t state; //!< TCB active or free uint32_t wait_time; //!< Timeout for mbox maiting or sleep qor_mbox_t *mbox; //!< Pointer to mailbox on which the thread is blocked, NULL if not blocked @@ -68,9 +57,9 @@ typedef struct TCB void qor_init(uint32_t scheduler_frequency_hz); -void qor_create_thread(qor_tcb_t *tcb, thread_func_t task, uint8_t priority, const char *name); +void qor_create_thread(qor_tcb_t *tcb, thread_func_t task, uint32_t *stack, uint32_t stack_size, uint8_t priority, const char *name); -bool qor_start(qor_tcb_t *idle_tcb, thread_func_t idle_task); +bool qor_start(qor_tcb_t *idle_tcb, thread_func_t idle_task, uint32_t *idle_stack, uint32_t idle_stack_size); void qor_sleep(uint32_t sleep_duration_ms);