[devel-ports] rtai & linux, как все должно работать?
gosha
=?iso-8859-1?q?gosha_=CE=C1_elins=2Eru?=
Пн Сен 1 17:23:53 MSD 2008
Добрый день.
Возникла необходимость написать поддержку зеленоградской процессорки (MIPS процессор) для rtai.
Но, после анализа исходных текстов rtai, нет понимания, как все должно работать и как должны дружить шедулеры rtai & linux:
- rt_task_init() - Creates a new real time task. The newly created real time task is initially in a suspend state. It can be made active by calling: rt_task_make_periodic, rt_task_make_periodic_relative_ns, rt_task_resume.
- для однопроцессорной системы (по исходным тектам rtai) rt_schedule() выполняется по прерыванию от системного таймера.
код (во всю высоту: 75 строк)
Возникла необходимость написать поддержку зеленоградской процессорки (MIPS процессор) для rtai.
Но, после анализа исходных текстов rtai, нет понимания, как все должно работать и как должны дружить шедулеры rtai & linux:
- rt_task_init() - Creates a new real time task. The newly created real time task is initially in a suspend state. It can be made active by calling: rt_task_make_periodic, rt_task_make_periodic_relative_ns, rt_task_resume.
- для однопроцессорной системы (по исходным тектам rtai) rt_schedule() выполняется по прерыванию от системного таймера.
код (во всю высоту: 75 строк)
static void rt_timer_handler(void)
{
RT_TASK *task, *new_task;
RTIME now;
int prio, delay, preempt;
TRACE_RTAI_TIMER(TRACE_RTAI_EV_TIMER_HANDLE_EXPIRY, 0, 0);
sched_rqsted = 1;
DO_TIMER_PROPER_OP();
prio = RT_SCHED_LINUX_PRIORITY;
task = new_task = &rt_linux_task;
rt_times.tick_time = oneshot_timer ? rdtsc() : rt_times.intr_time;
rt_time_h = rt_times.tick_time + (RTIME)rt_half_tick;
if (rt_times.tick_time >= rt_times.linux_time) {
rt_times.linux_time += (RTIME)rt_times.linux_tick;
rt_pend_linux_irq(TIMER_8254_IRQ);
}
wake_up_timed_tasks(0);
RR_YIELD();
TASK_TO_SCHEDULE();
RR_SETYT();
if (oneshot_timer) {
rt_times.intr_time = rt_times.linux_time > rt_times.tick_time ?
rt_times.linux_time : rt_times.tick_time + (RTIME)rt_times.linux_tick;
RR_TPREMP();
task = &rt_linux_task;
while ((task = task->tnext) != &rt_linux_task) {
if (task->priority <= prio && task->resume_time < rt_times.intr_time) {
rt_times.intr_time = task->resume_time;
preempt = 1;
break;
}
}
if ((shot_fired = preempt)) {
delay = (int)(rt_times.intr_time - (now = rdtsc())) - tuned.latency;
if (delay >= tuned.setup_time_TIMER_CPUNIT) {
delay = imuldiv(delay, TIMER_FREQ, tuned.cpu_freq);
} else {
delay = tuned.setup_time_TIMER_UNIT;
rt_times.intr_time = now + (RTIME)tuned.setup_time_TIMER_CPUNIT;
}
rt_set_timer_delay(delay);
}
} else {
rt_times.intr_time += (RTIME)rt_times.periodic_tick;
rt_set_timer_delay(0);
}
if (new_task != rt_current) {
if (rt_current == &rt_linux_task) {
rt_switch_to_real_time(0);
save_cr0_and_clts(linux_cr0);
}
if (new_task->uses_fpu) {
enable_fpu();
if (new_task != fpu_task) {
save_fpenv(fpu_task->fpu_reg);
fpu_task = new_task;
restore_fpenv(fpu_task->fpu_reg);
}
}
TRACE_RTAI_SCHED_CHANGE(rt_current->tid, new_task->tid, rt_current->state);
KEXECTIME();
rt_switch_to(new_task);
if (rt_current->signal) {
(*rt_current->signal)();
}
}
}
- соотв понятно, что из этого обработчика выполняются все прерывания linux после отработки прерываний rtai (включая прерывания linux по таймеру).
====================================================================
Но непонятно с расписанием выполнения прикладных задач linux & rtai:
- как и где в исх тексте шедулера rtai отдается управления задачам linux (которым отдал бы управление шедулер linux, если бы не было rtai).
- как я понял, должны выполняться приложения rtai постоянно, а, если им не требуется cpu, cpu временно отдается приложениям linux?
- не понятно, где/как это упраление передается приложениям linux и возвращается обратно к приложениям rtai?
Спасибо
--
С Уваженим,
gosha.
Подробная информация о списке рассылки devel-ports