void InitOS( void );\r
void StartOS( AppModeType Mode );\r
\r
-\r
-\r
ApplicationType GetApplicationID( void );\r
ISRType GetISRID( void );\r
StatusType GetActiveApplicationMode( AppModeType* mode);\r
TickType Os_SysTickGetValue( void );\r
TickType Os_SysTickGetElapsedValue( TickType preValue );\r
\r
+#if defined(USE_KERNEL_EXTRA)\r
+StatusType Sleep( TickType ticks );\r
+#endif\r
+\r
+\r
/*-------------------------------------------------------------------\r
* Schedule Tables\r
*-----------------------------------------------------------------*/\r
if (Os_Arc_OsTickCounter >= 0) {\r
\r
OsCounterType *cPtr = Os_CfgGetCounter(Os_Arc_OsTickCounter);\r
+#if defined(USE_KERNEL_EXTRA)\r
+ OsPcbType *pcbPtr;\r
+#endif\r
\r
os_sys.tick++;\r
\r
cPtr->val = Os_CounterAdd( cPtr->val, Os_CounterGetMaxValue(cPtr), 1 );\r
\r
- // os_sys.tick = cPtr->val;\r
+#if defined(USE_KERNEL_EXTRA)\r
+ /* Check sleep() (ST_WAITING) tasks */\r
+ TAILQ_FOREACH(pcbPtr, &os_sys.timerHead, timerEntry ) {\r
+ --pcbPtr->timerDec;\r
+ if( pcbPtr->timerDec <= 0 ) {\r
+ /* Remove from the timer queue */\r
+ TAILQ_REMOVE(&os_sys.timerHead, pcbPtr, timerEntry);\r
+ /* ... and add to the ready queue */\r
+ Os_TaskMakeReady(pcbPtr);\r
+ }\r
+ }\r
+#endif\r
\r
Os_AlarmCheck(cPtr);\r
Os_SchTblCheck(cPtr);\r
goto err;\r
}\r
\r
- if ( Os_TaskOccupiesResources(curr_pcb) ) {\r
+ if ( Os_TaskOccupiesResources(curr_pcb) ||\r
+ !Os_SchedulerResourceIsFree() ) {\r
rv = E_OS_RESOURCE;\r
goto err;\r
}\r
\r
curr_pcb->ev_wait = Mask;\r
\r
- if ( Os_SchedulerResourceIsFree() ) {\r
- // Os_TaskMakeWaiting(curr_pcb);\r
- Os_Dispatch(OP_WAIT_EVENT);\r
- assert( curr_pcb->state & ST_RUNNING );\r
- } else {\r
- Os_TaskMakeWaiting(curr_pcb);\r
- }\r
+ Os_Dispatch(OP_WAIT_EVENT);\r
+ assert( curr_pcb->state & ST_RUNNING );\r
}\r
\r
Irq_Enable();\r
\r
dest_pcb->ev_set |= Mask;\r
\r
- if( (Mask & dest_pcb->ev_wait) ) {\r
- /* We have an event match */\r
- if( dest_pcb->state & ST_WAITING) {\r
- Os_TaskMakeReady(dest_pcb);\r
-\r
- currPcbPtr = Os_TaskGetCurrent();\r
- /* Checking "4.6.2 Non preemptive scheduling" it does not dispatch if NON */\r
- if( (os_sys.int_nest_cnt == 0) &&\r
- (currPcbPtr->scheduling == FULL) &&\r
- (dest_pcb->prio > currPcbPtr->prio) &&\r
- (Os_SchedulerResourceIsFree()) )\r
- {\r
- Os_Dispatch(OP_SET_EVENT);\r
- }\r
-\r
- } else if(dest_pcb->state & (ST_READY|ST_RUNNING) ) {\r
- /* Hmm, we do nothing */\r
- } else {\r
- assert( 0 );\r
+ if( (Mask & dest_pcb->ev_wait)\r
+#if defined(USE_KERNEL_EXTRA)\r
+ /* Don't dispatch if target task is sleeping */\r
+ && !(dest_pcb->state & ST_SLEEPING)\r
+#endif\r
+\r
+ ) {\r
+ assert(dest_pcb->state & ST_WAITING );\r
+\r
+ Os_TaskMakeReady(dest_pcb);\r
+\r
+ currPcbPtr = Os_TaskGetCurrent();\r
+ /* Checking "4.6.2 Non preemptive scheduling" it does not dispatch if NON */\r
+ if( (os_sys.int_nest_cnt == 0) &&\r
+ (currPcbPtr->scheduling == FULL) &&\r
+ (dest_pcb->prio > currPcbPtr->prio) &&\r
+ (Os_SchedulerResourceIsFree()) )\r
+ {\r
+ Os_Dispatch(OP_SET_EVENT);\r
}\r
}\r
\r
#define ST_SUSPENDED (1<<2)\r
#define ST_RUNNING (1<<3)\r
#define ST_NOT_STARTED (1<<4)\r
+#define ST_SLEEPING (1<<5)\r
\r
typedef uint16_t state_t;\r
\r
\r
/* TODO: Arch specific regs .. make space for them later...*/\r
uint32_t regs[16]; // TASK\r
+#if defined(USE_KERNEL_EXTRA)\r
+ TAILQ_ENTRY(OsPcb) timerEntry; // TASK\r
+ int32_t timerDec;\r
+#endif\r
/* List of PCB's */\r
TAILQ_ENTRY(OsPcb) pcb_list; // TASK\r
/* ready list */\r
OP_SCHEDULE = 16,\r
OP_CHAIN_TASK = 32,\r
OP_RELEASE_RESOURCE = 64,\r
+ OP_SLEEP = 128,\r
} OpType ;\r
\r
typedef struct sys_s {\r
// uint32_t flags;\r
\r
uint32_t task_cnt;\r
+\r
+#if defined(USE_KERNEL_EXTRA)\r
+ /* List of PCB's to be put in ready list when timeout */\r
+ TAILQ_HEAD(,OsPcb) timerHead; // TASK\r
+#endif\r
+\r
/* List of all pcb's,\r
* Only needed for non-static configuration of the kernel\r
*/\r
os_sys.pcb_list = pcb_list;
TAILQ_INIT(& os_sys.ready_head);
TAILQ_INIT(& os_sys.pcb_head);
+#if defined(USE_KERNEL_EXTRA)
+ TAILQ_INIT(& os_sys.timerHead);
+#endif
// Calc interrupt stack
Os_CfgGetInterruptStackInfo(&int_stack);
\r
#VPATH += $(ROOTDIR)/arch/arm/arm_cm3/kernel\r
vpath-y += $(ARCH_PATH-y)/kernel\r
-obj-y += asm_sample.o\r
+#obj-y += asm_sample.o\r
#CFLAGS_asm_sample.o += -O3\r
obj-y += arch_krn.o\r
obj-$(CFG_HCS12D) += arch_irq.o\r
obj-y += isr.o\r
obj-y += os_arctest.o\r
obj-y += application.o\r
+obj-y += arc.o\r
+obj-$(USE_KERNEL_EXTRA) += sleep.o\r
+#obj-$(USE_KERNEL_EXTRA) += semaphore.o\r
\r
\r
# These are VERY cpu dependent.. remove\r
--- /dev/null
+/*\r
+ * semaphore.c\r
+ *\r
+ * Created on: 13 okt 2010\r
+ * Author: mahi\r
+ *\r
+ * Mutex usage:\r
+ * - Serialized access to a global resource. The same task\r
+ * ALWAYS first use Os_WaitMutex() and the Os_ReleaseMutex()\r
+ * Should mutex be as GetResource()/ReleaseResource() be able to\r
+ * tinker with priotities..\r
+ *\r
+ *\r
+ * Task1:\r
+ * Os_WaitMutex(my_mutex)\r
+ * ..\r
+ * Os_ReleaseMutex(my_mutex)\r
+\r
+ * Task2\r
+ * Os_WaitMutex(my_mutex)\r
+ * ..\r
+ * Os_ReleaseMutex(my_mutex)\r
+ *\r
+ * Semaphore usage:\r
+ * - Producer and consumer problems.\r
+ * Os_WaitSemaphore() and Os_SignalSemaphore().\r
+ *\r
+ * ISR:\r
+ * Os_SignalSemaphore(my_semaphore)\r
+\r
+ * Task:\r
+ * Os_WaitSemaphore(my_semaphore)\r
+ *\r
+ */\r
+\r
+StatusType WaitSemaphore( OsSemaphore *semPtr ) {\r
+ uint32_t flags;\r
+\r
+ Irq_Save(flags);\r
+\r
+ --semPtr->val;\r
+\r
+ if(semPtr->val < 0 ) {\r
+ /* Wait for the semaphore to be signaled */\r
+ Os_Dispatch(OP_WAIT_SEMAPHORE);\r
+ }\r
+\r
+ Irq_Restore(flags);\r
+\r
+ return E_OK;\r
+}\r
+\r
+/**\r
+ * Increate the semaphore value by 1.\r
+ *
+ * @param semPtr
+ */\r
+void SignalSemaphore( OsSemaphore *semPtr ) {\r
+ uint32_t flags;\r
+\r
+ Irq_Save(flags);\r
+\r
+ assert( semPtr != NULL );\r
+\r
+ ++semPtr->val;\r
+\r
+ if(semPtr->val <= 0 ) {\r
+ Os_Dispatch(OP_SIGNAL_SEMAPHORE);\r
+ }\r
+\r
+ Irq_Restore(flags);\r
+\r
+ return E_OK;\r
+}\r
+\r
+\r
+/*\r
+ * Usage:
+ */\r
+StatusType CreateSemaphore( OsSemaphore *, int initialCount ) {\r
+\r
+\r
+}\r
+\r
+\r
+/* With priority inheretance */\r
+StatusType CreateMutex( OsMutex *mutexPtr ) {\r
+\r
+\r
+}\r
+\r
+StatusType WaitMutex( OsMutex *mutexPtr ) {\r
+\r
+\r
+}\r
+\r
+StatusType Os_ReleaseMutex( OsMutex *mutexPtr ) {\r
+\r
+\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+\r
+#include "Os.h"\r
+#include "internal.h"\r
+#include <assert.h>\r
+#include <string.h>\r
+\r
+/**\r
+ * Will sleep for sleep ticks. This works only for extended\r
+ * tasks. If sleep is 0 it will just call the dispatcher to\r
+ * see if there is anything with higher priority to run.\r
+ *\r
+ *\r
+ *
+ * @param sleep
+ * @return E_OS_ACCESS if called from a basic task\r
+ * E_OS_RESOURCE called while holding a resource\r
+ *
+ */\r
+\r
+StatusType Sleep( TickType sleep ) {\r
+ OsPcbType *pcbPtr = Os_TaskGetCurrent();\r
+ uint32_t flags;\r
+\r
+ Irq_Save(flags);\r
+\r
+\r
+ if (pcbPtr->proc_type != PROC_EXTENDED) {\r
+ return E_OS_ACCESS;\r
+ }\r
+\r
+ if ( Os_TaskOccupiesResources(pcbPtr) ) {\r
+ return E_OS_RESOURCE;\r
+ }\r
+\r
+ if ( Os_SchedulerResourceIsFree() ) {\r
+ if( sleep != 0 ) {\r
+ TAILQ_INSERT_TAIL(&os_sys.timerHead,pcbPtr,timerEntry);\r
+ pcbPtr->timerDec = sleep;\r
+ Os_Dispatch(OP_SLEEP);\r
+ } else {\r
+ Os_Dispatch(OP_SCHEDULE);\r
+ }\r
+\r
+ }\r
+\r
+ Irq_Restore(flags);\r
+ return E_OK;\r
+}\r
/* Go the correct state for running task */\r
if( op & ( OP_SET_EVENT | OP_SCHEDULE | OP_RELEASE_RESOURCE )) {\r
Os_TaskRunningToReady(currPcbPtr);\r
- } else if( op & OP_WAIT_EVENT ) {\r
+ } else if( op & (OP_WAIT_EVENT )) {\r
Os_TaskMakeWaiting(currPcbPtr);\r
+ } else if( op & (OP_SLEEP )) {\r
+ Os_TaskMakeSleeping(currPcbPtr);\r
} else if( op & OP_ACTIVATE_TASK ) {\r
Os_TaskMakeReady(currPcbPtr);\r
} else if( op & OP_CHAIN_TASK ) {\r