External stack for QoRTOS

This commit is contained in:
Anthony Rabine 2023-07-21 18:26:53 +02:00
parent af2ad82e92
commit 89fa2f9466
3 changed files with 37 additions and 60 deletions

View file

@ -86,8 +86,6 @@ ost_event_t ev_queue[10];
qor_tcb_t tcb1; qor_tcb_t tcb1;
qor_tcb_t tcb2; qor_tcb_t tcb2;
qor_tcb_t tcb3;
qor_tcb_t idle;
void UserTask_1(void *args) 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) while (1)
{ {
@ -157,16 +160,15 @@ void UserTask_3(void *args)
qor_sleep(500); qor_sleep(500);
ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 1); ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 1);
qor_sleep(500); 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) while (1)
{ {
@ -175,41 +177,28 @@ void IdleTaskFunction(void *args)
} }
} }
// ===========================================================================================================
// MAIN ENTRY POINT
// ===========================================================================================================
int main() int main()
{ {
// timer_hw->inte = 0; // 1. Call the platform initialization
// timer_hw->alarm[3] = 0;
// timer_hw->dbgpause = 1;
ost_system_initialize(); 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); debug_printf("\r\n [OST] Starting OpenStoryTeller tests: V%d.%d\r\n", 1, 0);
/*
filesystem_mount();
picture_show("example.bmp"); // 3. Filesystem / SDCard initialization
*/ filesystem_mount();
// ost_audio_play("out2.wav");
qor_init(THREADFREQ); // 4. Initialize OS and threads
qor_init(125000000UL);
// qor_create_thread(&tcb1, UserTask_1, 2, "UserTask_1"); // qor_create_thread(&tcb1, UserTask_1, 2, "UserTask_1");
// qor_create_thread(&tcb2, UserTask_2, 1, "UserTask_2"); // 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; return 0;
} }
#endif #endif

View file

@ -149,9 +149,6 @@ static void timer_init()
// =========================================================================================================== // ===========================================================================================================
// GLOBAL AND STATIC VARIABLES // GLOBAL AND STATIC VARIABLES
// =========================================================================================================== // ===========================================================================================================
static uint32_t Stacks[MAXNUMTHREADS][STACKSIZE];
/* Pointer to the currently running thread */ /* Pointer to the currently running thread */
qor_tcb_t *RunPt = NULL; qor_tcb_t *RunPt = NULL;
static qor_tcb_t *TcbHead = 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; 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(); 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->stack_usage = 0;
tcb->so = false; 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->next = NULL;
tcb->mbox = NULL; tcb->mbox = NULL;
tcb->wait_next = 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) 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(); 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); 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; 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 // FIXME: use the scheduler to find the best first thread to start
IdleTcb = idle_tcb; IdleTcb = idle_tcb;

View file

@ -11,18 +11,6 @@ extern void ost_hal_panic();
*/ */
#define assert_or_panic(expr) ((expr) ? (void)0U : 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); typedef void (*thread_func_t)(void *args);
// =========================================================================================================== // ===========================================================================================================
@ -52,6 +40,7 @@ typedef struct TCB
uint32_t *sp; //!< Stack pointer, valid for threads not running uint32_t *sp; //!< Stack pointer, valid for threads not running
struct TCB *next; //!< Pointer to circular-linked-list of TCBs struct TCB *next; //!< Pointer to circular-linked-list of TCBs
struct TCB *wait_next; //!< Next TCB in waiting list struct TCB *wait_next; //!< Next TCB in waiting list
uint32_t stack_size;
qor_tcb_state_t state; //!< TCB active or free qor_tcb_state_t state; //!< TCB active or free
uint32_t wait_time; //!< Timeout for mbox maiting or sleep 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 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_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); void qor_sleep(uint32_t sleep_duration_ms);