]> rtime.felk.cvut.cz Git - arc.git/commitdiff
Fixed activation count on autostart. Fixed ChainTask implementation
authortojo <tobias.johansson@arccore.com>
Tue, 22 Jun 2010 12:11:46 +0000 (14:11 +0200)
committertojo <tobias.johansson@arccore.com>
Tue, 22 Jun 2010 12:11:46 +0000 (14:11 +0200)
include/Os.h
system/kernel/init.c
system/kernel/task.c

index a0a756bdaceeedab2fe59874883cda3af47fb287..b59c81937f82e68db5ffb34fece41c8d280a704c 100644 (file)
@@ -246,7 +246,7 @@ StatusType GetResource( ResourceType ResID );
 StatusType ReleaseResource( ResourceType ResID);\r
 \r
 /*\r
- * Define the scheduler resource as 0\r
+ * Define the scheduler resource as ~0\r
  */\r
 #define        RES_SCHEDULER                   ~(ResourceType)0\r
 \r
index 0db2b4a2f15fa84f8f9a2d99fc1cfa3b94678f62..67c5e6f58bf7ea010f3850435a27306fa68a0e23 100644 (file)
@@ -197,6 +197,13 @@ static void os_start( void ) {
        {\r
                // FIXME: Do this in a more structured way.. setting os_sys.curr_pcb manually is not the way to go..\r
                os_sys.curr_pcb = tmp_pcb;\r
+\r
+               // register this auto-start activation\r
+               if (tmp_pcb->proc_type == PROC_BASIC) {\r
+                       assert(tmp_pcb->activations < tmp_pcb->activationLimit);\r
+                       tmp_pcb->activations++;\r
+               }\r
+\r
                // NOTE! We don't go for os_swap_context() here..\r
                // first arg(NULL) is dummy only\r
                Os_TaskSwapContextTo(NULL,tmp_pcb);\r
index 1817afb86ae5b27554e2e92c9feb223c2eaaac50..e166c9ecf27cf8ee91e3c77e6f3fad08954165a6 100644 (file)
@@ -284,6 +284,7 @@ OsPcbType *Os_FindTopPrioTask( void ) {
  *   ActivateTask()\r
  *   WaitEvent()\r
  *   TerminateTask()\r
+ *   ChainTask()\r
  *\r
  * @param force Force a re-scheduling\r
  *\r
@@ -349,25 +350,11 @@ void Os_Dispatch( _Bool force ) {
 // We come here from\r
 // - os_init\r
 \r
-volatile static int a1, b1, c1;\r
-volatile static OsPcbType *o1;\r
-volatile static OsPcbType *n1;\r
-\r
-void hej(int a, int b, int c, OsPcbType *o, OsPcbType *n) {\r
-       a1 = a;\r
-       b1 = b;\r
-       c1 = c;\r
-       o1 = o;\r
-       n1 = n;\r
-}\r
-\r
 /**\r
  * Called when a task is to be run for the first time.\r
  */\r
 void Os_TaskSwapContextTo(OsPcbType *old_pcb, OsPcbType *new_pcb ) {\r
 \r
-       hej(1, 2, 3, old_pcb, new_pcb);\r
-\r
        Os_ArchSwapContextTo(old_pcb,new_pcb);\r
        /* TODO: When do we return here ?? */\r
 }\r
@@ -441,6 +428,18 @@ ISRType GetISRID( void ) {
                goto err;                                               \\r
        }\r
 \r
+static inline void Os_Arc_SetCleanContext( OsPcbType *pcb ) {\r
+       if (pcb->proc_type == PROC_EXTENDED) {\r
+               /** @req OSEK ActivateTask Cleanup events\r
+                * OSEK,ActivateTask, When an extended task is transferred from suspended\r
+                * state into ready state all its events are cleared.*/\r
+               pcb->ev_set = 0;\r
+               pcb->ev_wait = 0;\r
+       }\r
+       Os_StackSetup(pcb);\r
+       Os_ArchSetTaskEntry(pcb);\r
+       Os_ArchSetupContext(pcb);\r
+}\r
 \r
 /**\r
  * The task <TaskID> is transferred from the suspended state into\r
@@ -487,16 +486,7 @@ StatusType ActivateTask( TaskType TaskID ) {
 \r
        if( os_pcb_get_state(pcb) == ST_SUSPENDED ) {\r
                pcb->activations++;\r
-               if (pcb->proc_type == PROC_EXTENDED) {\r
-                       /** @req OSEK ActivateTask Cleanup events\r
-                        * OSEK,ActivateTask, When an extended task is transferred from suspended\r
-                        * state into ready state all its events are cleared.*/\r
-                       pcb->ev_set = 0;\r
-                       pcb->ev_wait = 0;\r
-               }\r
-               Os_StackSetup(pcb);\r
-               Os_ArchSetTaskEntry(pcb);\r
-               Os_ArchSetupContext(pcb);\r
+               Os_Arc_SetCleanContext(pcb);\r
                Os_TaskMakeReady(pcb);\r
        } else {\r
 \r
@@ -603,6 +593,10 @@ StatusType TerminateTask( void ) {
        } else {\r
                /* We need to add ourselves to the ready list again,\r
                 * with a startup context. */\r
+\r
+               /* We are already in ready list..\r
+                * This should give us a clean start /tojo */\r
+               Os_Arc_SetCleanContext(curr_pcb);\r
        }\r
 \r
 //     Os_ContextReInit(curr_pcb);\r
@@ -622,7 +616,8 @@ StatusType TerminateTask( void ) {
 }\r
 \r
 StatusType ChainTask( TaskType TaskId ) {\r
-       StatusType rv;\r
+       OsPcbType *curr_pcb = Os_TaskGetCurrent();\r
+       StatusType rv = E_OK;\r
        uint32_t flags;\r
 \r
 #if (OS_STATUS_EXTENDED == STD_ON )\r
@@ -632,12 +627,57 @@ StatusType ChainTask( TaskType TaskId ) {
                rv =  E_OS_CALLEVEL;\r
                goto err;\r
        }\r
+\r
+       if( Os_ResourceCheckAndRelease(curr_pcb) == 1 ) {\r
+               rv =  E_OS_RESOURCE;\r
+               goto err;\r
+       }\r
 #endif\r
+       OsPcbType *pcb = os_get_pcb(TaskId);\r
 \r
        Irq_Save(flags);\r
-       rv = ActivateTask(TaskId);\r
-       /* TODO: more more here..*/\r
-       TerminateTask();\r
+\r
+       if (curr_pcb == pcb) {\r
+               /* If we are chaining same task just make a clean start */\r
+               /* TODO: Is it allowed to chain same task if extended? */\r
+               Os_Arc_SetCleanContext(curr_pcb);\r
+\r
+               /* Force the dispatcher to find something, even if its us */\r
+               Os_Dispatch(1);\r
+\r
+               Irq_Restore(flags);\r
+               /* It must find something here...otherwise something is very wrong.. */\r
+               assert(0);\r
+\r
+       } else {\r
+               /* We are chaining another task\r
+                * We need to make sure it is in valid state */\r
+               if( os_pcb_get_state(pcb) != ST_SUSPENDED ) {\r
+                       if( pcb->proc_type == PROC_EXTENDED ) {\r
+                               /** @req OSEK Activate task.\r
+                                * An extended task be activated once. See Chapter 4.3 in OSEK */\r
+                               rv = E_OS_LIMIT;\r
+                               goto err;\r
+                       }\r
+\r
+                       /** @req OSEK_? Too many task activations */\r
+                       if( pcb->activations == pcb->activationLimit ) {\r
+                               rv=E_OS_LIMIT;\r
+                               goto err;\r
+                       }\r
+               }\r
+\r
+               // Terminate current task\r
+               --curr_pcb->activations;\r
+               if( curr_pcb->activations <= 0 ) {\r
+                       curr_pcb->activations = 0;\r
+                       Os_TaskMakeSuspended(curr_pcb);\r
+               }\r
+\r
+               rv = ActivateTask(TaskId);\r
+               // we return here only if something is wrong\r
+       }\r
+\r
        Irq_Restore(flags);\r
 \r
        if (rv != E_OK) goto err;\r