Main Page | Data Structures | File List | Data Fields | Globals

opale_core.c

Go to the documentation of this file.
00001 // C Source File 00002 // Created 05/02/05; 00:41:54 00003 00004 #include "opale_internal.h" 00005 00037 unsigned char* indexToLowestSettedBit; 00038 00039 unsigned short numberOfNestedISRs; 00040 unsigned short numberOfNestedShedulerHalts; 00041 unsigned short kernelStarted; 00042 00044 t_TASK idleTask; 00046 char* idleTaskStack; 00047 00049 t_TASK** runningTasks; 00051 t_TASK_BLOCK* roundRobin; 00053 t_TASK_BLOCK* readyTasks; 00054 00063 void op_KernelInit( register t_op_BUFFER* buffer asm("%a0"), register unsigned char rotationMask asm("%d0") ) 00064 { 00065 00066 short i,j; 00067 00068 indexToLowestSettedBit = buffer->indexToLowestSettedBit; 00069 readyTasks = &buffer->readyTasks; 00070 roundRobin = &buffer->roundRobin; 00071 idleTaskStack = buffer->idleTaskStack; 00072 runningTasks = buffer->runningTasks; 00073 00074 for(i=1; i< TO_LOWEST_SETTED_BIT_TABLE_SIZE; indexToLowestSettedBit[i++]=j) for(j=0; !((i>>j)&1); j++); 00075 00076 /* inits the number of running ISR to 0 */ 00077 numberOfNestedISRs = 0; 00078 00079 /* inits the number of requests to stop the scheduler to 1 (halted) */ 00080 numberOfNestedShedulerHalts = 1; 00081 kernelStarted = 0; 00082 00083 /* no tasks are ready yet, so we clear the ready row index */ 00084 readyTasks->rowIndex = 0; 00085 roundRobin->rowIndex = rotationMask; 00086 00087 /* inits each element of the readyTable to 0 (no active task) */ 00088 00089 for( i = 0; i<_Y_; ) 00090 { 00091 readyTasks->tasksTable[ i ] = 0; 00092 roundRobin->tasksTable[ i++ ] = 0; 00093 } 00094 00095 for( i = 0; i<NUM_TASKS ; ) 00096 { 00097 runningTasks[ i++ ] = NULL; 00098 } 00099 00100 InitIntVectors(); 00101 00102 op_TaskStart( &idleTask, IdleTaskFunction, &idleTaskStack[ IDLE_TASK_STACK_SIZE ], IDLE_TASK_IDENT, NULL ); 00103 00104 } 00105 00109 void PerformDelay( void ) 00110 { 00111 00112 t_TASK* task = &idleTask; 00113 00114 while( ( task = task->nextSleeping ) != NULL ) 00115 { 00116 if( --(task->tickDelay) <= 0 ) 00117 { 00118 00119 addTaskToTable( readyTasks, task->ident ); 00120 00121 if( ( (task->prevSleeping)->nextSleeping = task->nextSleeping ) ) 00122 (task->nextSleeping)->prevSleeping = task->prevSleeping; 00123 00124 } 00125 } 00126 } 00127 00128 00129 static unsigned char rotate( unsigned char t, register unsigned char n asm("%d2") ) 00130 { 00131 return (((t>>n)|(t<<(_X_-n)))); 00132 } 00133 00136 void Scheduler( void ) 00137 { 00138 00205 /* x and y shall not be allocated on the stack ! */ 00206 register unsigned char y asm("%d1") = indexToLowestSettedBit[ readyTasks->rowIndex ]; 00207 register unsigned char x asm("%d0") ; 00208 00209 if( roundRobin->rowIndex & indexToSettedBit( y ) ) 00210 { 00211 00212 register unsigned char decalage asm("%d2") = roundRobin->tasksTable[ y ] + 1; 00213 00214 x = ( indexToLowestSettedBit[ rotate( readyTasks->tasksTable[ y ], decalage ) ] + decalage ) & MASK_X; 00215 roundRobin->tasksTable[ y ] = x; 00216 } 00217 else 00218 { 00219 x = indexToLowestSettedBit[ readyTasks->tasksTable[ y ] ]; 00220 } 00221 00222 x += ( y << MASK_Y ); 00223 00224 /* perform context switch if this is not the current task */ 00225 if( currentTask->ident != x ) 00226 { 00227 00228 register t_TASK* highestPriorityTaskReady asm("%a3") = runningTasks[ x ]; 00229 /* context switch */ 00230 ContextSwitch( highestPriorityTaskReady, &currentTask ); 00231 } 00232 00233 /* work done ... */ 00234 00235 } 00236 00237 // 00238 //void op_EnterISR( void ) 00239 //{ 00240 // /* increments the number of ISR in execution ... should be performed in an atomic assembly instruction 00241 // (I need to check the assembly output) */ 00242 // 00243 // numberOfNestedISRs ++; 00244 // 00245 //} 00246 00247 00248 //void op_ExitISR( void ) 00249 //{ 00250 /* decrements the number of ISR in execution ... should also be performed in an atomic assembly instruction 00251 (I need to check the assembly output, too) 00252 If the number is back to , the we are back to a non-ISR function, we then call the scheduler 00253 (if it is enabled) to check if one of the ISR that just finished hasn't woken 00254 a high priority thread */ 00255 00256 // if( !( -- numberOfNestedISRs ) && ( numberOfNestedShedulerHalts ) ) 00257 // { 00258 // op_Scheduler(); 00259 // } 00260 //} 00261

Generated on Sun May 14 22:31:06 2006 for Opale by doxygen 1.3.8