[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