|
@@ -0,0 +1,196 @@
|
|
|
+#include "all-headers.h"
|
|
|
+
|
|
|
+
|
|
|
+#define ENABLE_XTR_ASSERTIONS
|
|
|
+
|
|
|
+
|
|
|
+#ifdef ENABLE_XTR_ASSERTIONS
|
|
|
+ #define XTR_ASSERT_NON_NULL_POINTER(ptr) assertNonNullPointer (ptr, __FILE__, __LINE__) ;
|
|
|
+#else
|
|
|
+ #define XTR_ASSERT_NON_NULL_POINTER(ptr)
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
+#ifdef ENABLE_XTR_ASSERTIONS
|
|
|
+ #define XTR_ASSERT(condition,value) assertion (condition, value, __FILE__, __LINE__) ;
|
|
|
+#else
|
|
|
+ #define XTR_ASSERT(condition,value)
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ uint32_t mR0 ;
|
|
|
+ uint32_t mR1 ;
|
|
|
+ uint32_t mR2 ;
|
|
|
+ uint32_t mR3 ;
|
|
|
+ uint32_t mR12 ;
|
|
|
+ uint32_t mLR ;
|
|
|
+ uint32_t mPC ;
|
|
|
+ uint32_t mXPSR ;
|
|
|
+} ExceptionFrame_without_floatingPointStorage ;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ uint32_t mR4 ;
|
|
|
+ uint32_t mR5 ;
|
|
|
+ uint32_t mR6 ;
|
|
|
+ uint32_t mR7 ;
|
|
|
+ uint32_t mR8 ;
|
|
|
+ uint32_t mR9 ;
|
|
|
+ uint32_t mR10 ;
|
|
|
+ uint32_t mR11 ;
|
|
|
+ ExceptionFrame_without_floatingPointStorage * mPSP ;
|
|
|
+ uint32_t mLR_RETURN_CODE ;
|
|
|
+} TaskContext ;
|
|
|
+
|
|
|
+
|
|
|
+static void kernel_set_task_context (INIT_MODE_
|
|
|
+ TaskContext & ioTaskContext,
|
|
|
+ const uint32_t inStackBufferAddress,
|
|
|
+ const uint32_t inStackBufferSize,
|
|
|
+ RoutineTaskType inTaskRoutine) {
|
|
|
+
|
|
|
+
|
|
|
+ ioTaskContext.mLR_RETURN_CODE = 0xFFFFFFFD ;
|
|
|
+
|
|
|
+
|
|
|
+ uint32_t initialTopOfStack = inStackBufferAddress + inStackBufferSize ;
|
|
|
+ initialTopOfStack -= sizeof (ExceptionFrame_without_floatingPointStorage) ;
|
|
|
+
|
|
|
+
|
|
|
+ auto ptr = (ExceptionFrame_without_floatingPointStorage *) initialTopOfStack ;
|
|
|
+ ioTaskContext.mPSP = ptr ;
|
|
|
+
|
|
|
+
|
|
|
+ ptr->mPC = (uint32_t) inTaskRoutine ;
|
|
|
+
|
|
|
+
|
|
|
+ ptr->mXPSR = 1 << 24 ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+typedef struct TaskControlBlock {
|
|
|
+
|
|
|
+
|
|
|
+ TaskContext mTaskContext ;
|
|
|
+
|
|
|
+
|
|
|
+ uint8_t mTaskIndex ;
|
|
|
+} TaskControlBlock ;
|
|
|
+
|
|
|
+
|
|
|
+static TaskControlBlock gTaskDescriptorArray [TASK_COUNT] ;
|
|
|
+
|
|
|
+
|
|
|
+TaskControlBlock * descriptorPointerForTaskIndex (const uint8_t inTaskIndex) {
|
|
|
+ XTR_ASSERT (inTaskIndex < TASK_COUNT, inTaskIndex) ;
|
|
|
+ return & gTaskDescriptorArray [inTaskIndex] ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+uint8_t indexForDescriptorTask (const TaskControlBlock * inTaskPtr) {
|
|
|
+ XTR_ASSERT_NON_NULL_POINTER (inTaskPtr) ;
|
|
|
+ return inTaskPtr->mTaskIndex ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+TaskControlBlock * gRunningTaskControlBlockPtr asm ("var.running.task.control.block.ptr") ;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+static TaskList gReadyTaskList ;
|
|
|
+
|
|
|
+
|
|
|
+static void kernel_makeTaskReady (IRQ_MODE_ TaskControlBlock * inTaskPtr) {
|
|
|
+ XTR_ASSERT_NON_NULL_POINTER (inTaskPtr) ;
|
|
|
+ gReadyTaskList.enterTask (MODE_ inTaskPtr) ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void kernelSelectTaskToRun (IRQ_MODE) asm ("kernel.select.task.to.run") ;
|
|
|
+
|
|
|
+void kernelSelectTaskToRun (IRQ_MODE) {
|
|
|
+ if (gRunningTaskControlBlockPtr != nullptr) {
|
|
|
+ gReadyTaskList.enterTask (MODE_ gRunningTaskControlBlockPtr) ;
|
|
|
+ }
|
|
|
+ gRunningTaskControlBlockPtr = gReadyTaskList.removeFirstTask (MODE) ;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+static uint8_t gTaskIndex ;
|
|
|
+
|
|
|
+
|
|
|
+void kernel_createTask (INIT_MODE_
|
|
|
+ uint64_t * inStackBufferAddress,
|
|
|
+ uint32_t inStackBufferSize,
|
|
|
+ RoutineTaskType inTaskRoutine) {
|
|
|
+ XTR_ASSERT (gTaskIndex < TASK_COUNT, gTaskIndex) ;
|
|
|
+ TaskControlBlock * taskControlBlockPtr = & gTaskDescriptorArray [gTaskIndex] ;
|
|
|
+ taskControlBlockPtr->mTaskIndex = gTaskIndex ;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ kernel_set_task_context (MODE_
|
|
|
+ taskControlBlockPtr->mTaskContext,
|
|
|
+ (uint32_t) inStackBufferAddress,
|
|
|
+ inStackBufferSize,
|
|
|
+ inTaskRoutine) ;
|
|
|
+
|
|
|
+
|
|
|
+ kernel_makeTaskReady (MODE_ taskControlBlockPtr) ;
|
|
|
+ gTaskIndex += 1 ;
|
|
|
+}
|
|
|
+
|
|
|
+
|