printf( "Starting application " SW_VER_ID " v "
BUILD_VERSION_STRING(SW_VER_MAJOR,SW_VER_MINOR,SW_VER_PATCH)
"\n" );
-
+
+// Task 1 ==============================================
Task_1_name = rtems_build_name( 'T', 'S', 'K', '1' );
- Task_2_name = rtems_build_name( 'T', 'S', 'K', '2' );
-
+
status = rtems_task_create(
Task_1_name,
TASK_1_PRIORITY,
RTEMS_DEFAULT_ATTRIBUTES,
&Task_1_id
);
-
-
check_rtems_status(status, 0, "rtems_task_create of Task_1");
+ status = rtems_task_start( Task_1_id, Task_1, 0 );
+ check_rtems_status(status, 0, "rtems_task_start of Task_1\n");
+// Task 2 ==============================================
+ Task_2_name = rtems_build_name( 'T', 'S', 'K', '2' );
+
status = rtems_task_create(
Task_2_name,
TASK_2_PRIORITY,
check_rtems_status(status, 0, "rtems_task_create of Task_2");
- status = rtems_task_start( Task_1_id, Task_1, 0 );
- check_rtems_status(status, 0, "rtems_task_start of Task_1\n");
status = rtems_task_start( Task_2_id, Task_2, 0 );
check_rtems_status(status, 0, "rtems_task_start of Task_2\n");
-
+// ====================================================
+
rtems_shell_init("SHLL",RTEMS_MINIMUM_STACK_SIZE+0x1000,
SHELL_TASK_PRIORITY,"/dev/console",1,0, NULL);
#include <rtems/score/isr.h>
#include <rtems/score/watchdog.h>
#include <rtems/score/wkspace.h>
+#include <rtems/score/percpu.h>
/* let the scheduler talk */
-#define SCHED_VERBOSE
+//#define SCHED_VERBOSE
void _Scheduler_edf_Initialize(void) {
#ifdef SCHED_VERBOSE
printf("Sched: Block");
#endif
- _Scheduler_edf_Extract(the_thread);
+ _Scheduler_edf_Extract(the_thread);
+
+ /* TODO: flash critical section? */
+
+ if ( _Thread_Is_heir( the_thread ) )
+ _Scheduler_edf_Schedule();
+
+ if ( _Thread_Is_executing( the_thread ) )
+ _Thread_Dispatch_necessary = true;
}
void _Scheduler_edf_Schedule(void) {
printf("Sched: Schedule");
#endif
// set the heir
- _Thread_Heir = (Thread_Control *) _Thread_Ready_EDF_chain.first;
+ _Thread_Heir = (Thread_Control *) _Thread_Ready_EDF_chain.first;
}
void * _Scheduler_edf_Allocate( Thread_Control *the_thread) {
RBT_Node *schinfo;
sched = _Workspace_Allocate (sizeof(RBT_Node));
the_thread->scheduler_info = (RBT_Node *) sched;
- the_thread->real_priority = ABS_DEADLINE_MAXIMUM - _Watchdog_Ticks_since_boot-2;
- the_thread->is_preemptible = TRUE;
- the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
- the_thread->budget_callout = NULL;
+ //the_thread->real_priority = ABS_DEADLINE_MAXIMUM - _Watchdog_Ticks_since_boot-2;
+ //the_thread->is_preemptible = TRUE;
+ //the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
+ //the_thread->budget_callout = NULL;
schinfo = (RBT_Node *)(the_thread->scheduler_info);
schinfo->rel_deadline = the_thread->real_priority;
schinfo->right = NULL;
schinfo->parent = NULL;
schinfo->ready_chain = &_Thread_Ready_EDF_chain;
-
+
return sched;
}
#endif
// after a priority changes, just extract and insert again
//in case it is in the tree
- EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
- _RBT_Extract(chain, the_thread);
- _RBT_Insert(chain, the_thread); // preserve the abs_deadline
+// EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
+// _RBT_Extract(chain, the_thread);
+// _RBT_Insert(chain, the_thread); // preserve the abs_deadline
}
void _Scheduler_edf_Unblock( Thread_Control *the_thread ) {
#ifdef SCHED_VERBOSE
printf("Sched: Unblock");
#endif
- _Scheduler_edf_Enqueue(the_thread);
+ _Scheduler_edf_Enqueue(the_thread);
+ /* TODO: flash critical section? */
+
+ /*
+ * If the thread that was unblocked is more important than the heir,
+ * then we have a new heir. This may or may not result in a
+ * context switch.
+ *
+ * Normal case:
+ * If the current thread is preemptible, then we need to do
+ * a context switch.
+ * Pseudo-ISR case:
+ * Even if the thread isn't preemptible, if the new heir is
+ * a pseudo-ISR system task, we need to do a context switch.
+ */
+ if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
+ _Thread_Heir = the_thread;
+ if ( _Thread_Executing->is_preemptible || the_thread->current_priority == 0 )
+ _Thread_Dispatch_necessary = true;
+ }
}
void _Scheduler_edf_Yield( void ) {
_Thread_Dispatch_necessary = TRUE;
_ISR_Enable( level );
- // --------------------------------
}
#endif
RBT_Node *node = (RBT_Node*)the_thread->scheduler_info;
EDF_Chain_Control *chain = node->ready_chain;
- node->abs_deadline = _Watchdog_Ticks_since_boot + node->rel_deadline;
+ if (node->rel_deadline == 255) //hack for idle task
+ node->abs_deadline = ABS_DEADLINE_MAXIMUM;
+ else
+ node->abs_deadline = _Watchdog_Ticks_since_boot + node->rel_deadline;
_RBT_Insert(chain,the_thread);
+
}
void _Scheduler_edf_Enqueue_first( Thread_Control *the_thread) {
printf("Sched: Enqueue_first");
#endif
// FIXME: force first position
- EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
- _RBT_Insert(chain,the_thread);
+ _Scheduler_edf_Enqueue(the_thread);
}
void _Scheduler_edf_Extract( Thread_Control *the_thread) {
#ifdef SCHED_VERBOSE
printf("Sched: Extract");
#endif
- EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
- _RBT_Extract(chain,the_thread);
+ EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
+ _RBT_Extract(chain,the_thread);
}