User Tools

Site Tools


realtime:documentation:howto:applications:cyclic

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
realtime:documentation:howto:applications:cyclic [2017/05/19 15:12]
jogness timespec should be part of pinfo to simplify basic stub
realtime:documentation:howto:applications:cyclic [2017/06/20 14:15] (current)
anna-maria adapt link kernel documentation
Line 14: Line 14:
  
 Any mechanism for implementing a cyclic task can be divided into the following parts: Any mechanism for implementing a cyclic task can be divided into the following parts:
-  * periodic_task_init(): ​initialization ​code for doing things like requesting timers, initializing variables, setting timer periods.+  * periodic_task_init(): ​Initialization ​code for doing things like requesting timers, initializing variables, setting timer periods.
   * do_rt_task():​ The real time task is done here.   * do_rt_task():​ The real time task is done here.
-  * wait_rest_of_period():​ After the task is done, wait for the rest of the period. The assumption here is the task less time to complete compared to the period length. +  * wait_rest_of_period():​ After the task is done, wait for the rest of the period. The assumption here is the task requires ​less time to complete compared to the period length. 
-  * struct period_info: ​this is a struct which will be used to pass around data required by the above mentioned functions.+  * struct period_info: ​This is a struct which will be used to pass around data required by the above mentioned functions.
  
 The stub for the real time task will look like: The stub for the real time task will look like:
Line 31: Line 31:
                 wait_rest_of_period(&​pinfo);​                 wait_rest_of_period(&​pinfo);​
         }         }
 +        ​
 +        return NULL;
 } }
 </​code>​ </​code>​
Line 38: Line 40:
  
 clock_nanosleep() is used to ask the process to sleep for certain amount of time. nanosleep() can also be used to sleep. But, nanosleep() uses CLOCK_REALTIME which can be changed by another processes and hence can be discontinuous or jump back in time. In clock_nanosleep,​ CLOCK_MONOTONIC is explicitly specified. This is a immutable clock which does not change after startup. clock_nanosleep() is used to ask the process to sleep for certain amount of time. nanosleep() can also be used to sleep. But, nanosleep() uses CLOCK_REALTIME which can be changed by another processes and hence can be discontinuous or jump back in time. In clock_nanosleep,​ CLOCK_MONOTONIC is explicitly specified. This is a immutable clock which does not change after startup.
-The periodicity is achieved by recording ​time before and after the task is implemented and sleeping for the difference between ​period ​length and execution time (determined by difference in the timestamps taken before RT task has started and after it has completed.+The periodicity is achieved by using absolute ​time to specify ​the end of each period. ​More information on clock_nanosleep at http://​man7.org/​linux/​man-pages/​man2/​clock_nanosleep.2.html
-more information on clock_nanosleep at http://​man7.org/​linux/​man-pages/​man2/​clock_nanosleep.2.html+
 <code c> <code c>
-struct period_info{ +struct period_info { 
-        struct timespec ​start_time+        struct timespec ​next_period
-        ​struct timespec time_elapsed;+        ​long period_ns;
 }; };
-  + 
-void periodic_task_init(struct period_info *pinfo)+static ​void inc_period(struct period_info *pinfo) ​
 { {
-        ​clock_gettime(CLOCK_MONOTONIC,​ &(pinfo->start_time));+        ​pinfo->​next_period.tv_nsec += pinfo->​period_ns;​ 
 + 
 +        while (pinfo->next_period.tv_nsec >= 1000000000
 +                /* timespec nsec overflow */ 
 +                pinfo->​next_period.tv_sec++;​ 
 +                pinfo->​next_period.tv_nsec -= 1000000000; 
 +        }
 } }
-  + 
-void do_rt_work()+static ​void periodic_task_init(struct period_info *pinfo)
 { {
-        //Do RT stuff here.+        /* for simplicity, hardcoding a 1ms period */ 
 +        pinfo->​period_ns = 1000000; 
 + 
 +        clock_gettime(CLOCK_MONOTONIC,​ &​(pinfo->​next_period));​
 } }
-  + 
-// Assuming the timespec_a is always greater than timespec_b. +static void do_rt_task()
-struct timespec time_difference(struct timespec *a, struct timespec *b)+
 { {
-        ​struct timespec diff; +        ​/* Do RT stuff here*/
-  +
-        diff.tv_sec = a->​tv_sec - b->​tv_sec;​ +
-        diff.tv_nsec = a->​tv_nsec - b->​tv_nsec;​ +
-  +
-        if (diff.tv_nsec < 0) +
-        { +
-                diff.tv_sec--;​ +
-                diff.tv_nsec += 1000000000;​ +
-        } +
-  +
-        return diff;+
 } }
-  + 
-void wait_rest_of_period(struct period_info *pinfo, struct timespec *period_length)+static ​void wait_rest_of_period(struct period_info *pinfo)
 { {
-        ​//Determine how much time has passed. +        ​inc_period(pinfo); 
-        //Wait for the rest of the period. + 
-        struct timespec current_time,​ time_elapsed,​ remaining_time;​ +        ​/* for simplicityignoring possibilities of signal wakes *
-  +        clock_nanosleep(CLOCK_MONOTONIC, ​TIMER_ABSTIME, &​pinfo->​next_period,​ NULL);
-        clock_gettime(CLOCK_MONOTONIC,​ &​current_time); +
-  +
-        ​time_elapsed = time_difference(&​current_time&​pinfo->​start_time);​ +
-        /Assuming that the task execution time is less than period_length. +
-        remaining_time = time_difference(period_length,​ &​time_elapsed);​ +
-  +
-        clock_nanosleep(CLOCK_MONOTONIC, ​0, &​remaining_time,​ NULL); +
-  +
-        // Starting the next period. +
-        clock_gettime(CLOCK_MONOTONIC, &​pinfo->​start_time);+
 } }
 </​code>​ </​code>​
Line 96: Line 84:
 Recently, earliest deadline first scheduling algorithm has been merged in the mainline kernel. Now, users can specify runtime, period and deadline of a task and they scheduler will run the task every specified period and will make sure the deadline is met. The scheduler will also let user know if the tasks(or a set of  tasks) cannot be scheduled because the deadline won't be met. Recently, earliest deadline first scheduling algorithm has been merged in the mainline kernel. Now, users can specify runtime, period and deadline of a task and they scheduler will run the task every specified period and will make sure the deadline is met. The scheduler will also let user know if the tasks(or a set of  tasks) cannot be scheduled because the deadline won't be met.
  
-More information about the EDF scheduler including an example of implementation can be found at: https://git.kernel.org/​cgit/​linux/​kernel/​git/​torvalds/​linux.git/​tree/​Documentation/​scheduler/​sched-deadline.txt?​id=refs/​tags/​v4.10-rc2+More information about the EDF scheduler including an example of implementation can be found at: https://www.kernel.org/​doc/​Documentation/​scheduler/​sched-deadline.txt
  
realtime/documentation/howto/applications/cyclic.1495206750.txt.gz · Last modified: 2017/05/19 15:12 by jogness