mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
stable QoRTOS (for now), before cleaning
This commit is contained in:
parent
ed8a63f96e
commit
af2ad82e92
7 changed files with 149 additions and 131 deletions
|
|
@ -1 +1 @@
|
||||||
[{"node":"TIMER","expanded":true,"format":0,"pinned":false}]
|
[{"node":"TIMER","expanded":true,"format":0,"pinned":false},{"node":"TIMER.INTR","expanded":true,"format":0},{"node":"TIMER.INTE","expanded":true,"format":0}]
|
||||||
|
|
@ -10,7 +10,7 @@ project(${PROJECT_NAME} LANGUAGES CXX C ASM)
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ static __attribute__((aligned(8))) pio_i2s i2s;
|
||||||
|
|
||||||
void ost_system_delay_ms(uint32_t delay)
|
void ost_system_delay_ms(uint32_t delay)
|
||||||
{
|
{
|
||||||
sleep_ms(delay);
|
busy_wait_ms(delay);
|
||||||
}
|
}
|
||||||
const uint8_t LED_PIN = 14; // GP 14
|
const uint8_t LED_PIN = 14; // GP 14
|
||||||
|
|
||||||
|
|
@ -87,8 +87,6 @@ void gpio_callback(uint gpio, uint32_t events)
|
||||||
one_time = false;
|
one_time = false;
|
||||||
// debouncer
|
// debouncer
|
||||||
debug_printf("G\n");
|
debug_printf("G\n");
|
||||||
|
|
||||||
qor_svc_call();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,17 @@ int main(void)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
// Raspberry Pico SDK
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "hardware/uart.h"
|
||||||
|
#include "hardware/spi.h"
|
||||||
|
#include "hardware/dma.h"
|
||||||
|
#include "hardware/irq.h"
|
||||||
|
#include "hardware/pio.h"
|
||||||
|
#include "hardware/clocks.h"
|
||||||
|
#include "pico.h"
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
#include "sdcard.h"
|
#include "sdcard.h"
|
||||||
|
|
||||||
const uint16_t tones[3][8] =
|
const uint16_t tones[3][8] =
|
||||||
|
|
@ -135,29 +146,23 @@ void UserTask_2(void *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raspberry Pico SDK
|
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#include "hardware/uart.h"
|
|
||||||
#include "hardware/spi.h"
|
|
||||||
#include "hardware/dma.h"
|
|
||||||
#include "hardware/irq.h"
|
|
||||||
#include "hardware/pio.h"
|
|
||||||
#include "hardware/clocks.h"
|
|
||||||
#include "pico.h"
|
|
||||||
|
|
||||||
void UserTask_3(void *args)
|
void UserTask_3(void *args)
|
||||||
{
|
{
|
||||||
gpio_init(1);
|
int cpt = 0;
|
||||||
gpio_set_dir(1, GPIO_OUT);
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
// gpio_put(1, 0);
|
|
||||||
ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 0);
|
ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 0);
|
||||||
qor_sleep(1000);
|
qor_sleep(500);
|
||||||
// gpio_put(1, 1);
|
|
||||||
ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 1);
|
ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 1);
|
||||||
qor_sleep(1000);
|
qor_sleep(500);
|
||||||
|
|
||||||
|
// if (++cpt >= 10)
|
||||||
|
// {
|
||||||
|
// cpt = 0;
|
||||||
|
// debug_printf("SU: %d, SO: %d\r\n", tcb3.stack_usage, tcb3.so);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,36 +175,12 @@ void IdleTaskFunction(void *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void UserTask_2(void)
|
|
||||||
{
|
|
||||||
InstrumentTriggerPE13_Init();
|
|
||||||
uint32_t count = 0;
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
InstrumentTriggerPE13_Toggle();
|
|
||||||
count++;
|
|
||||||
if (count % 35 == 0)
|
|
||||||
OS_Thread_Sleep(4500);
|
|
||||||
else
|
|
||||||
HAL_Delay(70);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UserTask_3(void)
|
|
||||||
{
|
|
||||||
InstrumentTriggerPE14_Init();
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
InstrumentTriggerPE14_Toggle();
|
|
||||||
HAL_Delay(60);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#include "pico/stdlib.h"
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
// timer_hw->inte = 0;
|
||||||
|
// timer_hw->alarm[3] = 0;
|
||||||
|
// timer_hw->dbgpause = 1;
|
||||||
|
|
||||||
ost_system_initialize();
|
ost_system_initialize();
|
||||||
|
|
||||||
// 1. Test the printf output
|
// 1. Test the printf output
|
||||||
|
|
@ -213,8 +194,8 @@ int main()
|
||||||
|
|
||||||
qor_init(THREADFREQ);
|
qor_init(THREADFREQ);
|
||||||
|
|
||||||
// qor_create_thread(&tcb1, UserTask_1, 2, "UserTask_0");
|
// qor_create_thread(&tcb1, UserTask_1, 2, "UserTask_1");
|
||||||
// qor_create_thread(&tcb2, UserTask_2, 1, "UserTask_1");
|
// qor_create_thread(&tcb2, UserTask_2, 1, "UserTask_2");
|
||||||
qor_create_thread(&tcb3, UserTask_3, 3, "UserTask_3");
|
qor_create_thread(&tcb3, UserTask_3, 3, "UserTask_3");
|
||||||
|
|
||||||
qor_start(&idle, IdleTaskFunction);
|
qor_start(&idle, IdleTaskFunction);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "qor.h"
|
#include "qor.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// Raspberry Pico SDK
|
// Raspberry Pico SDK
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
|
|
@ -29,66 +30,60 @@
|
||||||
#include "RP2040.h"
|
#include "RP2040.h"
|
||||||
|
|
||||||
void qor_switch_context();
|
void qor_switch_context();
|
||||||
static void timer_stop();
|
void qor_go();
|
||||||
|
// void qor_svc_call(void);
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG (*((volatile uint32_t *)0xe000ed04))
|
||||||
|
#define portNVIC_PENDSVSET_BIT (1UL << 28UL)
|
||||||
|
|
||||||
|
#define qor_svc_call() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
// ARM GENERIC
|
// ARM GENERIC
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
inline static void enable_irq()
|
|
||||||
{
|
|
||||||
__asm volatile("cpsie i");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void disable_irq()
|
static uint32_t gCritialNesting = 0;
|
||||||
{
|
|
||||||
__asm volatile("cpsid i");
|
|
||||||
}
|
|
||||||
|
|
||||||
void qor_sleep_ms(uint8_t svc, uint32_t ms)
|
#define enable_irq() __asm volatile("cpsie i")
|
||||||
{
|
#define disable_irq() __asm volatile("cpsid i")
|
||||||
|
|
||||||
__wfi;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
static inline uint32_t qor_enter_critical(void)
|
static inline uint32_t qor_enter_critical(void)
|
||||||
{
|
{
|
||||||
uint32_t primask = __get_PRIMASK();
|
uint32_t primask = __get_PRIMASK();
|
||||||
disable_irq();
|
disable_irq();
|
||||||
|
gCritialNesting++;
|
||||||
|
__asm volatile("dsb" ::
|
||||||
|
: "memory");
|
||||||
|
__asm volatile("isb");
|
||||||
return primask;
|
return primask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qor_exit_critical(uint32_t status)
|
void qor_exit_critical(uint32_t status)
|
||||||
{
|
{
|
||||||
|
gCritialNesting--;
|
||||||
|
|
||||||
|
if (gCritialNesting == 0)
|
||||||
|
{
|
||||||
|
enable_irq();
|
||||||
|
}
|
||||||
__set_PRIMASK(status);
|
__set_PRIMASK(status);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
__attribute__((naked)) void PendSV_Handler()
|
|
||||||
{
|
|
||||||
qor_switch_context();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const bool qor_inside_interrupt(void)
|
static const bool qor_inside_interrupt(void)
|
||||||
{
|
{
|
||||||
uint32_t ulCurrentInterrupt;
|
uint32_t ulCurrentInterrupt;
|
||||||
bool xReturn;
|
|
||||||
|
|
||||||
// Obtain the number of the currently executing interrupt
|
// Obtain the number of the currently executing interrupt
|
||||||
__asm volatile("mrs %0, ipsr"
|
__asm volatile("mrs %0, ipsr"
|
||||||
: "=r"(ulCurrentInterrupt)::"memory");
|
: "=r"(ulCurrentInterrupt)::"memory");
|
||||||
return ulCurrentInterrupt == 0 ? false : true;
|
return ulCurrentInterrupt == 0 ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qor_svc_call(void)
|
|
||||||
{
|
|
||||||
timer_stop();
|
|
||||||
volatile uint32_t *icsr = (void *)0xE000ED04;
|
|
||||||
// Pend a PendSV exception using by writing 1 to PENDSVSET at bit 28
|
|
||||||
*icsr = 0x1 << 28;
|
|
||||||
// flush pipeline to ensure exception takes effect before we
|
|
||||||
// return from this routine
|
|
||||||
__asm("isb");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
// RASPBERRY PICO
|
// RASPBERRY PICO
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
|
|
@ -101,40 +96,52 @@ static volatile uint32_t timer_period;
|
||||||
#include "hardware/structs/systick.h"
|
#include "hardware/structs/systick.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
// Beware, do not consume any local variable here, and keep the "naked" attribute
|
||||||
|
// Since it is an Exception (interrupt), we work on the MSB
|
||||||
|
// The syscall wil then call the scheduler so we will never free any local variables consumed
|
||||||
|
// It will result on a MSP infinite growing (0x42000 on the Pico) until user data overriding and at the end an hardfault will occur
|
||||||
|
// static void timer_irq(void)
|
||||||
|
// {
|
||||||
|
// // Clear the alarm irq
|
||||||
|
// hw_clear_bits(&timer_hw->intr, 1u << ALARM_NUM);
|
||||||
|
// qor_svc_call();
|
||||||
|
// }
|
||||||
|
|
||||||
static void timer_irq(void)
|
static uint64_t gNextAlarm = 0;
|
||||||
{
|
|
||||||
// Clear the alarm irq
|
|
||||||
hw_clear_bits(&timer_hw->intr, 1u << ALARM_NUM);
|
|
||||||
qor_svc_call();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_set_alam(uint32_t delay_ms)
|
static void timer_set_alarm(uint32_t delay_ms)
|
||||||
{
|
{
|
||||||
if (delay_ms > 0)
|
if (delay_ms > 0)
|
||||||
{
|
{
|
||||||
// Alarm is only 32 bits so if trying to delay more
|
// Alarm is only 32 bits so if trying to delay more
|
||||||
// than that need to be careful and keep track of the upper
|
// than that need to be careful and keep track of the upper
|
||||||
// bits
|
// bits
|
||||||
uint64_t target = timer_hw->timerawl + delay_ms * 1000;
|
gNextAlarm = timer_hw->timerawl + delay_ms * 1000;
|
||||||
timer_hw->alarm[ALARM_NUM] = (uint32_t)target;
|
timer_hw->alarm[ALARM_NUM] = (uint32_t)gNextAlarm;
|
||||||
// Enable the interrupt for our alarm (the timer outputs 4 alarm irqs)
|
// Enable the interrupt for our alarm (the timer outputs 4 alarm irqs)
|
||||||
hw_set_bits(&timer_hw->inte, 1u << ALARM_NUM);
|
hw_set_bits(&timer_hw->inte, 1u << ALARM_NUM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void timer_stop()
|
// __attribute__((naked))
|
||||||
|
static void timer_end()
|
||||||
{
|
{
|
||||||
|
timer_hw->armed = 0xF;
|
||||||
|
// Clear the alarm irq
|
||||||
|
hw_clear_bits(&timer_hw->intr, 1u << ALARM_NUM);
|
||||||
|
// Disable the intterupt for this alarm
|
||||||
hw_clear_bits(&timer_hw->inte, 1u << ALARM_NUM);
|
hw_clear_bits(&timer_hw->inte, 1u << ALARM_NUM);
|
||||||
|
|
||||||
|
qor_svc_call();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static void timer_init()
|
static void timer_init()
|
||||||
{
|
{
|
||||||
// Set irq handler for alarm irq
|
// Set irq handler for alarm irq
|
||||||
irq_set_exclusive_handler(ALARM_IRQ, timer_irq);
|
irq_set_exclusive_handler(ALARM_IRQ, timer_end);
|
||||||
// Enable the interrupt for our alarm (the timer outputs 4 alarm irqs)
|
// Disable the intterupt for this alarm
|
||||||
hw_set_bits(&timer_hw->inte, 1u << ALARM_NUM);
|
hw_clear_bits(&timer_hw->inte, 1u << ALARM_NUM);
|
||||||
// Enable the alarm irq
|
// Enable the alarm irq
|
||||||
irq_set_enabled(ALARM_IRQ, true);
|
irq_set_enabled(ALARM_IRQ, true);
|
||||||
}
|
}
|
||||||
|
|
@ -157,19 +164,34 @@ static uint32_t ActiveTCBsCount = 0;
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
// Quite Ok RTOS private and public functions
|
// Quite Ok RTOS private and public functions
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
void qor_init(uint32_t scheduler_frequency_hz)
|
// void qor_svc_call(void)
|
||||||
|
// {
|
||||||
|
// // hw_clear_bits(&timer_hw->inte, 1u << ALARM_NUM);
|
||||||
|
// // volatile uint32_t *icsr = (void *)0xE000ED04;
|
||||||
|
// // // Pend a PendSV exception using by writing 1 to PENDSVSET at bit 28
|
||||||
|
// // *icsr = 0x1 << 28;
|
||||||
|
// // // flush pipeline to ensure exception takes effect before we
|
||||||
|
// // // return from this routine
|
||||||
|
// //
|
||||||
|
// // __asm volatile("svc 0");
|
||||||
|
// }
|
||||||
|
|
||||||
|
void __attribute__((naked)) swc()
|
||||||
{
|
{
|
||||||
exception_set_exclusive_handler(PENDSV_EXCEPTION, PendSV_Handler);
|
qor_switch_context();
|
||||||
}
|
}
|
||||||
|
|
||||||
void qor_exit_loop()
|
void qor_init(uint32_t scheduler_frequency_hz)
|
||||||
|
{
|
||||||
|
exception_set_exclusive_handler(PENDSV_EXCEPTION, qor_switch_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qor_exit_loop()
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void qor_go();
|
|
||||||
|
|
||||||
uint32_t *qor_initialize_stack(uint32_t *top_of_stack, thread_func_t task, void *args)
|
uint32_t *qor_initialize_stack(uint32_t *top_of_stack, thread_func_t task, void *args)
|
||||||
{
|
{
|
||||||
// ARM Calling convention: the folowwing registers are automatically saved onto the stack by the processor (in this ordoer on the stack)
|
// ARM Calling convention: the folowwing registers are automatically saved onto the stack by the processor (in this ordoer on the stack)
|
||||||
|
|
@ -193,6 +215,12 @@ void qor_create_thread(qor_tcb_t *tcb, thread_func_t task, uint8_t priority, con
|
||||||
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);
|
||||||
|
|
||||||
|
tcb->stack_bottom = &Stacks[ActiveTCBsCount][0];
|
||||||
|
tcb->stack_usage = 0;
|
||||||
|
tcb->so = false;
|
||||||
|
|
||||||
tcb->state = qor_tcb_state_active;
|
tcb->state = qor_tcb_state_active;
|
||||||
tcb->wait_time = 0;
|
tcb->wait_time = 0;
|
||||||
tcb->state = qor_tcb_state_active;
|
tcb->state = qor_tcb_state_active;
|
||||||
|
|
@ -223,7 +251,7 @@ void qor_create_thread(qor_tcb_t *tcb, thread_func_t task, uint8_t priority, con
|
||||||
enable_irq();
|
enable_irq();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool 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)
|
||||||
{
|
{
|
||||||
assert_or_panic(ActiveTCBsCount > 0);
|
assert_or_panic(ActiveTCBsCount > 0);
|
||||||
|
|
||||||
|
|
@ -242,8 +270,7 @@ bool qor_start(qor_tcb_t *idle_tcb, thread_func_t idle_task)
|
||||||
timer_init();
|
timer_init();
|
||||||
|
|
||||||
/* Prevent the timer's ISR from firing before start is called */
|
/* Prevent the timer's ISR from firing before start is called */
|
||||||
disable_irq();
|
enable_irq();
|
||||||
|
|
||||||
qor_go();
|
qor_go();
|
||||||
|
|
||||||
/* This statement should not be reached */
|
/* This statement should not be reached */
|
||||||
|
|
@ -252,6 +279,7 @@ bool qor_start(qor_tcb_t *idle_tcb, thread_func_t idle_task)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void __not_in_flash_func(qor_scheduler)(void)
|
||||||
void qor_scheduler(void)
|
void qor_scheduler(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
@ -321,17 +349,27 @@ void qor_scheduler(void)
|
||||||
RunPt = IdleTcb;
|
RunPt = IdleTcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_set_alam(next_alarm);
|
// Statistics
|
||||||
|
if (RunPt->stack_bottom[0] != 0xAAAAAAAA)
|
||||||
|
{
|
||||||
|
RunPt->so = true;
|
||||||
|
}
|
||||||
|
RunPt->stack_usage = RunPt->sp - RunPt->stack_bottom;
|
||||||
|
|
||||||
|
timer_set_alarm(next_alarm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qor_sleep(uint32_t sleep_duration_ms)
|
void qor_sleep(uint32_t sleep_duration_ms)
|
||||||
{
|
{
|
||||||
uint32_t status = qor_enter_critical();
|
if (sleep_duration_ms > 0)
|
||||||
|
{
|
||||||
|
disable_irq();
|
||||||
RunPt->state = qor_tcb_state_sleep;
|
RunPt->state = qor_tcb_state_sleep;
|
||||||
RunPt->ts = time_us_64() / 1000;
|
RunPt->ts = time_us_64() / 1000;
|
||||||
RunPt->wait_time = sleep_duration_ms;
|
RunPt->wait_time = sleep_duration_ms;
|
||||||
qor_exit_critical(status);
|
enable_irq();
|
||||||
qor_svc_call(); // call scheduler, recompute next timeout
|
qor_svc_call(); // call scheduler, recompute next timeout
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
|
|
@ -349,7 +387,7 @@ void qor_mbox_init(qor_mbox_t *mbox, void **msgBuffer, uint32_t maxCount)
|
||||||
|
|
||||||
uint32_t qor_mbox_wait(qor_mbox_t *mbox, void **msg, uint32_t wait_ms)
|
uint32_t qor_mbox_wait(qor_mbox_t *mbox, void **msg, uint32_t wait_ms)
|
||||||
{
|
{
|
||||||
uint32_t status = qor_enter_critical();
|
disable_irq();
|
||||||
|
|
||||||
// No any data, block on that resource
|
// No any data, block on that resource
|
||||||
if (mbox->count == 0)
|
if (mbox->count == 0)
|
||||||
|
|
@ -362,30 +400,28 @@ uint32_t qor_mbox_wait(qor_mbox_t *mbox, void **msg, uint32_t wait_ms)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qor_exit_critical(status);
|
enable_irq();
|
||||||
return QOR_MBOX_ERROR;
|
return QOR_MBOX_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = qor_enter_critical();
|
|
||||||
|
|
||||||
--mbox->count;
|
--mbox->count;
|
||||||
*msg = mbox->msgBuffer[mbox->read++];
|
*msg = mbox->msgBuffer[mbox->read++];
|
||||||
if (mbox->read >= mbox->maxCount)
|
if (mbox->read >= mbox->maxCount)
|
||||||
{
|
{
|
||||||
mbox->read = 0;
|
mbox->read = 0;
|
||||||
}
|
}
|
||||||
qor_exit_critical(status);
|
enable_irq();
|
||||||
return QOR_MBOX_OK;
|
return QOR_MBOX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t qor_mbox_notify(qor_mbox_t *mbox, void *msg, uint32_t notifyOption)
|
uint32_t qor_mbox_notify(qor_mbox_t *mbox, void *msg, uint32_t notifyOption)
|
||||||
{
|
{
|
||||||
uint32_t status = qor_enter_critical();
|
disable_irq();
|
||||||
|
|
||||||
if (mbox->count >= mbox->maxCount)
|
if (mbox->count >= mbox->maxCount)
|
||||||
{
|
{
|
||||||
qor_exit_critical(status);
|
enable_irq();
|
||||||
return QOR_MBOX_FULL;
|
return QOR_MBOX_FULL;
|
||||||
}
|
}
|
||||||
if (notifyOption == QOR_MBOX_OPTION_SEND_FRONT)
|
if (notifyOption == QOR_MBOX_OPTION_SEND_FRONT)
|
||||||
|
|
@ -417,14 +453,14 @@ uint32_t qor_mbox_notify(qor_mbox_t *mbox, void *msg, uint32_t notifyOption)
|
||||||
t->wait_time = 0;
|
t->wait_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
qor_exit_critical(status);
|
enable_irq();
|
||||||
qor_svc_call(); // call scheduler
|
qor_svc_call(); // call scheduler
|
||||||
return QOR_MBOX_OK;
|
return QOR_MBOX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qor_mbox_get_stats(qor_mbox_t *mbox, mbox_stats_t *info)
|
void qor_mbox_get_stats(qor_mbox_t *mbox, mbox_stats_t *info)
|
||||||
{
|
{
|
||||||
uint32_t status = qor_enter_critical();
|
disable_irq();
|
||||||
|
|
||||||
info->count = mbox->count;
|
info->count = mbox->count;
|
||||||
info->maxCount = mbox->maxCount;
|
info->maxCount = mbox->maxCount;
|
||||||
|
|
@ -437,5 +473,5 @@ void qor_mbox_get_stats(qor_mbox_t *mbox, mbox_stats_t *info)
|
||||||
head = head->wait_next;
|
head = head->wait_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
qor_exit_critical(status);
|
enable_irq();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ extern void ost_hal_panic();
|
||||||
* exposes the functions for interacting with it.
|
* exposes the functions for interacting with it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAXNUMTHREADS 10 /* Maximum number of threads, allocated at compile time */
|
#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 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 THREADFREQ 1 /* Maximum time-slice, in Hz, before the scheduler is run */
|
||||||
|
|
||||||
|
|
@ -59,6 +59,11 @@ typedef struct TCB
|
||||||
uint64_t ts; //!< system timestamp
|
uint64_t ts; //!< system timestamp
|
||||||
const char *name; //!< Descriptive name to facilitate debugging
|
const char *name; //!< Descriptive name to facilitate debugging
|
||||||
|
|
||||||
|
// Debug/traces
|
||||||
|
uint32_t stack_usage;
|
||||||
|
uint32_t *stack_bottom;
|
||||||
|
bool so; // stack overflow detected
|
||||||
|
|
||||||
} qor_tcb_t;
|
} qor_tcb_t;
|
||||||
|
|
||||||
void qor_init(uint32_t scheduler_frequency_hz);
|
void qor_init(uint32_t scheduler_frequency_hz);
|
||||||
|
|
@ -69,8 +74,6 @@ bool qor_start(qor_tcb_t *idle_tcb, thread_func_t idle_task);
|
||||||
|
|
||||||
void qor_sleep(uint32_t sleep_duration_ms);
|
void qor_sleep(uint32_t sleep_duration_ms);
|
||||||
|
|
||||||
void qor_svc_call(void);
|
|
||||||
|
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
// MAILBOX API
|
// MAILBOX API
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ qor_switch_context:
|
||||||
|
|
||||||
@ Les registers r0-r3 r12 etc. sont sauvegardés par le processeur
|
@ Les registers r0-r3 r12 etc. sont sauvegardés par le processeur
|
||||||
|
|
||||||
|
cpsid i
|
||||||
mrs r0, psp @ get the current stack address ()
|
mrs r0, psp @ get the current stack address ()
|
||||||
|
|
||||||
ldr r1, =RunPt
|
ldr r1, =RunPt
|
||||||
|
|
@ -125,11 +126,9 @@ qor_switch_context:
|
||||||
mov r7, r11
|
mov r7, r11
|
||||||
stmia r0!, {r4-r7}
|
stmia r0!, {r4-r7}
|
||||||
|
|
||||||
cpsid i
|
|
||||||
bl qor_scheduler
|
bl qor_scheduler
|
||||||
cpsie i
|
|
||||||
|
|
||||||
ldr R0, =RunPt
|
ldr r0, =RunPt
|
||||||
ldr r1, [r0]
|
ldr r1, [r0]
|
||||||
ldr r0, [r1] @ R0 is the stack address
|
ldr r0, [r1] @ R0 is the stack address
|
||||||
|
|
||||||
|
|
@ -143,6 +142,7 @@ qor_switch_context:
|
||||||
|
|
||||||
|
|
||||||
msr psp, r0 @ new task stack top address
|
msr psp, r0 @ new task stack top address
|
||||||
|
str r0, [r1] @ Save the new top of stack
|
||||||
|
|
||||||
subs r0, r0, #32
|
subs r0, r0, #32
|
||||||
ldmia r0!, {r4-r7}
|
ldmia r0!, {r4-r7}
|
||||||
|
|
@ -150,6 +150,6 @@ qor_switch_context:
|
||||||
// Exit handler. Using a bx to the special EXC_RETURN values causes the
|
// Exit handler. Using a bx to the special EXC_RETURN values causes the
|
||||||
// processor to perform the exception return behavior.
|
// processor to perform the exception return behavior.
|
||||||
ldr r0, =EXC_RETURN
|
ldr r0, =EXC_RETURN
|
||||||
|
cpsie i
|
||||||
bx r0
|
bx r0
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue