예제 #1
0
// Executes a binary program
int exec(char* bin) {
	
	// Looking for free task
	int index = -1;
	for (int i = 0; i < tasks_nb; i++)
		if (!tasks[i].free) {
			index = i;
			tasks[i].free = 1;
			break;
		}
	if (index < 0) return 1;

	// Read program if existing
	if (file_exists(bin)) {
		
		// Copy binary program at the right address
		if (file_read(bin, (uint32_t*) tasks[index].addr)) return 3;
		
		// Commute to task with corresponding TSS as argument
		call_task(tasks[index].gdt_tss_sel); 
		
		// Structure array reset
		tasks[index].task_tss.eip = tasks[index].free         = 0;			 // instruction pointer and freedom
		tasks[index].task_tss.esp = tasks[index].task_tss.ebp = TASK_LIMIT;  // stack pointers
		
		// End of routine
		return 0;
		
	}
	else return 2;
	
}
예제 #2
0
파일: scheduler.c 프로젝트: JohsBL/MobRob
int32_t scheduler_update(scheduler_t* scheduler) 
{
	int32_t i;
	int32_t realtime_violation = 0;

	task_set_t* ts = scheduler->task_set;

	task_function_t call_task;
	task_argument_t function_argument;
	task_return_t treturn;

	// Iterate through registered tasks
	for (i = ts->current_schedule_slot; i < ts->task_count; i++) 
	{
		uint32_t current_time = time_keeper_get_micros();

		// If the task is active and has waited long enough...
		if ( (ts->tasks[i].run_mode != RUN_NEVER) && (current_time >= ts->tasks[i].next_run) ) 
		{
			uint32_t delay = current_time - (ts->tasks[i].next_run);
			uint32_t task_start_time;

		    task_start_time = time_keeper_get_micros();

		    // Get function pointer and function argument
		    call_task = ts->tasks[i].call_function;
			function_argument = ts->tasks[i].function_argument;

			// Execute task
		    treturn = call_task(function_argument);
	
			// Set the next execution time of the task
			switch (ts->tasks[i].timing_mode) 
			{
				case PERIODIC_ABSOLUTE:
					// Do not take delays into account
					ts->tasks[i].next_run += ts->tasks[i].repeat_period;
				break;

				case PERIODIC_RELATIVE:
					// Take delays into account
					ts->tasks[i].next_run = time_keeper_get_micros() + ts->tasks[i].repeat_period;
				break;
			}
			
			// Set the task to inactive if it has to run only once
			if (ts->tasks[i].run_mode == RUN_ONCE)
			{
				ts->tasks[i].run_mode = RUN_NEVER;
			}

			// Check real time violations
			if (ts->tasks[i].next_run < current_time) 
			{
				realtime_violation = -i; //realtime violation!!
				ts->tasks[i].rt_violations++;
				ts->tasks[i].next_run = current_time + ts->tasks[i].repeat_period;
			}
			
			// Compute real-time statistics
			ts->tasks[i].delay_avg = (7 * ts->tasks[i].delay_avg + delay) / 8;
			if (delay > ts->tasks[i].delay_max) 
			{
				ts->tasks[i].delay_max = delay;
			}
			ts->tasks[i].delay_var_squared = (15 * ts->tasks[i].delay_var_squared + (delay - ts->tasks[i].delay_avg) * (delay - ts->tasks[i].delay_avg)) / 16;
			ts->tasks[i].execution_time = (7 * ts->tasks[i].execution_time + (time_keeper_get_micros() - task_start_time)) / 8;
				
			// Depending on shceduling strategy, select next task slot	
			switch (scheduler->schedule_strategy) 
			{
				case FIXED_PRIORITY: 
					// Fixed priority scheme - scheduler will start over with tasks with the highest priority
					ts->current_schedule_slot = 0;
				break;		
	
				case ROUND_ROBIN:
					// Round robin scheme - scheduler will pick up where it left.
					if (i >= ts->task_count)
					{ 
						ts->current_schedule_slot = 0;
					}
				break;

				default:
				break;
			}

			return realtime_violation;			
		}
	}
	return realtime_violation;
}