/* ================================================================= * This simple program tests the scheduler to see if the execution * times for the task are uniform. * * Test the RTAI scheduler. Before running this module, you * must install rtai and rtai_sched. * * ================================================================= */ #include #include #include #include #include #define TICK_PERIOD 5000000000 // 5 seconds in nanoseconds #define STACK_SIZE 1000 #define TASK_PRIORITY 1 static RT_TASK rt_task; static void printTime (int val) { RTIME t; long time; long last_time; long interval; // Initialize the last time. last_time = 0l; while (1) { /* * Get the time and print the interval time. * rt_get_time_ns gets the time since the timer started in nanoseconds * * printk is the module form of printf. Output goes through the kernel * output process and can be read with the command dmesg. */ t = (long) rt_get_time_ns (); // time = (int) t * 0.000001; // (t / 1000000 + 0.5); interval = t - last_time; printk ("Interval = %ld, error = %ld\n", interval, interval - TICK_PERIOD); last_time = t; /* * That was fun, lets do it again. * rt_task_wait_period suspends this task until the next period is * reached. */ rt_task_wait_period (); } } int init_module (void) { RTIME tick_period; /* * Set the mode to periodic and create a task * rt_task_init creates a task * task structure to save task data * the thread to execute when the task runs; this task must * have the calling sequence void f (int). * the data to pass to the newly created task - a single int * the stack size - STACK_SIZE is the default size constant * the task priority, 0 is highest, RT_LOWEST_PRIORITY is lowest * a flag indicating if the floating point unit will be used * the * a function to be called when the task become the current running * task after a context switch. * * rt_set_periodic_mode sets the periodic mode for the system timer; * the alternative is rt_set_oneshot_mode for a single interrupt * and then the task must be rescheduled. */ rt_set_periodic_mode (); rt_task_init (&rt_task, printTime, 1, STACK_SIZE, TASK_PRIORITY, 0, 0); /* * Set up a tick period and start the periodic scheduling. * * start_rt_timer starts the timer with the given period. nano2count * converts the time in nanoseconds to the internal clock representation. * * rt_task_make_periodic makes the task periodic with the parameters: * the task to schedule periodically * the time at which to start periodic scheduling; rt_get_time * gets that to the current time. * the period */ tick_period = start_rt_timer (nano2count (TICK_PERIOD)); rt_task_make_periodic (&rt_task, rt_get_time () + tick_period, tick_period); return 0; } void cleanup_module (void) { /* * Stop the timer and dispose of the task. */ stop_rt_timer (); rt_task_delete (&rt_task); return; }