> What code is sending the packets and how are they received (I mean user
> space application, or some kernel code?)
Most of the network traffic is incoming (99.99...%). There is a server
application (in user space) that receives the data and stores it in
the shared memory, accessible to RT tasks for processing.
> I guess you should somehow allow network interrupt to be serviced while
> your RT task is running. How much time is your RT task taking?
That was my idea. I modified the rate-monotonic scheduler (the
original is available on the RTL web page), so that rt_linux_task (the
Linux kernel) is assigned a period, just like the RT tasks. For a
start, I set this period to 20ms, while the RT tasks had periods of
50ms and 500ms (two sets of them, currently). Each time the
rt_linux_task preempts another task, I set the timer to call
rt_schedule() after, say, 2ms (it is possible that some delayed RT
task has sooner resume_time, so that the 2ms is the upper bound of
time that rt_linux_task has available). When the following call to
rt_schedule() is made, rt_linux_task is made delayed (from ready), so
that the RT tasks can continue to run. This idea seems to work for
some values of the period and "demand"... I am attaching chunks of the
modified code (look for "AMB") in rt_monotonic_sched.c; I admit I am
not 100% sure about the interrupt and flag "fix".
> Tomek
Thanks!
Aleks
void
rt_schedule(void)
{
RTIME now;
RTIME preemption_time;
RT_TASK *task;
RT_TASK *new_task;
RT_TASK *preemptor;
RTIME shortest_period;
int flags, flags2; /* AMB */
r_save_flags(flags);
save_flags(flags2); /* AMB */
r_cli();
cli(); /* AMB */
now = rt_get_time(); /* moved up by AMB */
#ifdef DEBUG
if (rt_current->identifier != -1) {
debug.state = EXEC;
debug.id = rt_current->identifier;
debug.in = init_time;
debug.out = now;
rtf_put(DEBUG_FIFO, (char *) &debug, sizeof(debug));
}
#endif
for (task = rt_tasks; task; task = task->next)
{
if (task->state == RT_TASK_DELAYED &&
task->resume_time < (now+10))
{
task->state = RT_TASK_READY;
}
}
new_task = 0; /* &rt_linux_task; AMB */
/* begin rate-monotonic scheduling */
shortest_period = RT_BIGGEST_PERIOD; /* rt_linux_task.period; AMB */
/* AMB begin */
if ((rt_current == &rt_linux_task) &&
(rt_linux_task.priority == RT_LOWEST_PRIORITY))
{
rt_linux_task.state = RT_TASK_DELAYED;
rt_linux_task.priority = RT_LOWEST_PRIORITY - 1;
rt_linux_task.resume_time += rt_linux_task.period;
}
/* AMB end */
for (task = rt_tasks; task; task = task->next)
{
if (task->state == RT_TASK_READY &&
task->period < shortest_period)
{
new_task = task;
shortest_period = task->period;
}
}
preemptor = 0;
preemption_time = RT_TIME_END;
/* AMB begin */
if (new_task == &rt_linux_task)
{
rt_linux_task.priority = RT_LOWEST_PRIORITY;
preemptor = &rt_linux_task;
preemption_time = now + RT_TICKS_PER_SEC / 100;
}
/* AMB end */
for (task = rt_tasks; task; task = task->next)
{
if (task->state == RT_TASK_DELAYED &&
task->resume_time < preemption_time)
{
preemption_time = task->resume_time;
preemptor = task;
}
}
/* AMB begin */
if (new_task == 0)
{
rt_linux_task.state = RT_TASK_READY;
rt_linux_task.priority = RT_LOWEST_PRIORITY - 2;
new_task = &rt_linux_task;
}
/* AMB end */
/* End of rate-monotonic scheduler */
if (preemptor)
{
rt_set_timer(preemption_time);
}
else
{
rt_no_timer();
}
if (new_task == rt_current)
{
if (rt_current != &rt_linux_task)
rt_current->resume_time += rt_current->period; /* AMB */
r_restore_flags(flags);
restore_flags(flags2); /* AMB */
return;
}
if (new_task == &rt_linux_task)
{
SFIF = linux_irq_state;
}
else
if (rt_current == &rt_linux_task)
{
linux_irq_state = SFIF;
SFIF = 0;
}
#ifdef DEBUG
if (new_task->identifier != -1) { /* Monotonic scheduler */
init_time = now;
}
#endif
new_task->state = RT_TASK_READY;
rt_switch_to(new_task);
r_restore_flags(flags);
restore_flags(flags2); /* AMB */
}
int
init_module(void)
{
#ifdef DEBUG
rtf_create(DEBUG_FIFO, 4000);
#endif
rt_tasks = &rt_linux_task;
rt_current = &rt_linux_task;
rt_linux_task.priority = RT_LOWEST_PRIORITY - 1; /* AMB */
rt_linux_task.period = RT_TICKS_PER_SEC / 50; /* RT_BIGGEST_PERIOD; AMB */
rt_linux_task.resume_time = rt_get_time(); /* AMB */
rt_linux_task.next = 0;
rt_linux_task.identifier = -1; /* Monotonic */
rt_linux_task.state = RT_TASK_READY;
rt_request_timer(&rt_schedule);
return 0;
}
--- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
----
For more information on Real-Time Linux see:
http://www.rtlinux.org/~rtlinux/